成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

你不知道的js中關(guān)于this綁定機(jī)制的解析[看完還不懂算我輸]

dunizb / 883人閱讀

摘要:綁定書中提到在中,實(shí)際上并不存在所謂的構(gòu)造函數(shù),只有對于函數(shù)的構(gòu)造調(diào)用。規(guī)則使用構(gòu)造調(diào)用的時候,會自動綁定在期間創(chuàng)建的對象上。指向新創(chuàng)建的對象綁定比隱式綁定優(yōu)先級高。

前言

最近正在看《你不知道的JavaScript》,里面關(guān)于this綁定機(jī)制的部分講的特別好,很清晰,這部分對我們js的使用也是相當(dāng)關(guān)鍵的,并且這也是一個面試的高頻考點(diǎn),所以整理一篇文章分享一下這部分的內(nèi)容,相信看本文的解析,你一定會有所收獲的,如果喜歡的話可以點(diǎn)波贊/關(guān)注,支持一下。

個人博客了解一下:obkoro1.com
為什么要用this:
function identify() {
  console.log("Hello,I"m " + this.name);
}
let me = {
  name: "Kyle"
};
let you = {
  name: "Reader"
};
identify.call(me); // Hello,I"m Kyle
identify.call(you); // Hello,I"m Reader

這個簡單的栗子,可以在不同的對象中復(fù)用函數(shù)identify,不用針對每個對象編寫一個新函數(shù)。

this解決的問題:

this提供了一種更優(yōu)雅的方法來隱式"傳遞"一個對象的引用,因此可以將API設(shè)計(jì)得更加簡潔并且易于復(fù)用。

this的四種綁定規(guī)則: 默認(rèn)綁定:

規(guī)則:在非嚴(yán)格模式下,默認(rèn)綁定的this指向全局對象,嚴(yán)格模式下this指向undefined

function foo() {
  console.log(this.a); // this指向全局對象
}
var a = 2;
foo(); // 2
function foo2() {
  "use strict"; // 嚴(yán)格模式this綁定到undefined
  console.log(this.a); 
}
foo2(); // TypeError:a undefined

默認(rèn)綁定規(guī)則如上述栗子,書中還提到了一個微妙的細(xì)節(jié):

function foo() {
  console.log(this.a); // foo函數(shù)不是嚴(yán)格模式 默認(rèn)綁定全局對象
}
var a = 2;
function foo2(){
  "use strict";
  foo(); // 嚴(yán)格模式下調(diào)用其他函數(shù),不影響默認(rèn)綁定
}
foo2(); // 2

所以:對于默認(rèn)綁定來說,決定this綁定對象的是函數(shù)體是否處于嚴(yán)格模式,嚴(yán)格指向undefined,非嚴(yán)格指向全局對象。

通常不會在代碼中混用嚴(yán)格模式和非嚴(yán)格模式,所以這種情況很罕見,知道一下就可以了,避免某些{{BANNED}}的面試題挖坑。

隱式綁定:

規(guī)則:函數(shù)在調(diào)用位置,是否有上下文對象,如果有,那么this就會隱式綁定到這個對象上。

    function foo() {
      console.log(this.a);
    }
    var a = "Oops, global";
    let obj2 = {
      a: 2,
      foo: foo
    };
    let obj1 = {
      a: 22,
      obj2: obj2
    };
    obj2.foo(); // 2 this指向調(diào)用函數(shù)的對象
    obj1.obj2.foo(); // 2 this指向最后一層調(diào)用函數(shù)的對象
    
    // 隱式綁定丟失
    let bar = obj2.foo; // bar只是一個函數(shù)別名 是obj2.foo的一個引用
    bar(); // "Oops, global" - 指向全局

隱式綁定丟失:

隱式綁定丟失的問題:實(shí)際上就是函數(shù)調(diào)用時,并沒有上下文對象,只是對函數(shù)的引用,所以會導(dǎo)致隱式綁定丟失。

同樣的問題,還發(fā)生在傳入回調(diào)函數(shù)中,這種情況更加常見,并且隱蔽,類似:

    test(obj2.foo); // 傳入函數(shù)的引用,調(diào)用時也是沒有上下文對象。
顯式綁定:

就像我們上面看到的,如果單純使用隱式綁定肯定沒有辦法得到期望的綁定,幸好我們還可以在某個對象上強(qiáng)制調(diào)用對象,從而將this綁定在這個函數(shù)上。

規(guī)則:我們可以通過apply、call、bind將函數(shù)中的this綁定到指定對象上。

function foo() {
    console.log(this.a);
}
let obj = {
    a: 2
};
foo.call(obj); // 2

傳入的不是對象:

如果你傳入了一個原始值(字符串,布爾類型,數(shù)字類型),來當(dāng)做this的綁定對象,這個原始值轉(zhuǎn)換成它的對象形式。

如果你把null或者undefined作為this的綁定對象傳入call/apply/bind,這些值會在調(diào)用時被忽略,實(shí)際應(yīng)用的是默認(rèn)綁定規(guī)則。

new綁定:
書中提到:在js中,實(shí)際上并不存在所謂的"構(gòu)造函數(shù)",只有對于函數(shù)的"構(gòu)造調(diào)用"。

new的時候會做哪些事情:

創(chuàng)建一個全新的對象。

這個新對象會被執(zhí)行 [[Prototype]] 連接。

這個新對象會綁定到函數(shù)調(diào)用的this

如果函數(shù)沒有返回其他對象,那么new表達(dá)式中的函數(shù)調(diào)用會自動返回這個新對象。

規(guī)則:使用構(gòu)造調(diào)用的時候,this會自動綁定在new期間創(chuàng)建的對象上。

function foo(a) {
  this.a = a; // this綁定到bar上
}
let bar = new foo(2);
console.log(bar.a); // 2
this四種綁定規(guī)則的優(yōu)先級

如果在某個調(diào)用位置應(yīng)用了多條規(guī)則,如何確定哪條規(guī)則生效?

    obj.foo.call(obj2); // this指向obj2 顯式綁定比隱式綁定優(yōu)先級高。
    new obj.foo(); // thsi指向new新創(chuàng)建的對象 new綁定比隱式綁定優(yōu)先級高。

顯式綁定和new綁定無法直接比較((會報錯),默認(rèn)綁定是不應(yīng)用其他規(guī)則之后的兜底綁定所以優(yōu)先級最低,最后的結(jié)果是:

顯式綁定 > 隱式綁定 > 默認(rèn)綁定

new綁定 > 隱式綁定 > 默認(rèn)綁定

箭頭函數(shù)的this指向不會使用上述的四條規(guī)則:
function foo() {
  return () => {
    console.log(this.a);
  };
}
let obj1 = {
  a: 2
};
let obj2 = {
  a: 22
};
let bar = foo.call(obj1); // foo this指向obj1
bar.call(obj2); // 輸出2 這里執(zhí)行箭頭函數(shù) 并試圖綁定this指向到obj2

從上述栗子可以得出,箭頭函數(shù)的this規(guī)則:

箭頭函數(shù)中的this繼承于它外面第一個不是箭頭函數(shù)的函數(shù)的this指向

箭頭函數(shù)的 this 一旦綁定了上下文,就不會被任何代碼改變

結(jié)語

認(rèn)真看完的話,相信你已經(jīng)get到this的用法了,最后推薦一下《你不知道的JavaScript》,這本書真的很好,寫的也很有趣,沒看過的小伙伴抓緊入手了。

PS:目前離職中,大佬們有坑位可以介紹一下呀,base:上海長寧。

希望看完的朋友可以點(diǎn)個喜歡/關(guān)注,您的支持是對我最大的鼓勵。

個人blog and 掘金個人主頁,如需轉(zhuǎn)載,請放上原文鏈接并署名。碼字不易,感謝支持!

如果喜歡本文的話,歡迎關(guān)注我的訂閱號,漫漫技術(shù)路,期待未來共同學(xué)習(xí)成長。

以上2018.6.30

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/95874.html

相關(guān)文章

  • 十分鐘快速了解《你不知道 JavaScript》(上卷)

    摘要:最近剛剛看完了你不知道的上卷,對有了更進(jìn)一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對象原型。附錄詞法這一章并沒有說明機(jī)制,只是介紹了中的箭頭函數(shù)引入的行為詞法。第章混合對象類類理論類的機(jī)制類的繼承混入。 最近剛剛看完了《你不知道的 JavaScript》上卷,對 JavaScript 有了更進(jìn)一步的了解。 《你不知道的 JavaScript》上卷由兩部...

    趙春朋 評論0 收藏0
  • 記大四以來前端面試

    摘要:大四到校就開始了緊張的秋招。在此紀(jì)錄一下大四以來的前端面試。面試準(zhǔn)備準(zhǔn)備簡歷。主要是??途W(wǎng),牛客網(wǎng)秋招和春招都有面經(jīng)分享活動,很多拿到大廠的大牛會在上面分享面試經(jīng)驗(yàn)。這段是調(diào)用函數(shù)的語句,調(diào)用了約好的函數(shù),并且將數(shù)據(jù)當(dāng)做參數(shù)傳入。 前言 大三下學(xué)期因?yàn)檠劬剂诉^敏性結(jié)膜炎,只好在家養(yǎng)病,錯過了寶貴的實(shí)習(xí)時間。大四到校就開始了緊張的秋招。拿到的第一個offer是一家廈門的公司,當(dāng)時跟技術(shù)...

    galois 評論0 收藏0
  • 記大四以來前端面試

    摘要:大四到校就開始了緊張的秋招。在此紀(jì)錄一下大四以來的前端面試。面試準(zhǔn)備準(zhǔn)備簡歷。主要是??途W(wǎng),??途W(wǎng)秋招和春招都有面經(jīng)分享活動,很多拿到大廠的大牛會在上面分享面試經(jīng)驗(yàn)。這段是調(diào)用函數(shù)的語句,調(diào)用了約好的函數(shù),并且將數(shù)據(jù)當(dāng)做參數(shù)傳入。 前言 大三下學(xué)期因?yàn)檠劬剂诉^敏性結(jié)膜炎,只好在家養(yǎng)病,錯過了寶貴的實(shí)習(xí)時間。大四到校就開始了緊張的秋招。拿到的第一個offer是一家廈門的公司,當(dāng)時跟技術(shù)...

    劉福 評論0 收藏0
  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點(diǎn)提及,但是只要善于運(yùn)用,其實(shí)基于原型的繼承模型比傳統(tǒng)的類繼承還要強(qiáng)大。中文指南基本操作指南二繼續(xù)熟悉的幾對方法,包括,,。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 怎樣使用 this 因?yàn)楸救藢儆趥吻岸?,因此文中只看懂?8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評論0 收藏0
  • 你不知道javascript》中關(guān)this記錄

    摘要:使用調(diào)用函數(shù)時,會自動執(zhí)行以下操作創(chuàng)建一個全新的對象該對象會被執(zhí)行連接該對象會綁定到函數(shù)調(diào)用的若函數(shù)沒有返回其他對象,表達(dá)式中的函數(shù)調(diào)用會自動返回該對象。 使用this可以減少傳入上下文對象,可以隱式傳遞一個對象引用。使API簡潔而復(fù)用,可以自動引用合適的上下文對象。 【要注意的幾個點(diǎn)】 1. this不一定指向自身; 2. this不一定指向函數(shù)作用域(因?yàn)樽饔糜驘o法通過js代碼訪...

    tommego 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<