面向对象语言中 this 表示当前对象的一个引用。
但在 JavaScript 中 this 不是一成不变的,它会随着执行环境的改变而改变。
This指向的几种常见方式:
1、在方法中的this调用,在方法中this指向的是调用该方法的对象
2、在函数中调用,this指向window。
3、在构造函数中调用,this指向构造出来的对象(也就是指向通过new关键字创造的对象)
4、call、bind、apply方式调用,this指向这些方法的第一个参数
5、在事件中的this,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()//张三
函数中的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()
构造函数中,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
使用了这三个方法,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)()//李四
在事件中this指向了接收该事件的元素
<button onclick="this.style.display='none' console.log(this)"> 点我后我就消失了 </button>
点击按钮触发事件后的输出结果
以下这案例大家可以猜猜输出什么,这个是牛客网上的题目
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。
this总是指向函数的直接调用者(而非间接调用者)
如果有new关键字,this指向new出来的那个对象
在事件中,this指向触发这个事件的对象
总之,谁调用就指向谁