标题浅谈This对象的理解
this是执行上下文的一种属性,它指向最后一次调用的对象(非严格模式下)。this的指向是动态的,它会随着触发函数的对象改变而改变。在实际开发中,this的指向可以通过四种调用模式来判断。
- 第一种是函数的调用模式,当一个函数不是一个对象的属性时,直接作为函数来调用时,this指向全局对象。
- 第二种是方法调用模式,如果一个函数作为一个对象的方法来调用时,this指向这个对象。
- 第三种是构造器调用模式,如果一个函数用new调用时,函数执行前会创建一个对象,this指向新创建的对象。
- 第四种是apply、、call和bind调用模式,这三种方法都可以显示的指定调用函数的this指向。
其中apply方法接收两个参数:一个是this绑定的对象,一个是参数
数组。后面的其他参数是传入函数执行的参数。
也就是说,在使用**call()**方法时,传递给函数的参数必须逐个列举出来。
bind方法通过传入一个对象,返回一个this绑定了传入对象的新函数。这个函数的this指向除了使用new时会被改变,其实情况下都不会改变。
实例如下
var name = "window";
function foo(){
console.log(this.name);
}
var obj = {
name:'nibao',
foo:function(){
console.log(this.name);
}
}
var obj1 = {
name:'wohao'
}
var obj2 = {
name:'dajiahao'
}
foo(); // 执行window.foo() this指向window this.name = window.name = 'window'
obj.foo(); // 执行window.obj.foo(); this指向obj this.name = obj.name = 'nibao'
foo.call(obj); //执行foo() this指向obj this.name = obj.name = 'nibao'
foo.apply(obj1); // 执行foo() this指向obj1 this.name = obj1.name = 'wohao'
foo.bind(obj2)(); // 执行foo() this指向obj2 this.name = obj2.name = 'dajiahao'
obj.foo.apply(obj2); // 执行obj.foo() this指向obj2 this.name = obj2.name = 'dajjiahao'
var a = new obj.foo(); // 执行obj.foo() this 指向 new构造的实例化对象a this.name = a.name = undefiend
var res = obj.foo.bind(obj2)
res() //执行obj.foo() bind()触发 this指向obj2 this.name = obj2.name = dajiahao
var res1 = obj.foo;
res1() //执行obj.foo() this指向window this.name = window.name = 'window'
这四种方式,使用构造器调用模式的优先级最高,然后apply、call和bind调用模式,然后是方法调用模式,然后是函数调用模式。
this关键字的判断规则:
- 一般情况下,全局作用域下的this指向window.
- 在箭头函数中, 没有this则使用上一层作用域中this, —> 判断上一层的this.
在函数体内:- new 关键字触发的函数, this指向 new创建的实例函数对象
- call() / apply() / bind() 触发的函数, this指向 方法API的参数中的参数一的对象。
- 普通对象触发的函数,谁调用就指向谁。