摘要:綁定為這個(gè)數(shù)組五綁定如果使用來(lái)創(chuàng)建對(duì)象,因?yàn)楹竺娓氖菢?gòu)造函數(shù),所以稱它為構(gòu)造器調(diào)用。為傳進(jìn)來(lái)的構(gòu)造函數(shù)你這要看懂這步就行。
記得剛開始,我理解 this 的時(shí)候 也是云里霧里的,哈哈,希望通過(guò)這篇文章,對(duì)你有幫助吧。
關(guān)于 this 最多的說(shuō)法,就是:誰(shuí)調(diào)用它,this就指向誰(shuí)。這話呢,不能說(shuō)它錯(cuò)了,只能說(shuō)它講的不嚴(yán)謹(jǐn),為什么呢?我們先來(lái)了解下 this 的幾種綁定規(guī)則。
一、默認(rèn)綁定默認(rèn)綁定 發(fā)生在全局環(huán)境 。
全局環(huán)境中,this 默認(rèn)綁定到 window。(嚴(yán)格模式下一樣)
console.log(this === window); //true "use strict"; //使用嚴(yán)格模式執(zhí)行代碼 var a = 666; console.log(this.a) //666
隱式綁定 發(fā)生在 方法調(diào)用(執(zhí)行)。
什么是方法呢?通常把 對(duì)象的屬性值 是函數(shù)的,稱為方法。
var obj = { fun: function(){} } //這里obj 對(duì)象里 的fun 屬性值是個(gè)函數(shù), 就把 這個(gè)fun 屬性稱為方法了。
通常,方法調(diào)用時(shí),this 隱式綁定到其 所屬的對(duì)象 上。
var a = "window"; var obj = { a: "obj", fun: function(){ console.log(this.a); } } obj.fun(); //"obj"
來(lái)個(gè)難一點(diǎn)的:
var obj1 = { a: "obj1", obj2: { a: "obj2", fun: function(){ console.log(this.a); } } } obj1.obj2.fun(); //"obj2"
這里的答案 跟你想的一樣嗎? 出現(xiàn)這個(gè)答案的關(guān)鍵 就是于,fun 函數(shù) 在作為對(duì)象方法執(zhí)行時(shí), this 綁定的是它的 所屬對(duì)象,也就是 obj2 。 而非外層 的 obj1。
三、隱式綁定丟失在判斷是否是隱式綁定的時(shí)候,最容易出問(wèn)題的地方就是發(fā)生在 隱式綁定丟失。
隱式丟失是指被隱式綁定的函數(shù)丟失綁定對(duì)象,從而綁定到window。這種情況容易出錯(cuò)卻又常見(jiàn)。(嚴(yán)格模式下,綁定到undefined)
隱式綁定丟失 一般 發(fā)生在 函數(shù)獨(dú)立調(diào)用時(shí)。
啥是獨(dú)立調(diào)用呢?就是一個(gè)簡(jiǎn)單的函數(shù)執(zhí)行. 函數(shù)名的前面沒(méi)有任何引導(dǎo)內(nèi)容。
function ff(){}; ff(); //獨(dú)立調(diào)用
當(dāng)函數(shù)獨(dú)立調(diào)用(執(zhí)行)時(shí),this 就會(huì)隱式綁定丟失,而綁定到 window 對(duì)象上。(非嚴(yán)格模式下)
function fun(){ console.log(this === window); } fun(); //true
那么嚴(yán)格模式下呢?是指向 undefined 的。
function fun(){ "use strict"; //使用嚴(yán)格模式執(zhí)行代碼 console.log(this); } fun(); //undefined
考考你:
var a = "window"; var obj = { a: "obj", fun1: function(){ console.log(this.a); } } var fun2 = obj.fun; fun2(); //"window"
判斷是否隱式綁定丟失的關(guān)鍵就在于, 判斷函數(shù) 是否是哪種調(diào)用。
上面的例子,關(guān)鍵點(diǎn)就在 最后兩行代碼。
先看其中的第一行:
var fun2 = obj.fun;
這里把 obj 的fun 方法 賦值給了 一個(gè)變量 fun2,這里的 fun 并沒(méi)有作為對(duì)象的方法來(lái)執(zhí)行,因?yàn)?,fun 方法這里沒(méi)有執(zhí)行。
其后:
fun2();
再執(zhí)行 fun2,它保存著 fun1 方法,這時(shí)候執(zhí)行 fun2(等于fun1) ,但是,它是獨(dú)立調(diào)用。因?yàn)椋瑳](méi)有作為對(duì)象的方法來(lái)調(diào)用。所以 this 就被指向 window了。
那么怎么解決隱式丟失問(wèn)題呢?
var a = "window"; var obj = { a: "obj", fun: function(){ return function(){ console.log(this.a); } } } obj.fun()(); //"window" //這里我們想要的是 obj里 a 的值,可是,隱式綁定丟失導(dǎo)致獲取到了 window 里 a 的值。
可以基礎(chǔ)好的已經(jīng)知道答案了:
var a = "window"; var obj = { a: "obj", fun: function(){ var that = this; return function(){ console.log(that.a); } } } obj.fun()(); //"obj"
因?yàn)?fun 是作為方法調(diào)用的,所以 this 綁定到 obj 對(duì)象上,因此,我們就可以先用一個(gè)變量 that 來(lái)保存 this,然后 在內(nèi)部的 匿名函數(shù)中 使用 that 就可以了。它保存著 上面 this 的綁定對(duì)象。
忽然靈機(jī)一動(dòng),想出個(gè)題目,看人家都玩出題,我也試試,哈哈:
var a = "window"; function fun(){ var a = "fun"; return (function(){ return this.a; })() } fun() //“你猜”
這道題中 有立即執(zhí)行函數(shù)、this問(wèn)題,哈哈,乍一看挺惡心,其實(shí)看完上面的,應(yīng)該可以看出來(lái)的。
四、顯示綁定通過(guò)call()、apply()、bind()方法把 this 綁定到對(duì)象上,叫做顯式綁定。對(duì)于被調(diào)用的函數(shù)來(lái)說(shuō),叫做間接調(diào)用。
var a = "window" var obj = { a:"obj", } function fun(){ console.log(this.a); } fun.call(obj); //"obj";
這里使用了 call 方法,把fun 中的 this 綁定到 obj 對(duì)象上。
javascript內(nèi)置的一些函數(shù),具有顯式綁定的功能,如數(shù)組的5個(gè)迭代方法:map()、forEach()、filter()、some()、every(),以及創(chuàng)建對(duì)象的 Object.create() 函數(shù)(后面原型鏈中會(huì)細(xì)說(shuō)),都可以手動(dòng)綁定this。
大家可以去看下API文檔,數(shù)組的這幾個(gè)函數(shù)的最后一個(gè)參數(shù),就是指定函數(shù)內(nèi) this 的綁定,如果不指定,則是window,嚴(yán)格模式下是undefined。
var a = [1,2,3]; a.forEach(function(){ console.log(this) },a); //綁定 this 為 a 這個(gè)數(shù)組 //(3) [1, 2, 3] //(3) [1, 2, 3] //(3) [1, 2, 3]五、new 綁定
如果 使用 new 來(lái)創(chuàng)建對(duì)象,因?yàn)?后面跟著的是構(gòu)造函數(shù),所以稱它為構(gòu)造器調(diào)用。對(duì)于this綁定來(lái)說(shuō),稱為new綁定。
想知道 構(gòu)造器調(diào)用 中 this 的綁定,就要知道 new 到底做了啥了。
先來(lái)個(gè) new 的實(shí)現(xiàn)。看不懂不要緊,在后面原型鏈那篇,還會(huì)說(shuō)的。
function New(proto){ //proto 為傳進(jìn)來(lái)的構(gòu)造函數(shù) var obj = {}; obj.__proto__ = proto.prototype; proto.apply(obj, Array.prototype.slice.call(argument,1)); //你這要看懂這步就行。這里把構(gòu)造函數(shù)里的 this 綁定到了 新的obj 對(duì)象上,最后 返回了該新對(duì)象,作為實(shí)例對(duì)象。 return obj; }
所以在使用 new 來(lái)創(chuàng)建實(shí)例對(duì)象時(shí),new 內(nèi)部把 構(gòu)造函數(shù)的 this 綁定到 返回的新對(duì)象 上了。
function Person(name){ this.name = name; } var c = new Person("zdx"); c.name;
總結(jié): this的四種綁定規(guī)則:隱式綁定、隱式綁定丟失、顯式綁定和new綁定,分別對(duì)應(yīng)函數(shù)的四種調(diào)用方式:方法調(diào)用、獨(dú)立調(diào)用、間接調(diào)用和構(gòu)造器調(diào)用。
1、關(guān)于this綁定 的優(yōu)先級(jí)問(wèn)題。
簡(jiǎn)單提一下吧:
new 綁定 > 顯示綁定 > 隱式綁定 > 默認(rèn)綁定 。
2、ES6 中,箭頭函數(shù)的 this 綁定。
箭頭函數(shù)內(nèi)的 this 綁定的 是所屬的環(huán)境(函數(shù)或者對(duì)象), 它是固定不變的。
先看下上面的這個(gè)例子
var a = "window"; var obj = { a: "obj", fun: function(){ return function(){ console.log(this.a); } } } obj.fun()(); //"window"
上面我們使用 一個(gè)變量來(lái)保存 this 的綁定,下面我們來(lái)用 箭頭函數(shù)解決問(wèn)題
var a = "window"; var obj = { a: "obj", fun: function(){ return () => { console.log(this.a); } } } obj.fun()(); //"obj"
實(shí)際上,箭頭函數(shù)內(nèi)部是沒(méi)有this 的,所以,它不能使用 new 構(gòu)造器調(diào)用,call 等顯示綁定。所以它內(nèi)部就是使用了一個(gè)變量來(lái)保存 箭頭函數(shù) 所屬環(huán)境的(函數(shù)或者對(duì)象) this。
就相當(dāng)于:
var a = "window"; var obj = { a: "obj", fun: function(){ that = this; return function(){ console.log(that.a); } } } obj.fun()(); //"obj"
考考你:
var a = "window"; var obj = { a: "obj", fun1: function(){ return () => { console.log(this.a); } } } var fun2 = obj.fun1; fun2()();
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96444.html
摘要:情況沒(méi)有明確作用對(duì)象的情況下,通常為全局對(duì)象例如函數(shù)的回調(diào)函數(shù),它的就是全局對(duì)象。正因如此,機(jī)器可以作為這類對(duì)象的標(biāo)志,即面向?qū)ο笳Z(yǔ)言中類的概念。所以機(jī)器又被稱為構(gòu)造函數(shù)。原型鏈也就是繼承鏈。 JS面向?qū)ο蠖?this/原型鏈/new原理 阮一峰JavaScript教程:面向?qū)ο缶幊?阮一峰JavaScript教程:實(shí)例對(duì)象與 new 命令 阮一峰JavaScript教程:this 關(guān)...
摘要:此時(shí)產(chǎn)生了閉包。導(dǎo)致,函數(shù)的活動(dòng)對(duì)象沒(méi)有被銷毀。是不是跟你想的不一樣其實(shí),這個(gè)例子重點(diǎn)就在函數(shù)上,這個(gè)函數(shù)的第一個(gè)參數(shù)接受一個(gè)函數(shù)作為回調(diào)函數(shù),這個(gè)回調(diào)函數(shù)并不會(huì)立即執(zhí)行,它會(huì)在當(dāng)前代碼執(zhí)行完,并在給定的時(shí)間后執(zhí)行。 上一節(jié)說(shuō)了執(zhí)行上下文,這節(jié)咱們就乘勝追擊來(lái)搞搞閉包!頭疼的東西讓你不再頭疼! 一、函數(shù)也是引用類型的。 function f(){ console.log(not cha...
摘要:每一個(gè)由構(gòu)造函數(shù)創(chuàng)建的對(duì)象都會(huì)默認(rèn)的連接到該神秘對(duì)象上。在構(gòu)造方法中也具有類似的功能,因此也稱其為類實(shí)例與對(duì)象實(shí)例一般是指某一個(gè)構(gòu)造函數(shù)創(chuàng)建出來(lái)的對(duì)象,我們稱為構(gòu)造函數(shù)的實(shí)例實(shí)例就是對(duì)象。表示該原型是與什么構(gòu)造函數(shù)聯(lián)系起來(lái)的。 本文您將看到以下內(nèi)容: 傳統(tǒng)構(gòu)造函數(shù)的問(wèn)題 一些相關(guān)概念 認(rèn)識(shí)原型 構(gòu)造、原型、實(shí)例三角結(jié)構(gòu)圖 對(duì)象的原型鏈 函數(shù)的構(gòu)造函數(shù)Function 一句話說(shuō)明什么...
摘要:有關(guān)函數(shù)柯里化的詳解,請(qǐng)回閱前端進(jìn)擊的巨人五學(xué)會(huì)函數(shù)柯里化。構(gòu)造函數(shù)中的通過(guò)操作符可以實(shí)現(xiàn)對(duì)函數(shù)的構(gòu)造調(diào)用。在了解構(gòu)造函數(shù)中的前,有必要先了解下實(shí)例化對(duì)象的過(guò)程。 showImg(https://segmentfault.com/img/bVburMp?w=800&h=600); 常見(jiàn)this的誤解 指向函數(shù)自身(源于this英文意思的誤解) 指向函數(shù)的詞法作用域(部分情況) th...
摘要:匿名函數(shù)是不能單獨(dú)寫的,所以就提不上立即執(zhí)行了。六立即執(zhí)行函數(shù)在閉包中的應(yīng)用立即執(zhí)行函數(shù)能配合閉包保存狀態(tài)。來(lái)看下上節(jié)內(nèi)容中閉包的例子現(xiàn)在,我們來(lái)利用立即執(zhí)行函數(shù)來(lái)簡(jiǎn)化它第一個(gè)匿名函數(shù)執(zhí)行完畢后,返回了第二個(gè)匿名函數(shù)。 前面的閉包中,提到與閉包相似的立即執(zhí)行函數(shù),感覺(jué)兩者還是比較容易弄混吧,嚴(yán)格來(lái)說(shuō)(因?yàn)橄透叱虒?duì)閉包的定義不同),立即執(zhí)行函數(shù)并不屬于閉包,它不滿足閉包的三個(gè)條件。...
閱讀 3160·2023-04-26 02:33
閱讀 3116·2023-04-25 21:33
閱讀 915·2021-09-02 09:56
閱讀 2937·2019-08-30 15:44
閱讀 2466·2019-08-30 13:15
閱讀 1044·2019-08-30 13:04
閱讀 1645·2019-08-29 15:09
閱讀 3977·2019-08-26 18:26