JS中的this

參考
English
中文

先導(dǎo)知識:

call, apply, bind

兩個概念:

調(diào)用點(call-site):代碼中函數(shù)被調(diào)用的地方而不是函數(shù)被定義的地方孝偎。
調(diào)用棧(call-stack):代碼執(zhí)行時到達(dá)當(dāng)前位置的函數(shù)棧访敌。我們care的是當(dāng)前函數(shù)環(huán)境的調(diào)用位置。
舉個栗子:

function a(){
  //調(diào)用棧為'a'
  //調(diào)用點在全局作用域中
  console.log('a');
  //b的調(diào)用點
  b();
}
function b(){
  //調(diào)用棧為'a' ->'b'
  //調(diào)用點在a中
  console.log('b');
  //c的調(diào)用點
  c();
}
function c(){
  //調(diào)用棧為'a' ->'b'->'c'
  //調(diào)用點在b中
  console.log('c');
}

//a的調(diào)用點
a();

四種綁定:

默認(rèn)綁定(Default Binding)

被直接(plain, un-decorated)調(diào)用的函數(shù)在非嚴(yán)格(non-strict)模式下綁定的是全局對象衣盾;在嚴(yán)格(strict)模式下undefined寺旺,報錯爷抓。
栗子:

  1. 非嚴(yán)格模式直接調(diào)用函數(shù)
function foo() {
    console.log( this.a );
}
var a = 2;
foo(); // 2
  1. 嚴(yán)格模式直接調(diào)用函數(shù)(只和函數(shù)內(nèi)部是不是嚴(yán)格模式有關(guān),而和調(diào)用點是不是嚴(yán)格模式無關(guān))
function foo() {
    "use strict";

    console.log( this.a );
}
var a = 2;
foo(); // TypeError: `this` is `undefined`

隱式綁定(Implicit Binding)

調(diào)用點函數(shù)引用是否有一個環(huán)境對象(如果有多級引用阻塑,則取離函數(shù)最近的對象)
栗子:

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

var obj = {
    a: 2,
    foo: foo
};

obj.foo(); // 2

番栗子:

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

var obj = {
    a: 2,
    foo: foo
};

var bar = obj.foo; // function reference/alias!

var a = "oops, global"; // `a` also property on global object
//此處調(diào)用bar依然是對foo函數(shù)的直接引用蓝撇,所以是默認(rèn)綁定
bar(); // "oops, global"

如果不想像調(diào)用對象上的屬性函數(shù)這樣來綁定this,請看下面的顯示綁定

顯示綁定(Explicit Binding)

使用call方法和bind方法
栗子:foo.call(obj)陈莽,此時foo函數(shù)中的this引用的就是obj

  1. 強(qiáng)綁定(Hard Binding)
    栗子:
function foo() {
    console.log( this.a );
}
var obj = {
    a: 2
};
var bar = function() {
    foo.call( obj );
};
bar(); // 2
setTimeout( bar, 100 ); // 2
// bar是一個將this強(qiáng)綁定為obj的函數(shù)渤昌,他已經(jīng)不是foo了
//所以bar中的this不能被重載了
bar.call( window ); // 2

個人覺得You don't know JS作者將強(qiáng)綁定歸入顯示綁定而不是劃等號應(yīng)該是因為顯示綁定中可能就是直接以foo.call(obj)形式調(diào)用一次,而強(qiáng)綁定則將這個強(qiáng)綁定的函數(shù)保留多次調(diào)用走搁。如有其它建議独柑,歡迎討論。

  1. API調(diào)用環(huán)境(API call context)
    許多庫函數(shù)都可以接受一個環(huán)境參數(shù)
    栗子:
function foo(el) {
    console.log( el, this.id );
}
var obj = {
    id: "awesome"
};
// 每次調(diào)用foo函數(shù)都把obj作為this引用
[1, 2, 3].forEach( foo, obj ); // 1 awesome  2 awesome  3 awesome

new綁定(new Binding):

在JS中私植,構(gòu)造器(constructor)僅僅是使用new操作符調(diào)用的函數(shù)而已忌栅。它不附屬于類,沒有實例化一個類曲稼,甚至不是特殊類型的函數(shù)索绪。它只是因為new的用法而被誤解的普通函數(shù)。
在JS中沒有構(gòu)造函數(shù)贫悄,只有對函數(shù)的構(gòu)造調(diào)用求摇。當(dāng)一個函數(shù)被new操作符調(diào)用時扶平,發(fā)生了下列操作

  1. 生成一個新對象
  2. 新對象被[[Prototype]]-linked
  3. 新對象被綁定到這次函數(shù)調(diào)用的this
  4. 除非函數(shù)返回其他對象屈糊,否則默認(rèn)就返回這個新創(chuàng)建的對象的了
    栗子:
function foo(a) {
    this.a = a;
}
var bar = new foo( 2 );//this綁定到了新創(chuàng)建的對象谍失,即bar
console.log( bar.a ); // 2

綁定例外(Binding Exceptions)

詞法this(Lexical this)

ES6的箭頭函數(shù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嫡丙,隨后出現(xiàn)的幾起案子拴袭,更是在濱河造成了極大的恐慌,老刑警劉巖曙博,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拥刻,死亡現(xiàn)場離奇詭異,居然都是意外死亡父泳,警方通過查閱死者的電腦和手機(jī)般哼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惠窄,“玉大人蒸眠,你說我怎么就攤上這事「巳冢” “怎么了楞卡?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我蒋腮,道長淘捡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任池摧,我火速辦了婚禮焦除,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘作彤。我一直安慰自己膘魄,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布宦棺。 她就那樣靜靜地躺著瓣距,像睡著了一般黔帕。 火紅的嫁衣襯著肌膚如雪代咸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天成黄,我揣著相機(jī)與錄音呐芥,去河邊找鬼。 笑死奋岁,一個胖子當(dāng)著我的面吹牛思瘟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播闻伶,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼滨攻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蓝翰?” 一聲冷哼從身側(cè)響起光绕,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎畜份,沒想到半個月后诞帐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡爆雹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年停蕉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钙态。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡慧起,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出册倒,到底是詐尸還是另有隱情蚓挤,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站屈尼,受9級特大地震影響册着,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜脾歧,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一甲捏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鞭执,春花似錦司顿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至估脆,卻和暖如春钦奋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疙赠。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工付材, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人圃阳。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓厌衔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捍岳。 傳聞我的和親對象是個殘疾皇子富寿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

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