《你不知道的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指向函数被调用位置所在的做用域的对应对象。

相关文章
相关标签/搜索