簡(jiǎn)述
js中函數(shù)的應(yīng)用占有非常重要的地位,可以單純的將一部分邏輯封成一個(gè)函數(shù),也可以創(chuàng)建對(duì)象。簡(jiǎn)單談?wù)勎业睦斫狻?/p>
創(chuàng)建一個(gè)函數(shù)都干了些什么
1.創(chuàng)建一個(gè)Function類(lèi)型實(shí)例
2.初始化參數(shù),包括函數(shù)的名字,參數(shù)的個(gè)數(shù),外層空間的引用,和一些其他配置
運(yùn)行一個(gè)函數(shù)都干了些什么
1.首先創(chuàng)建一個(gè)自己的封閉空間
2.創(chuàng)建arguments對(duì)象
3.初始化變量,包括傳入進(jìn)來(lái)的參數(shù),這是會(huì)出現(xiàn)變量提升,同名變量將進(jìn)行覆蓋
4.運(yùn)行js代碼
var a = 'a';
function b(){
a = 'b';
}
b();
console.log(a);
這段代碼輸出“b”。當(dāng)運(yùn)行代碼中碰到一個(gè)變量時(shí),他會(huì)先在自己的封閉空間中查找,如果找不到會(huì)到外層空間去找同名的變量。
var a = 'a';
function b(){
a = 'b';
return;
function a(){}
}
b();
console.log(a);
觀察上面這段代碼,這段代碼的輸出為“a”,不是“b”,發(fā)生這個(gè)原因是因?yàn)樽兞刻嵘?。正常情況下在函數(shù)內(nèi)部找不到對(duì)應(yīng)得變量,會(huì)到函數(shù)的外部引用找到同名的變量,所以這個(gè)變量就變成了外部的變量a,修改的也是這個(gè)變量。但是函數(shù)在return后聲明了一個(gè)同名的a函數(shù),變量提升后,有了內(nèi)部變量a,a='b'修改的是這個(gè)函數(shù),并不是外層的變量a。綜上所述全局的變量a根本沒(méi)有進(jìn)行修改。
而這塊封閉的區(qū)間就會(huì)形成函數(shù)閉包
function a(){
var b = 'b';
return function(){
console.log(b);
}
};
var c = a();
c();
c = null;
輸出為“b”,這就形成了一個(gè)閉包,外界無(wú)法通過(guò)c直接更改它的輸出值。需要注意的是每次運(yùn)行a,都會(huì)創(chuàng)建一個(gè)新的a的內(nèi)部空間并且被c引用,由于js的回收機(jī)制,只要是被引用的對(duì)象都不會(huì)被回收,這樣就造成內(nèi)存泄漏。記得用完c之后賦個(gè)null,這樣就斷掉了c對(duì)空間的引用,a的運(yùn)行空間就可以被回收了。
由于這個(gè)特性,就為js編程提供了一個(gè)近似狀態(tài)機(jī)的概念,比如說(shuō)柯里化
js中new一個(gè)對(duì)象的過(guò)程
1. 創(chuàng)建新對(duì)象為{}
2. 新對(duì)象的proto指向構(gòu)造函數(shù)的prototype對(duì)象,構(gòu)造函數(shù)中的this被指向新對(duì)象
3. 調(diào)用構(gòu)造函數(shù),設(shè)置新對(duì)象的constructor為構(gòu)造函數(shù),
4. 將初始化完畢的新對(duì)象地址,保存到等號(hào)左邊的變量中
function A(){
this.name = 'a';
};
let a = new A();
A.prototype.show = function(){
console.log(this.name);
};
function B(){
this.show();
this.name = 'b';
}
B.prototype = a;
var b = new B();
b.show();
輸出為“a”,“b”。這段代碼實(shí)現(xiàn)了原始的一種原型鏈,這是b.proto=B.prototype=a;這段代碼可以看出原型鏈的查找順序,第一次調(diào)用show函數(shù)時(shí),b沒(méi)有name屬性,所以到它的proto屬性中進(jìn)行查找,輸出為“a”;第二次調(diào)用show函數(shù)時(shí),b有了自己的name屬性,不需要到proto中查找,所以輸出“b”,多層鏈同理。這時(shí)需要注意一點(diǎn),創(chuàng)建a時(shí),A.prototype并沒(méi)有show函數(shù),但是在b的構(gòu)造函數(shù)中卻可以調(diào)用,說(shuō)明每次調(diào)用屬性時(shí)都會(huì)從新查找原型鏈。這樣可以一邊創(chuàng)建對(duì)象一邊修改原型鏈,不必?fù)?dān)心已經(jīng)創(chuàng)建的對(duì)象無(wú)法調(diào)用的問(wèn)題。