this的隱式綁定(implicit binding)

show code

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

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

obj.foo(); // 2

this指向了obj,由於foo執行時call-site(能夠理解爲調用時所在做用域)在obj上面。注意是運行的時候,和在哪裏聲明的沒有關係。oop

call-site and call-stack

call-site姑且理解爲調用域call-stack調用棧。以下代碼能夠輔助咱們理解this

function baz() {
    // call-stack is: `baz`
    // so, our call-site is in the global scope

    console.log( "baz" );
    bar(); // <-- call-site for `bar`
}

baz()中調用bar(),因此bar的調用域是baz,此時bar的調用棧只有baz;而baz自己暴露在全局做用域中,因此它的調用域則也在全局做用域中。code

function bar() {
    // call-stack is: `baz` -> `bar`
    // so, our call-site is in `baz`

    console.log( "bar" );
    foo(); // <-- call-site for `foo`
}

function foo() {
    // call-stack is: `baz` -> `bar` -> `foo`
    // so, our call-site is in `bar`

    console.log( "foo" );
}

baz(); // <-- call-site for `baz`

理解以後再回頭看開頭的例子,是否是感受清晰了不少。其實this只是指向了它的call-siteci

還有以下玩法:作用域

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

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

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

obj1.obj2.foo(); // 42

Implicitly Lost(隱式丟失)

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(); // "oops, global"

雖然bar引用了obj上的foo,但實際上至關因而直接對foo引用而已,因此會默認綁定到全局。it

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

function doFoo(fn) {
    // `fn` is just another reference to `foo`

    fn(); // <-- call-site!
}

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

var a = "oops, global"; // `a` also property on global object

doFoo( obj.foo ); // "oops, global"
相關文章
相關標籤/搜索