《你不知道的JavaScript(上卷)》讀書總結之this

JavaScript中的this到底指向誰?javascript

書中介紹了四種規則來判斷,以下,優先級從高到低。java

1.(new綁定)函數是否在new中調用?若是是的話,this綁定的是新建立的對象。app

function foo(a){
        this.a = a;
    }
    var bar = new foo(2);
    console.log(bar.a);  // 2

2.(顯示綁定)函數是否經過call、apply調用?若是是的話,this綁定指定的對象上。函數

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

3.(隱形綁定)函數是否在某個上下文對象中調用?若是是的話,this綁定的是那個上下文對象。this

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

上述代碼中,foo函數在obj中被調用,因此這裏this指向obj。code

function foo(){
        console.log(this.a);
    }
    var obj2={
        a:2,
        foo:foo
    }
    var obj1={
        a:1,
        obj2:obj2
    }
    obj1.obj2.foo(); // 2

上述代碼中,foo函數在obj2中被調用,因此this指向obj2。對象

function foo(){
        console.log(this.a);
    }
    var obj={
        a:2,
        foo:foo
    }
    var bar=obj.foo;
    var a="global"
    bar(); // "global"

這三段代碼很類似,區別在於第三個多了一個 var bar=obj.foo; ,foo是個函數(引用類型),因此bar引用的是foo函數自己,因此這段代碼至關於:ip

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

這時,this指向的是window對象(全局對象),至關於下面的第四條規則。在javascript中老是說等於號「=」是賦值運算符,其實這種說法不太全面,我以爲對「=」的理解應該爲:賦值或引用。看下面代碼:內存

var a=1;
    var b=a;  // 賦值
    var c={username:123};
    var d=c;  // 引用
    b=2;
    d.username=456;
    console.log(a);             // 1
    console.log(c.username);   // 456

由於變量a是個值類型,存儲在內存的棧中,因此對b進行修改不會影響到a的本來值;而c是個對象(引用類型),存放在內存的堆中,變量c和d指向同一個內存地址,對d進行修改會影響到c。作用域

4.(默認綁定)若是函數不在嚴格模式下,this綁定的是全局對象。

function foo(){
        console.log(this.a);
    }
    var a=2;
    foo(); // 2

其實,第3條和第4條的this指向都和函數被調用的位置有關,能夠合爲一條規則,即:this指向函數被調用位置所在的做用域的對應對象,在某個函數內部被調用,那麼this就指向這個函數對象,在全局做用域中被調用,那麼this就指向全局對象。

因此,對於this的指向,咱們能夠總結爲:在一般狀況下(沒有new和顯示綁定),this指向函數被調用位置所在的做用域的對應對象。

相關文章
相關標籤/搜索