函數(shù)的聲明與定義
方式1:
function print(s) {
console.log(s);
}
方式2:
var print = function(s) {
console.log(s);
};
//方式2定義函數(shù)岖妄,如果使用了函數(shù)名,如下面代碼的x,函數(shù)名在函數(shù)體外邊無效喳瓣。
var print = function x(){
console.log(typeof x);
};
X;// ReferenceError: x is not defined
方式3:不推薦使用
var foo = new Function(
'return "hello world"'
);
函數(shù)的調(diào)用
函數(shù)名加()表示還是調(diào)用瑟枫,() 中間
function add(x, y) {
return x + y;
}
add(1, 1)
第一等公民
JavaScript 語言將函數(shù)看作一種值,與其它值(數(shù)值捷泞、字符串声搁、布爾值等等)地位相同黑竞。凡是可以使用值的地方,就能使用函數(shù)疏旨。比如很魂,可以把函數(shù)賦值給變量和對象的屬性,也可以當(dāng)作參數(shù)傳入其他函數(shù)檐涝,或者作為函數(shù)的結(jié)果返回遏匆。函數(shù)只是一個(gè)可以執(zhí)行的值法挨,此外并無特殊之處。
函數(shù)名提升
JavaScript 引擎將函數(shù)名視同變量名幅聘,所以采用function命令聲明函數(shù)時(shí)凡纳,整個(gè)函數(shù)會像變量聲明一樣,被提升到代碼頭部帝蒿。所以荐糜,下面的代碼不會報(bào)錯(cuò)。
f();
function f() { ... }
獲取函數(shù)信息
- name屬性獲取函數(shù)的名字
function f1() {}
f1.name
// -----
var f2 = function () {};
f2.name
- length屬性獲取 函數(shù)定義之中的參數(shù)個(gè)數(shù)葛超。
length屬性提供了一種機(jī)制狞尔,判斷定義時(shí)和調(diào)用時(shí)參數(shù)的差異,以便實(shí)現(xiàn)面向?qū)ο缶幊痰摹狈椒ㄖ剌d“(overload)巩掺。
function f(a, b) {}
f.length // 2
- toString方法返回一個(gè)字符串,內(nèi)容是函數(shù)的源碼页畦。帶// 注釋
function f() {
a();
b();
c();
}
f.toString()
// function f() {
// a();
// b();
// c();
// }
作用域
作用域(scope)指的是變量存在的范圍胖替。在 ES5 的規(guī)范中,Javascript 只有兩種作用域:一種是全局作用域豫缨,變量在整個(gè)程序中一直存在独令,所有地方都可以讀取好芭;另一種是函數(shù)作用域燃箭,變量只在函數(shù)內(nèi)部存在。ES6 又新增了塊級作用域舍败。
- 在函數(shù)內(nèi)部定義的變量招狸,外部無法讀取,稱為“局部變量”(local variable)邻薯。
- 函數(shù)外部聲明的變量就是全局變量(global variable)裙戏,它可以在函數(shù)內(nèi)部讀取。
- 函數(shù)本身也是一個(gè)值厕诡,也有自己的作用域累榜。它的作用域與變量一樣,由其聲明所在的位置決定灵嫌。
同名參數(shù)
同名參數(shù)壹罚,最后面的覆蓋前面的,前面的無效寿羞。
function f(a, a) {
console.log(a);
}
f(1, 2) // 2
arguments 對象
由于 JavaScript 允許函數(shù)有不定數(shù)目的參數(shù)猖凛,在內(nèi)部是由 arguments對象機(jī)制實(shí)現(xiàn)的。
arguments對象包含了函數(shù)運(yùn)行時(shí)的所有參數(shù)稠曼,arguments[0]就是第一個(gè)參數(shù)形病,arguments[1]就是第二個(gè)參數(shù)客年,以此類推。這個(gè)對象只有在函數(shù)體內(nèi)部漠吻,才可以使用量瓜。
var f = function (one) {
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
f(1, 2, 3)
//輸出1,2途乃,3
js閉包
由于在 JavaScript 語言中绍傲,只有函數(shù)內(nèi)部的子函數(shù)才能讀取內(nèi)部變量,因此可以把閉包簡單理解成“定義在一個(gè)函數(shù)內(nèi)部的函數(shù)”耍共。
function f1() {
var n = 999;
function f2() {
console.log(n);
}
return f2;
}
var result = f1();
result();
上面代碼中烫饼,函數(shù)f1的返回值就是函數(shù)f2,由于f2可以讀取f1的內(nèi)部變量试读,所以就可以在外部獲得f1的內(nèi)部變量了杠纵。
閉包就是函數(shù)f2,即定義在某函數(shù)內(nèi)部钩骇,讀取該函數(shù)內(nèi)部變量的函數(shù)比藻。
立即執(zhí)行函數(shù)
// 寫法一
var tmp = newData;
processData(tmp);
storeData(tmp);
// 寫法二
(function () {
var tmp = newData;
processData(tmp);
storeData(tmp);
}());
有時(shí),我們需要在定義函數(shù)之后倘屹,立即調(diào)用該函數(shù)银亲。這時(shí),你不能在函數(shù)的定義之后加上圓括號纽匙,這會產(chǎn)生語法錯(cuò)誤务蝠。
產(chǎn)生這個(gè)錯(cuò)誤的原因是,JavaScript 引擎規(guī)定烛缔,如果function關(guān)鍵字出現(xiàn)在行首馏段,一律解釋成語句。因此力穗,行首是function關(guān)鍵字毅弧,引擎認(rèn)為這是函數(shù)的定義語句,不應(yīng)該以圓括號結(jié)尾当窗,所以就報(bào)錯(cuò)了够坐。解決方法就是不要讓function出現(xiàn)在行首,按表達(dá)式處理函數(shù)定義崖面。最簡單的方法元咙,就是將其放在一個(gè)圓括號里面。
(function(){ /* code */ })();
eval命令
eval命令接受一個(gè)字符串作為參數(shù)巫员,并將這個(gè)字符串當(dāng)作語句執(zhí)行庶香。