尋找this的指向總結(jié) js

一、this是什么?

this是指包含它的函數(shù)作為方法被調(diào)用時(shí)所屬的對(duì)象。

二、由new調(diào)用(new綁定),綁定到新創(chuàng)建的對(duì)象

new表達(dá)式:

function foo(a) {
 this.a = a;
}
var bar = new foo( 2 );
console.log( bar.a ); // 2
三、由call 、apply、bind 調(diào)用(顯示綁定),綁定到指定的對(duì)象

顯示綁定:可以直接指定this的綁定對(duì)象,例如call()、apply()。

1.call ( 傳的this,參數(shù)用逗號(hào)隔開 )
2.aplay(傳的this,【參數(shù)用數(shù)組形式】)
3.bind 返回的是一個(gè)新的函數(shù),必須調(diào)用它才會(huì)被執(zhí)行,它的參數(shù)和 call 一樣。

注意:
如果第一個(gè)參數(shù)傳的是null,和undefined ,this會(huì)指向window;
如果是number、string、boolean會(huì)轉(zhuǎn)向包裝類型。

四、由上下文調(diào)用(隱式綁定),綁定到那個(gè)上下文對(duì)象

隱式綁定:會(huì)把函數(shù)調(diào)用的this綁定到這個(gè)上下文對(duì)象。
注意:隱式綁定的函數(shù)如果丟失了綁定的對(duì)象,就會(huì)應(yīng)用默認(rèn)綁定,從而吧this綁定到全局對(duì)象或者undefined上,取決于是否是嚴(yán)格模式。

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

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

obj.foo(); // 2

下面的this的指向是window,并不是foo。

function foo(num) {
    console.log( "foo: " + num );

    // keep track of how many times `foo` is called
    this.count++;
}

foo.count = 0;

var i;

for (i=0; i<10; i++) {
    if (i > 5) {
        foo( i );
    }
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9

// how many times was `foo` called?
console.log( foo.count ); // 0 -- WTF?        
image.png
五、用 call-site 和 call-stack 來(lái)查找上下文調(diào)用時(shí)this的指向

call-site:調(diào)用位置,函數(shù)在代碼中被調(diào)用的位置(不是聲明的位置)。
call-stack:調(diào)用棧,就是為了到達(dá)當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù)??梢詮恼{(diào)用棧中分析出真正的調(diào)用位置,因?yàn)樗鼪Q定了this的綁定。

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

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

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

obj1.obj2.foo(); // 42
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
bar(); // 調(diào)用位置  "oops, global" 

這里bar是obj.foo的一個(gè)引用,它引用的是foo函數(shù)本身,因此此時(shí)的bar()其實(shí)是一個(gè)不帶任何修飾的函數(shù)調(diào)用。

六、默認(rèn)綁定

如果上面三種綁定方法都不是的話,使用默認(rèn)綁定。如果在嚴(yán)格模式下,就綁定到 undefined ,否則綁定到全局對(duì)象。

  1. 在全局范圍內(nèi)聲明的變量,就是同名全局對(duì)象屬性的同義詞
function foo() {
    console.log( this );
    console.log( this.a );
}
var a = 2;
foo();// 2
  1. 在嚴(yán)格模式下,全局對(duì)象不符合默認(rèn)綁定的條件,因此將this設(shè)置為undefined
function foo() {
 "use strict";
 console.log( this.a );
}
var a = 2;
foo(); // TypeError: `this` is `undefined`
  1. 這個(gè)嚴(yán)格模式的作用區(qū)域,并沒有在foo中。
function foo() {
    console.log( this.a );
}
var a = 2;
(function(){
    "use strict";
    foo(); // 2
})();

注意:有些調(diào)用可能在無(wú)意中使用默認(rèn)綁定規(guī)則。如果想保護(hù)全局對(duì)象,可以創(chuàng)建一個(gè)空對(duì)象,比如 Object.create(unll)。

七、ES6中箭頭函數(shù)

ES6中箭頭函數(shù)并不會(huì)使用四種標(biāo)準(zhǔn)的綁定規(guī)則,而是根據(jù)當(dāng)前的詞法作用域來(lái)決定this

var obj = {
      say: function () {
        setTimeout(() => {
          //  this指向obj,箭頭函數(shù)是根據(jù)當(dāng)前的詞法作用域來(lái)決定this。
            console.log(this == obj);
        }, 0)
      }
    }
obj.say();
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 1.概念 在JavaScript中,this 是指當(dāng)前函數(shù)中正在執(zhí)行的上下文環(huán)境,因?yàn)檫@門語(yǔ)言擁有四種不同的函數(shù)調(diào)...
    BluesCurry閱讀 1,236評(píng)論 0 2
  • 關(guān)于 this this 關(guān)鍵字是 JavaScript 中最復(fù)雜的機(jī)制之一。它是一個(gè)很特別的關(guān)鍵字,被自動(dòng)定義在...
    游學(xué)者灬墨槿閱讀 626評(píng)論 1 2
  • 函數(shù)和對(duì)象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對(duì)于任何一門語(yǔ)言來(lái)說都是核心的概念。通過函數(shù)可以封裝任意多條語(yǔ)句,而且...
    道無(wú)虛閱讀 4,932評(píng)論 0 5
  • 1. this之謎 在JavaScript中,this是當(dāng)前執(zhí)行函數(shù)的上下文。因?yàn)镴avaScript有4種不同的...
    百里少龍閱讀 1,093評(píng)論 0 3
  • 特別說明,為便于查閱,文章轉(zhuǎn)自https://github.com/getify/You-Dont-Know-JS...
    殺破狼real閱讀 816評(píng)論 0 1

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