面向对象语言中 this 表示当前对象的一个引用。
但在 JavaScript 中 this 不是一成不变的,它会随着执行环境的改变而改变。
This指向的几种常见方式:
1、在方法中的this调用,在方法中this指向的是调用该方法的对象
2、在函数中调用,this指向window。
3、在构造函数中调用,this指向构造出来的对象(也就是指向通过new关键字创造的对象)
4、call、bind、apply方式调用,this指向这些方法的第一个参数
5、在事件中的this,this表示接收事件的元素
1、方法中的this调用
哪个对象调用了该方法this就指向该对象
var fn =function(){
console.log(this.name);
}
var obj={
name:'张三',
say:function(){
console.log(this.name);
},
foo:fn
}
var obj2={
name:'李四',
foo:fn
}
obj.foo()//张三
obj2.foo()//李四
obj.say()//张三
2、函数中this调用
函数中的this指向window,也就是全局对象,我们声明的a是一个全局变量
所以this.a就是指向了全局变量a,就输出了2
var a=2
function fn(){
console.log(this.a);//2
console.log(this.a==window.a);//true
}
fn()
3、构造函数中的this调用
构造函数中,this指向new出的实例对象
// 构造函数
function Person(name,age){
this.name=name
this.age=age
}
// new了一个构造函数的实例对象
var person = new Person('李四',20)
console.log(person.name);//李四
console.log(person.age);//20
4、call、bind、apply方式调用
使用了这三个方法,this就是指向了这三个方法的第一个参数,其实就是参数绑定的执行环境的对象,具体可以看我上一篇这三个用法的介绍。这里要的是注意bind返回的是一个函数。使用这个三个方法就实现this“指哪就打哪”的功能
function foo(){
console.log(this.name);
}
var obj1={
name:'李四',
}
var obj2={
name:'张三'
}
foo.call(obj1)//张三 this指向obj1
foo.call(obj2)//李四 this指向obj2
foo.apply(obj1)//张三
foo.apply(obj1)//李四
foo.bind(obj1)()//张三
foo.bind(obj2)()//李四
5、事件中this的调用
在事件中this指向了接收该事件的元素
<button onclick="this.style.display='none' console.log(this)"> 点我后我就消失了 </button>
点击按钮触发事件后的输出结果
6.案例
以下这案例大家可以猜猜输出什么,这个是牛客网上的题目
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log(this.foo);
console.log(self.foo);
(function() {
console.log(this.foo);
console.log(self.foo);
}());
}
};
myObject.func();
你做对了吗?
1.第一个this.foo输出bar,因为当前this指向对象myObject。
2.第二个self.foo输出bar,因为self是this的副本,同指向myObject对象。
3.第三个this.foo输出undefined,因为这个IIFE(立即执行函数表达式)中的this指向window。
4.第四个self.foo输出bar,因为这个匿名函数所处的上下文中没有self,所以通过作用域链向上查找,从包含它的父函数中找到了指向myObject对象的self。
7、总结
this总是指向函数的直接调用者(而非间接调用者)
如果有new关键字,this指向new出来的那个对象
在事件中,this指向触发这个事件的对象
总之,谁调用就指向谁