1. new 關(guān)鍵字
例如:var a = new F();
其實(shí)際操作如下:
1. var a = {};
2. a.__proto__ = F.prototype;
3. F.prototype.call(a, [...param]);
2. 閉包
閉包是有權(quán)限訪(fǎng)問(wèn)父函數(shù)作用域中變量的函數(shù),即在一個(gè)函數(shù)內(nèi)部創(chuàng)建另外一個(gè)函數(shù)。
例如:function F() {
????var i = 0;
????return function() {
? ? ????console.log(i ++);
????}
}
var a = F();? ? a(); // 0????a(); // 1
var b = F();????b(); // 0????b(); // 1
為什么子函數(shù)可以訪(fǎng)問(wèn)父函數(shù)變量
1. JavaScript語(yǔ)言特有的"鏈?zhǔn)阶饔糜?結(jié)構(gòu),子對(duì)象會(huì)一級(jí)一級(jí)地向上尋找所有父對(duì)象的變量。所以,父對(duì)象的所有變量,對(duì)子對(duì)象都是可見(jiàn)的,反之則不成立。
2. JavaScript的垃圾回收機(jī)制,并沒(méi)有清除引用變量的內(nèi)存。
垃圾回收機(jī)制
標(biāo)記清除(mark and sweep):垃圾回收器會(huì)在運(yùn)行的時(shí)候給存儲(chǔ)在內(nèi)存中的所有變量加上標(biāo)記,然后去掉環(huán)境中的變量以及被環(huán)境中變量所引用的變量(閉包),在這些完成之后仍存在標(biāo)記的就是要?jiǎng)h除的變量了,因?yàn)榄h(huán)境中的變量已經(jīng)無(wú)法訪(fǎng)問(wèn)到這些變量了,然后垃圾回收器相會(huì)這些帶有標(biāo)記的變量機(jī)器所占空間。
大部分瀏覽器都是使用這種方式進(jìn)行垃圾回收,區(qū)別在于如何標(biāo)記及垃圾回收間隔而已,除了低版本IE。
引用計(jì)數(shù)(reference counting):引用計(jì)數(shù)的策略是跟蹤記錄每個(gè)值被使用的次數(shù),當(dāng)聲明了一個(gè)變量并將一個(gè)引用類(lèi)型賦值給該變量的時(shí)候這個(gè)值的引用次數(shù)就加1,如果該變量的值變成了另外一個(gè),則這個(gè)值得引用次數(shù)減1,當(dāng)這個(gè)值的引用次數(shù)變?yōu)?的時(shí)候,說(shuō)明沒(méi)有變量在使用,這個(gè)值沒(méi)法被訪(fǎng)問(wèn)了,因此可以將其占用的空間回收,這樣垃圾回收器會(huì)在運(yùn)行的時(shí)候清理掉引用次數(shù)為0的值占用的空間。
如果存在相互引用的情況下該策略就無(wú)法清除內(nèi)存,照成內(nèi)存泄漏,在低版本IE中經(jīng)常會(huì)出現(xiàn)內(nèi)存泄露,很多時(shí)候就是因?yàn)槠洳捎靡糜?jì)數(shù)方式進(jìn)行垃圾回收。
引用于:https://www.cnblogs.com/dolphinX/p/3348468.html
閉包所引起的常見(jiàn)問(wèn)題
例如:var a = [];
function f() {
????var b= [1, 2, 3];
????for (var i = 0; i < b.length; i++) {
????????var item = b[i];
? ? ? ? var _a = function() {
? ? ? ? ? ? console.log(item);
????????}
????????a.push(_a);
????}
}
f();
a[0](); // 3
a[1](); // 3
a[2](); // 3
造成這個(gè)結(jié)果的原因是,1. 閉包所引用的是變量是地址,而不是其值。2. 變量item被所有子函數(shù)共享,所以改變item的值其他子函數(shù)都會(huì)變化。
解決辦法:(function(item) {
? ? var _a = function() {
? ? ? ? console.log(item);
????}
? ? a.push(_a);
})(item)
使用立即執(zhí)行函數(shù)將item變量轉(zhuǎn)變每個(gè)子函數(shù)的私有變量,從而互不干擾。