JS的this指向深入
this指向深入
this的绑定规则
- 默认绑定
- this默认指向了window
- 全局环境下this指向了window
- 函数独立调用,函数内部的this也指向了window
<script>
function fn(){
console.log(this);
}
fn();
</script>
- 函数被嵌套的函数独立调用时,this默认指向了window
- 函数当做对象的方法来调用时,this指向了obj
<script>
var obj = {
a:2,
foo:function(){
var that = this;
function test(){
console.log(that.a);
}
test();
}
}
obj.foo();
</script>
- 自执行函数内容this也指向了window
<script>
var a = 10;
function foo(){
(function(){console.log(this.a);}());
}
var obj = {
a:2,
foo:foo
}
obj.foo();
</script>
- 闭包this默认指向window
<script>
var a = 0;
var obj = {
a:2,
foo:function(){
var c = this.a;
return function test(){
console.log(this);
return c;
}
}
}
var fn = obj.foo();
console.log(fn);
</script>
隐式绑定
<script>
function foo(){
console.log(this.a);
}
var obj = {
a:1,
foo:foo
}
//foo()函数的直接对象是obj,this的指向直接对象。
obj.foo();
</script>
隐式丢失
隐式丢失是指被隐式绑定的函数丢失了绑定对象 从而默认绑定到window
这种情况比较容易出错却非常常见。
<script>
var a = 0;
function foo(){
console.log(this.a);
}
var obj = {
a:1,
foo:foo
var bar = obj.foo();
bar();
</script>
把obj.foo()赋值给别名bar,造成隐式丢失的情况,因为只有把obj.foo()赋值了bar变量
而bar与obj对象毫无关系。
new绑定
如果是new关键字来执行函数,相当于构造函数来实例化对象,name内部的this指向了当前实例化的对象
<script>
function fn(){
console.log(this);
}
var fn = new fn();
console.log(fn);
</script>
使用return关键字来返回对象的时候,this还是指向了当前的对象。
<script>
function fn2(){
console.log(this);
return {
name:'xxx'
}
}
var fn2 = new fn2();
console.log(fn2);
</script>
严格模式下的this
严格模式下,独立调用的函数内部的this指向了undefined
<script>
function fn(){
'use strict';
console.log(this);
}
fn();
//函数apply()和call()
//严格模式下,函数apply()和call()内部的this始终是它们的第一个参数。
var color = 'red';
function showColor(){
'use strict';
console.log(this);
console.log(this.color);
}
showColor.call(undefined);
</script>
this总结
- 默认绑定
- 隐式绑定
- 显示绑定
- new绑定
分别对应了函数的四种调用方式,
四种调用方式对应了this绑定
调用方式 - 独立调用
- 方法调用
- 间接调用
- 构造方法调用
- 独立调用 对应 默认绑定
- 方法调用this指向obj
- 间接调用通过call()、apply()、bind() 来更改内部的this指向。
- 构造函数在函数中添加了new关键字,内部中的this会发生改变,它会改变当前的实例化对象。