RN this指針

解決問題:如何準(zhǔn)確判斷this指向的是什么
this是什么搀缠?

首先記住this不是指向自身铛楣!this就是一個指針,指向調(diào)用函數(shù)的對象艺普◆ぶ荩【劃重點:調(diào)用函數(shù)的對象、對象歧譬、對象0痘搿!瑰步!

首先需要知道this的綁定規(guī)則
1矢洲、默認綁定

默認綁定 在不能應(yīng)用其它綁定規(guī)則時使用的默認規(guī)則,通常是獨立函數(shù)調(diào)用缩焦。

function sayHi() {
    console.log('Hello,',this.name);
}

var name = 'ZSZ'

sayHi();

在調(diào)用sayHi()時读虏,應(yīng)用了默認綁定责静,this指向全局對象(非嚴(yán)格模式下),嚴(yán)格模式下盖桥,this指向undefined灾螃,undefined上沒有this對象,會拋出錯誤揩徊。

上面的代碼腰鬼,如果在瀏覽器環(huán)境中運行,那么結(jié)果就是 Hello,ZSZ

但是如果在node環(huán)境中運行塑荒,結(jié)果就是Hello,undefined.這是因為node中name并不是掛在全局對象上的熄赡。

2、隱式綁定

隱式綁定函數(shù)的調(diào)用是在某個對象上觸發(fā)的袜炕,即調(diào)用位置上存在上下文對象本谜。典型的形式為 XXX.fun().

function sayHi() {
    console.log('Hello,',this.name);
}

var person = {
    name:'ZSZ01',
    sayHi:sayHi
}

var name = 'ZSZ02';

person.sayHi();

打印的結(jié)果是Hello,ZSZ01.
sayHi函數(shù)聲明在外部,嚴(yán)格來說并不屬于person偎窘,但是在調(diào)用sayHi時乌助,調(diào)用位置會使用person上下文來引用函數(shù),隱式綁定會把函數(shù)調(diào)用中的this(即此例sayHi函數(shù)中的this)綁定到這個上下文對象(即此例中的person)
需要注意的是:對象屬性鏈中只有最后一層會影響到調(diào)用位置陌知。例子如下:

function sayHi() {
    console.log('Hello,',this.name);
}
var person2 = {
    name:'Christina',
    sayHi:sayHi
}
var person1 = {
    name:'ZSZ'
    friend:person2
}

person1.friend.sayHi();

打印是:Christina
因為只有最后一層會確定this指向的是什么他托,不管有多少層,在判斷this的時候仆葡,我們只關(guān)注最后一層赏参。即此處的friend。

隱式綁定有一個大陷阱沿盅,綁定很容易丟失(或者說容易給我們造成誤導(dǎo)把篓,我們以為this指向的是什么,但是實際上并非如此)腰涧。

例子如下:

function sayHi() {
    console.log('Hello,',this.name);
}
var person = {
    name:'ZSZ01',
    sayHi:sayHi
}
var name = 'ZSZ02';
var Hi = person.sayHi; // Hi指向了sayHi的引用
Hi();

打印是 ZSZ02
Hi直接指向了sayHi的引用韧掩,在調(diào)用的時候,跟person沒有半毛錢關(guān)系窖铡,針對此類問題疗锐,我們只需要急著這個格式 XXX.fn(); 如果fn()前如果什么都沒有,那么肯定不是隱式綁定费彼,但是也不一定就是默認綁定滑臊。

除了上面這種丟失之外,隱式綁定的丟失是發(fā)生在回調(diào)函數(shù)中(事件回調(diào)也是其中一種)箍铲,例子如下:


function sayHi() {
    console.log('Hello,',this.name);
}

var person1 = {
    name:'ZSZ01',
    sayHi:function(){
        setTimeout(function(){
            console.log('Hello,',this.name);
        })
    }
}


打印結(jié)果為:

Hello, Wiliam
Hello, Wiliam
Hello, 

第一條輸出很容易理解雇卷,setTimeout的回調(diào)函數(shù)中,this使用的是默認綁定,非嚴(yán)格模式下关划,執(zhí)行的是全局對象

第二條輸出是不是有點迷惑了膘融?說好XXX.fun()的時候,fun中的this指向的是XXX呢祭玉,為什么這次卻不是這樣了!Why春畔?

其實這里我們可以這樣理解:setTimeout(fn,delay){fn();} 相當(dāng)于是將person2.sayHi賦值給了一個變量脱货,最后執(zhí)行了一個變量,這個時候律姨,sayHi中的this顯然和person2就沒有關(guān)系了振峻。

第三條雖然也是在setTimeout的回調(diào)中,但是我們可以看出择份,這是執(zhí)行的是person2.sayHi()使用的隱式綁定扣孟,因此這是this指向的是person2,跟當(dāng)前的作用域沒有任何關(guān)系

3荣赶、硬綁定[顯式綁定]

顯式綁定比較好理解凤价,就是通過call,apply,bind的方式,顯式的指定this所指向的對象拔创。(注意《你不知道的Javascript》中將bind單獨作為了硬綁定講解了)

call,apply和bind的第一個參數(shù)利诺,就是對應(yīng)函數(shù)的this所指向的對象。call和apply的作用一樣剩燥,只是傳參方式不同慢逾。call和apply都會執(zhí)行對應(yīng)的函數(shù),而bind方法不會灭红。

function sayHi(){
    console.log('Hello,',this.name);
}
var person = {
    name:'ZSZ01',
    sayHi:sayHi
}
var name = 'ZSZ02';
var Hi = person.sayHi;
Hi.call(person); // Hi.apply(person)

輸出結(jié)果為: Hello,ZSZ01 因為使用硬綁定明確將this綁定在了person上侣滩。

那么,使用了硬綁定变擒,是不是意味著不會出現(xiàn)隱式綁定所遇到的綁定丟失呢?顯然不是這樣的君珠,不信,繼續(xù)往下看赁项。


function sayHi() {
    console.log('Hello,',this.name);
}
var person = {
    name:'ZSZ01',
    sayHi:sayHi,
}
var name = 'ZSZ02';
var Hi = function(fn) {
    fn();
}
Hi.call(person,person.sayHi);

輸出的結(jié)果是 Hello,ZSZ02葛躏。原因很簡單,Hi.call(person,person.sayHi);的確是將this綁定到Hi中的this了悠菜。但是在執(zhí)行fn的時候舰攒,相當(dāng)于直接調(diào)用了sayHi方法(記住:person.sayHi已經(jīng)被賦值給fn了悔醋,隱式綁定也丟了)摩窃,沒有指定this的值,對應(yīng)的是默認綁定。

現(xiàn)在猾愿,我們希望綁定不會丟失鹦聪,要怎么做?很簡單蒂秘,調(diào)用fn的時候泽本。也給它硬綁定。

function sayHi(){
    console.log('Hello,',this.name);
}
var person = {
    name:'ZSZ01',
    sayHi:sayHi,
}
var name = 'ZSZ02'
var Hi = function(fn) {
    fn.call(this);
}
Hi.call(person,person.sayHi);

此時姻僧,輸出結(jié)果為:Hello,ZSZ01,因為person被綁定到Hi函數(shù)中的this上规丽,fn又將這個對象綁定給了sayHi的函數(shù)。這時撇贺,sayHi中的this指向的就是person對象赌莺。

4、new綁定

javaScript和C++不一樣松嘶,并沒有類艘狭,在javaScript中,構(gòu)造函數(shù)只是使用new操作符時被調(diào)用的函數(shù)翠订,這些函數(shù)和普通的函數(shù)并沒有什么不同巢音,它不屬于某個類,也不可能實例化出一個類尽超。任何一個函數(shù)都可以使用new來調(diào)用港谊,因此其實并不存在構(gòu)造函數(shù),而只有對于函數(shù)的“構(gòu)造調(diào)用”橙弱。

使用new來調(diào)用函數(shù)歧寺,會自動執(zhí)行下面的操作:

1、創(chuàng)建一個新對象
2棘脐、將構(gòu)造函數(shù)的作用域賦值給新對象斜筐,即this指向這個新對象
3、執(zhí)行構(gòu)造函數(shù)中的代碼
4蛀缝、返回新對象
因此顷链,我們使用new來調(diào)用函數(shù)的時候,就會把新對象綁定到這個函數(shù)的this上屈梁。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嗤练,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子在讶,更是在濱河造成了極大的恐慌煞抬,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件构哺,死亡現(xiàn)場離奇詭異革答,居然都是意外死亡战坤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門残拐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來途茫,“玉大人,你說我怎么就攤上這事溪食∧也罚” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵错沃,是天一觀的道長边败。 經(jīng)常有香客問我,道長捎废,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任致燥,我火速辦了婚禮登疗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嫌蚤。我一直安慰自己辐益,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布脱吱。 她就那樣靜靜地躺著智政,像睡著了一般。 火紅的嫁衣襯著肌膚如雪箱蝠。 梳的紋絲不亂的頭發(fā)上续捂,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音宦搬,去河邊找鬼牙瓢。 笑死,一個胖子當(dāng)著我的面吹牛间校,可吹牛的內(nèi)容都是我干的矾克。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼憔足,長吁一口氣:“原來是場噩夢啊……” “哼胁附!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起滓彰,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤控妻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后揭绑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饼暑,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了弓叛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彰居。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖撰筷,靈堂內(nèi)的尸體忽然破棺而出陈惰,到底是詐尸還是另有隱情,我是刑警寧澤毕籽,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布抬闯,位于F島的核電站,受9級特大地震影響关筒,放射性物質(zhì)發(fā)生泄漏溶握。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一蒸播、第九天 我趴在偏房一處隱蔽的房頂上張望睡榆。 院中可真熱鬧,春花似錦袍榆、人聲如沸胀屿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宿崭。三九已至,卻和暖如春才写,著一層夾襖步出監(jiān)牢的瞬間葡兑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工赞草, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铁孵,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓房资,卻偏偏與公主長得像蜕劝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子轰异,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容