深入淺出this

What's this?

由于運(yùn)行期綁定的特性,JavaScript 中的 this 含義非常多,它可以是全局對(duì)象、當(dāng)前對(duì)象或者任意對(duì)象,這完全取決于函數(shù)的調(diào)用方式
隨著函數(shù)使用場(chǎng)合的不同,this的值會(huì)發(fā)生變化。但是有一個(gè)總的原則,那就是this指的是,調(diào)用函數(shù)的那個(gè)對(duì)象

作為函數(shù)調(diào)用

在函數(shù)被直接調(diào)用時(shí)this綁定到全局對(duì)象。在瀏覽器中,window 就是該全局對(duì)象

console.log(this);//window
function fn1(){
    console.log(this);
}
fn1();//window   因?yàn)樵趂n的作用域里找不到,就會(huì)像上找,這樣就會(huì)找到window

還有,函數(shù)里this不是代表函數(shù)本身,這個(gè)很重要,很多新人都會(huì)犯這個(gè)錯(cuò)誤,包括我之前也老是覺(jué)得,函數(shù)里的this,代表的就是這個(gè)函數(shù),這是錯(cuò)誤的,下面我們來(lái)看這個(gè)例子

var a = 100
function fn(){
  var a = 1
  console.log(this.a);
}
fn()//100

很多新手一看就覺(jué)得,咦!怎么打印的不是1,而是全局下的a呢?因?yàn)樵诤瘮?shù)里找不到this,那么就會(huì)去外面找,上面說(shuō)了,外面的this代表window,所以console.log(this.a);實(shí)際上就是console.log(window.a);,所以打印出的值是100。

內(nèi)部函數(shù)

函數(shù)嵌套產(chǎn)生的內(nèi)部函數(shù)的this不是其父函數(shù),仍然是全局變量

function parent(){
  function children(){
    console.log(this);
  }
  children()
}
parent()//window

首先會(huì)再函數(shù)內(nèi)部找this,發(fā)現(xiàn)子函數(shù)里找不到this,那就去父函數(shù)找,還是找不到,最后就去父函數(shù)的外面也就是全局下找this,所以打印出的是window

setTimeout、setInterval

這兩個(gè)方法執(zhí)行的函數(shù)this也是全局對(duì)象

document.addEventListener('click', function(e){
    console.log(this);
    setTimeout(function(){
        console.log(this);
    }, 200);
}, false);

第一個(gè)this是綁定事件的這個(gè)元素,第二個(gè)this代表的全局對(duì)象window,如下圖所示


image.png

如果在函數(shù)里申明了var self=this,那么第二個(gè)this就變掉了,相當(dāng)于把第一個(gè)this代表的元素保存起來(lái)了,我們直接來(lái)看代碼。如果看的有點(diǎn)繞的話,可以這么想,我可以不用_this,可以用me、self來(lái)代替,效果一樣

image.png

document.addEventListener('click', function(e){
    console.log(this);
    var me = this
    setTimeout(function(){
        console.log(me);
    }, 200);
}, false)

作為構(gòu)造函數(shù)調(diào)用

所謂構(gòu)造函數(shù),就是通過(guò)這個(gè)函數(shù)生成一個(gè)新對(duì)象(object)。這時(shí),this就指這個(gè)新對(duì)象

new 運(yùn)算符接受一個(gè)函數(shù) F 及其參數(shù):new F(arguments...)。這一過(guò)程分為三步:

  • 創(chuàng)建類(lèi)的實(shí)例。這步是把一個(gè)空的對(duì)象的 __proto__ 屬性設(shè)置為 F.prototype 。
  • 初始化實(shí)例。函數(shù) F 被傳入?yún)?shù)并調(diào)用,關(guān)鍵字 this 被設(shè)定為該實(shí)例。
  • 返回實(shí)例。
function Person(name){
    this.name = name;
}
Person.prototype.printName = function(){
    console.log(this.name);
};

var p1 = new Person('Byron');
var p2 = new Person('Casper');
var p3 = new Person('Vincent');

p1.printName();
p2.printName();
p3.printName();

p1.printName();這句話執(zhí)行的時(shí)候,先執(zhí)行p1 = new Person('Byron'),然后在new的時(shí)候,做了三件事,
1、創(chuàng)建新的空對(duì)象
2、然后是把這個(gè)空的對(duì)象的 __proto__ 屬性設(shè)置為 Person.prototype 
3、執(zhí)行函數(shù)Person,遇到this,就認(rèn)為this是剛才創(chuàng)建的對(duì)象,給它添加一個(gè)屬性name,而這個(gè)屬性的值就是函數(shù)Person的name
執(zhí)行完成之后,把新對(duì)象return出來(lái)賦值給p1
這樣就可以通過(guò)p1的方式去用了

作為對(duì)象方法調(diào)用

在 JavaScript 中,函數(shù)也是對(duì)象,因此函數(shù)可以作為一個(gè)對(duì)象的屬性,此時(shí)該函數(shù)被稱(chēng)為該對(duì)象的方法,在使用這種調(diào)用方式時(shí),this 被自然綁定到該對(duì)象,簡(jiǎn)單的來(lái)說(shuō),就是誰(shuí)調(diào)用這個(gè)函數(shù),這個(gè)函數(shù)指的就是誰(shuí)(這個(gè)this就代表誰(shuí))。

如:Object1.fn(),this指的就是Object1,
假如:Object1.Object2.Object3.fn(),this指的就是Object3,
this指向最后一次調(diào)用者

var obj1 = {
    name: 'Byron',
    fn : function(){
        console.log(this);
    }
};
obj1.fn();//{name: "Byron", fn: ?}

var fn2 = obj1.fn;
fn2();//window 因?yàn)閒n是全局變量,等同于執(zhí)行winow.fn2()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第2章 基本語(yǔ)法 2.1 概述 基本句法和變量 語(yǔ)句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,569評(píng)論 0 13
  • 第5章 引用類(lèi)型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類(lèi)型 使用基本類(lèi)型...
    大學(xué)一百閱讀 3,683評(píng)論 0 4
  • 大型企業(yè)分布式微服務(wù)云架構(gòu)服務(wù)組件 實(shí)現(xiàn)模塊化、微服務(wù)化、原子化、灰度發(fā)布、持續(xù)集成 commonservice ...
    swiftie10閱讀 194評(píng)論 1 1
  • 2017年,10月8日,打開(kāi)了簡(jiǎn)書(shū)之窗。 走進(jìn)簡(jiǎn)書(shū),完全是因?yàn)橐粋€(gè)人。 一個(gè)已經(jīng)認(rèn)識(shí)了三年多的人。 剛剛認(rèn)識(shí)他的時(shí)...
    系南方姑娘吖閱讀 388評(píng)論 10 3

友情鏈接更多精彩內(nèi)容