幾句話帶你理解JS中的this、閉包、原型鏈
原型鏈
所有對(duì)象都是基于Object.prototype,Object.prototype就是JavaScript的根對(duì)象,在Object.prototype中定義的方法都可以被其它對(duì)象訪問到,當(dāng)然也可以被重寫了,所以直接在Object.prototype上調(diào)用的是原始功能的toString()方法,該方法會(huì)放回參數(shù)對(duì)象的內(nèi)置屬性[[class]]的值,這個(gè)值是個(gè)字符串,比如'[Object String]'
要理解原型鏈機(jī)制的話,首先得知道根本原因:JavaScript中的對(duì)象都有一個(gè)內(nèi)置屬性[[Prototype]],這個(gè)屬性和非標(biāo)準(zhǔn)的__proto__屬性一樣,__proto__在ES6中被納入標(biāo)準(zhǔn)了,可以說它們基本上是等價(jià)的,但內(nèi)置屬性是無法訪問到的。對(duì)象之間通過內(nèi)置屬性[[Prototype]]關(guān)聯(lián)了起來就形成了原型鏈,而原型鏈的頂層就是根對(duì)象Object.prototype,Object.prototype的原型將是null,即Object.prototype.__proto__ === null;
例如:
在訪問對(duì)象的屬性的時(shí)候,如:obj.a,首先查找自身,沒有,就到它的內(nèi)置屬性[[Prototype]]所引用的對(duì)象上找,還是沒有,就繼續(xù)在這個(gè)上層對(duì)象的內(nèi)置屬性[[Prototype]]所引用的對(duì)象上找,一直找到根對(duì)象Object.prototype,找不到就返回undefined;
this
理解this的第一步就是要明白:this既不指向函數(shù)自身,也不指向函數(shù)的詞法作用域;
this是在運(yùn)行時(shí)進(jìn)行綁定的,而不是在編寫時(shí)綁定,它的上下文取決于函數(shù)調(diào)用時(shí)的各種條件;
this的綁定和函數(shù)聲明的位置沒有任何關(guān)系,只取決于函數(shù)的調(diào)用位置和調(diào)用方式;
this綁定規(guī)則有4點(diǎn):按優(yōu)先級(jí)1到4判斷
1.由new調(diào)用?綁定到新創(chuàng)建的空對(duì)象;
2.由call、apply、bind調(diào)用?綁定到指定的參數(shù)對(duì)象;如foo.call(obj)
3.由上下文對(duì)象調(diào)用?綁定到這個(gè)上下文對(duì)象;如obj.foo()
4.默認(rèn)情況下綁定到全局對(duì)象,foo();在嚴(yán)格模式下綁定到undefined;
閉包
function foo(){ var a = 2; function bar(){} return bar; } var a = foo(); a();
閉包:不是指函數(shù)bar也不是a,它是一個(gè)引用,這個(gè)引用被內(nèi)部函數(shù)bar持有,這個(gè)引用指向外部函數(shù)foo的整個(gè)作用域,它使得這個(gè)作用域即使在外部函數(shù)foo()執(zhí)行后也不會(huì)被垃圾回收器回收。也就是說這個(gè)外部函數(shù)foo的作用域就是閉包本身。
無論通過何種手段(直接或間接)將內(nèi)部函數(shù)傳遞到所在的詞法作用域以外,它都會(huì)持有對(duì)原始定義作用域的引用,無論在何處執(zhí)行這個(gè)函數(shù)都會(huì)使用閉包。
var fn; //間接傳遞函數(shù) function foo(){ var a = 2; function baz(){ console.log(a); } fn = baz; } function bar(){ fn();} foo(); bar(); function foo(){ var a = 2; function baz(){ console.log(a); } bar(baz); } function bar(fn){ fn(); }
相關(guān)文章
微信小程序:數(shù)據(jù)存儲(chǔ)、傳值、取值詳解
這篇文章主要介紹了微信小程序:數(shù)據(jù)存儲(chǔ)、傳值、取值,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05JS構(gòu)造一個(gè)html文本內(nèi)容成文件流形式發(fā)送到后臺(tái)
本文通過實(shí)例代碼給大家介紹了JS構(gòu)造一個(gè)html文本內(nèi)容成文件流形式發(fā)送到后臺(tái)的相關(guān)資料,需要的朋友可以參考下2018-07-07javascript的document中的動(dòng)態(tài)添加標(biāo)簽實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄獪\談javascript的document中的動(dòng)態(tài)添加標(biāo)簽實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-10-10js 將線性數(shù)據(jù)轉(zhuǎn)為樹形的示例代碼
這篇文章主要介紹了js 將線性數(shù)據(jù)轉(zhuǎn)為樹形的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05理解javascript函數(shù)式編程中的閉包(closure)
這篇文章主要幫助大家理解javascript函數(shù)式編程中的閉包(closure)概念,通俗地講, JavaScript 中每個(gè)的函數(shù)都是一個(gè)閉包,感興趣的小伙伴們可以參考一下2016-03-03js對(duì)象數(shù)組和對(duì)象的使用實(shí)例詳解
在本篇文章里小編給大家整理了關(guān)于js對(duì)象數(shù)組和對(duì)象的使用實(shí)例相關(guān)知識(shí)點(diǎn),有需要的朋友們學(xué)習(xí)下。2019-08-08JavaScript之iterable_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了JavaScript之iterable,遍歷Array可以采用下標(biāo)循環(huán),遍歷Map和Set就無法使用下標(biāo)。為了統(tǒng)一集合類型,ES6標(biāo)準(zhǔn)引入了新的iterable類型,Array、Map和Set都屬于iterable類型2017-06-06