關(guān)于JS中的 this 的指向

概述

在絕大多數(shù)情況下,函數(shù)的調(diào)用方式?jīng)Q定了this的值吩坝。在絕大多數(shù)情況下控轿,函數(shù)的調(diào)用方式?jīng)Q定了this的值。this不能在執(zhí)行期間被賦值宿礁,并且在每次函數(shù)被調(diào)用時this的值也可能會不同案铺。

this的指向在函數(shù)定義的時候是確定不了的,只有函數(shù)執(zhí)行的時候才能確定this到底指向誰梆靖,實(shí)際上this的最終指向的是那個調(diào)用它的對象

this 中的四種綁定方式 ?

一 默認(rèn)綁定

console.log(this === window); 
console.log(this.document === document); 
this.a = 91;
console.log(window.a); 

全局環(huán)境中控汉,this默認(rèn)綁定到window。

例子:

var a = 0;
function foo(){
    (function test(){
        console.log(this.a);
    })()
};
var obj = {
    a : 2,
    foo:foo
}
obj.foo();  

等價于上例

var a = 0;
var obj = {
    a : 2,
    foo:function(){
            function test(){
                console.log(this.a);
            }
            test();
    }
}
obj.foo();//0

函數(shù)獨(dú)立調(diào)用時返吻,this默認(rèn)綁定到window姑子。

(function () {
     console.log(this === window); // true
})();

function foo(){
    console.log(this === window);
}
foo();

二 隱式綁定

function foo() {
    console.log( this.a )
  }

  var obj2 = { 
      a: 42,
      foo: foo
   }

   var obj1 = {
      a: 2,
      obj2: obj2
   }

  obj1.obj2.foo();  

結(jié)合上面的例子,this的指向可以總結(jié)為一下三種情況测僵。

情況1:如果一個函數(shù)中有this壁酬,但是它沒有被上一級的對象所調(diào)用,那么this指向的就是window恨课,在js的嚴(yán)格版中this指向的不是window舆乔,而是undefined

情況2:如果一個函數(shù)中有this剂公,這個函數(shù)有被上一級的對象所調(diào)用希俩,那么this指向的就是上一級的對象。

情況3:如果一個函數(shù)中有this纲辽,這個函數(shù)中包含多個對象颜武,盡管這個函數(shù)是被最外層的對象所調(diào)用,this指向的也只是它上一級的對象拖吼。

隱式丟失
var o = {
a:10,
b: {
       a:12,
       fn:function(){
        console.log(this.a);  
        console.log(this);    
    }
  }
}
var j = o.b.fn;
j();

函數(shù)別名的情況
賦值操作和調(diào)用不是同一個概念鳞上,上面說的 this是指向上一級調(diào)用它的對象,跟賦值操作沒有上面關(guān)系吊档。例子中雖然函數(shù) fn 是被對象b 所引用篙议,但是在將 fn 賦值給變量 j 的時候并沒有執(zhí)行所以最終指向的是 window。

var a = 2;
function foo() {
    console.log( this.a );
}
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo(); 

(p.foo = o.foo)();

間接引用的情況
等價于函數(shù)別名的情況。
如果要輸出 4 鬼贱,該怎么做移怯?

var a = 2;
function foo() {
    console.log( this.a );
}
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo(); 
p.foo = o.foo;
p.foo();

三 顯示綁定

就是給this指定值,如:new这难,call, apply, bind綁定等

1)call 和 apply 綁定

function foo( something ) {
    console.log( this.a, something)
    return this.a + something
}

var obj = {
    a: 2
}

var bar = function() {
    return foo.apply( obj, arguments)
}

var b = bar(3); 
console.log(b);

類型轉(zhuǎn)換

function bar() {
   console.log(Object.prototype.toString.call(this));
}

bar.call(7); 

使用 callapply函數(shù)時要注意舟误,如果傳遞給this的值不是一個對象,JS會嘗試使用內(nèi)部的ToObject操作將其轉(zhuǎn)化為對象姻乓。因此嵌溢,如果傳遞的值是一個原始值比如 7 ,那么就會使用相關(guān)構(gòu)造函數(shù)將它轉(zhuǎn)換為對象蹋岩,所以原始值7會被轉(zhuǎn)換為對象赖草,像new Number(7)這樣。

2) bind 綁定

var module = {
  x: 42,
  getX: function() {
    return this.x;
  }
}

var unboundGetX = module.getX;
console.log(unboundGetX());          

var boundGetX = unboundGetX.bind(module);
console.log(boundGetX());

調(diào)用f.bind(someObject)會創(chuàng)建一個與f具有相同函數(shù)體和作用域的函數(shù)星澳,但是在這個新函數(shù)中疚顷,this將永久地被綁定到了bind的第一個參數(shù),無論這個函數(shù)是如何被調(diào)用的禁偎。返回由指定的this值和初始化參數(shù)改造的原函數(shù)拷貝

function foo( something ) {
    console.log( this.a, something)
    return this.a + something
}

var obj = {
    a: 2
 }

var bar = foo.bind(obj)

var b = bar(3); 
console.log(b); 

注意 bind指生效一次

3) new 綁定

在傳統(tǒng)面向類的語言中腿堤,使用new初始化類的時候會調(diào)用類中的構(gòu)造函數(shù),但是JS中new的機(jī)制實(shí)際上和面向類和語言完全不同如暖。

使用new來調(diào)用函數(shù)笆檀,或者說發(fā)生構(gòu)造函數(shù)調(diào)用時,會自動執(zhí)行下面的操作:

  • 創(chuàng)建(或者說構(gòu)造)一個全新的對象

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

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

    function fn() {
        this.a = 2;
    }
    var test = new fn();
    console.log(test); 
    

當(dāng) this 遇到 return 時

在構(gòu)造函數(shù)中使用this分為兩種情況

 function fn()  
  {  
     this.user = 'zhong';  
     return undefined;       
  }
  var a = new fn;  
  console.log(a);   

函數(shù)當(dāng)作構(gòu)造函數(shù)使用且函數(shù)內(nèi)沒有返回值盒至,或返回值是5種基本型(Undefined類型酗洒、Null類型、Boolean類型枷遂、Number類型樱衷、String類型)之一,指向?qū)嵗蟮膶ο?/p>

  function fn()  
  {  
      this.user = 'zhong';   
      return [1,2,3,4];
  }
  var a = new fn;  
  console.log(a);    

函數(shù)當(dāng)作構(gòu)造函數(shù)使用且有return值酒唉,返回是數(shù)組矩桂、對象等,this指向返回值

function C2() {
  this.a = 1;
  return {
    a: 2
  };
}
o = new C2();
console.log(o); 

Reference

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末痪伦,一起剝皮案震驚了整個濱河市侄榴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌网沾,老刑警劉巖癞蚕,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辉哥,居然都是意外死亡桦山,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來度苔,“玉大人匆篓,你說我怎么就攤上這事浑度】芤ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵箩张,是天一觀的道長甩骏。 經(jīng)常有香客問我,道長先慷,這世上最難降的妖魔是什么饮笛? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮论熙,結(jié)果婚禮上福青,老公的妹妹穿的比我還像新娘巍举。我一直安慰自己裸卫,他們只是感情好房官,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布脚翘。 她就那樣靜靜地躺著观堂,像睡著了一般氮凝。 火紅的嫁衣襯著肌膚如雪们豌。 梳的紋絲不亂的頭發(fā)上树碱,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天交惯,我揣著相機(jī)與錄音次泽,去河邊找鬼。 笑死席爽,一個胖子當(dāng)著我的面吹牛意荤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播只锻,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼玖像,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了炬藤?” 一聲冷哼從身側(cè)響起御铃,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沈矿,沒想到半個月后上真,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡羹膳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年睡互,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡就珠,死狀恐怖寇壳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情妻怎,我是刑警寧澤壳炎,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站逼侦,受9級特大地震影響匿辩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜榛丢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一铲球、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晰赞,春花似錦稼病、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锨用,卻和暖如春丰刊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背增拥。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工啄巧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掌栅。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓秩仆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親猾封。 傳聞我的和親對象是個殘疾皇子澄耍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

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

  • 1.概念 在JavaScript中,this 是指當(dāng)前函數(shù)中正在執(zhí)行的上下文環(huán)境晌缘,因?yàn)檫@門語言擁有四種不同的函數(shù)調(diào)...
    BluesCurry閱讀 1,122評論 0 2
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持磷箕,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券选酗,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 6,922評論 15 54
  • 函數(shù)和對象 1岳枷、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念芒填。通過函數(shù)可以封裝任意多條語句呜叫,而且...
    道無虛閱讀 4,525評論 0 5
  • #100天閱讀計劃#29/100〉钏ィ《王者速讀法》朱庆,為什么下決心看一本書的時候往往失敗告終,因?yàn)槲覀儚男”唤逃叭f般...
    肌肉控閱讀 162評論 0 0
  • 春天萬物復(fù)蘇闷祥,沉睡了很久的種子在黑暗的土壤里應(yīng)運(yùn)而蘇醒娱颊,慢慢地生根發(fā)芽,在太陽和細(xì)雨中不斷向外伸展蜀踏,這段時間是新...
    柯瑞娜閱讀 290評論 0 0