Progress is the activity of today and the assurance of tomorrow.
進步是今天的活動,明天的保證。
函數是由事件驅動的或者當它被調用時執行的可重復使用的代碼塊。
定義函數
語法
function funcName(x) {
... // 函數體
}
解釋:
-
function
指出這是一個函數定義; -
JavaScript
對大小寫敏感。關鍵詞function
必須是小寫的; -
funcName
是函數的名稱; -
(x)
括號內列出函數的參數,多個參數以,分隔; -
{ ... }
之間的代碼是函數體,可以包含若干語句,甚至可以沒有任何語句。
==注意:== 函數體內部的語句在執行時,一旦執行到return
時,函數就執行完畢,并將結果返回;如果沒有return
語句,函數執行完畢后也會返回結果,只是結果為undefined
。
實例
// 求絕對值
function abs(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
}
// 求和
function sum(x, y) {
return x + y;
}
由于JavaScript
的函數也是一個對象,上述定義的abs()
函數實際上是一個函數對象,而函數名abs
可以視為指向該函數的變量。
因此,第二種定義函數的方式如下:
var abs = function (x) {
if (x >= 0) {
return x;
} else {
return -x;
}
};
function (x) { ... }
是一個匿名函數,它沒有函數名
通過變量abs
就可以調用該函數
上述兩種定義完全等價,注意第二種方式按照完整語法需要在函數體末尾加一個;
,表示賦值語句結束
調用函數
abs(10); // 返回10
abs(-9); // 返回9
abs(); // 返回NaN
sum(10, 20); // 返回 30
變量作用域
局部作用域
在JavaScript中,用var申明的變量實際上是有作用域的。
如果一個變量在函數體內部申明,則該變量的作用域為整個函數體,在函數體外不可引用該變量:
function foo(x) {
var y = 1; // 此變量 `y` 只能在 foo {...} 大括號內部使用
return x + y;
}
如果兩個不同的函數各自申明了同一個變量,那么該變量只在各自的函數體內起作用。換句話說,不同函數內部的同名變量互相獨立,互不影響:
function foo() {
var x = 1;
var y = 2;
return x + y;
}
function bar() {
var x = 1;
var z = 2;
return x + z;
}
兩個函數內部的變量 x
互不影響
由于JavaScript的函數可以嵌套,此時,內部函數可以訪問外部函數定義的變量,反過來則不行:
function foo() {
var a = 0;
function bar() {
var b = a + 3; // bar 可以訪問foo的變量 a
}
var c = b - 1; // error: foo 不可以訪問bar的變量 y
}
全局作用域
不在任何函數內定義的變量就具有全局作用域。實際上,JavaScript默認有一個全局對象window,全局作用域的變量實際上被綁定到window的一個屬性:
// 全局變量
var welcome = "Hello JavaScript";
alert(welcome); // "Hello JavaScript"
alert(window.welcome); // "Hello JavaScript"
全局函數
function foo() {
alert('foo');
}
foo(); // 直接調用foo()
window.foo(); // 通過window.foo()調用
命名空間
全局變量會綁定到window上,不同的JavaScript文件如果使用了相同的全局變量,或者定義了相同名字的頂層函數,都會造成命名沖突,并且很難被發現。
減少沖突的一個方法是把自己的所有變量和函數全部綁定到一個全局變量中。例如:
JavaScript
類似于Swift
也支持命名空間
// 唯一的全局變量MAZY:
var MAZY = {};
// 其他變量:
MAZY.name = 'myName';
MAZY.age = 21;
// 其他函數:
MAZY.foo = function () {
return 'foo';
};