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