在前端javascript中,最难理解的就是this的指向问题,这也是面试中最常见的问题。那就看下this存在哪些场景中。
先来看下几个场景
存在对象之中
var name = 'window_leon'
var obj = {
name:'leon',
fn:function(){
console.log(this.name);
}
};
obj.fn();
这时候断点this的时候,this显示的是对象obj。可以获取到对象的name和fn,所以最后控制台输出的是leon。再来看下在普通函数之中的this。
var age = '33333';
var getAge = function(){
console.log(this.age);
}
getAge();
执行普通函数时,打印出33333。此时的this指向的对象是window全局。再来看下在构造函数的时候。
function People(city){
this.city = city;
};
var p = new People('suzhou');
console.log(p.city);
调试发现在构造函数中的this指向的是当前构造函数,city属性又挂载在People的原型链上,所以p.city相当于People.city。
从上面3个简单的栗子中可以总结出一个规律,在javascript中的this,始终指向那个最后调用的那个对象。对象中的obj.fn()指向了obj;普通函数中的getAge()相当于window.getAge(),所以最后的this指向了window;
知道了this的指向,下面就是如何改变this的指向。在js中改变this的指向主要使用的就是call,apply和bind三种方法
使用区别
传递参数时,apply是使用数组的形式来传递。调用触发时,bind需要手动触发函数。
var obj1 = {
name:'leon1',
age:23
};
var obj2 = {
name:'leon2',
age:33
};
var demo = {
name:'demo',
fn:function(){
console.log(this.name);
}
};
var test = {
fn:function(a,b){
console.log(this.name+"++++++"+a+"==========="+b);
}
};
test.fn.call(obj1,1,2);
test.fn.apply(obj2,[2,3]);
test.fn.bind(obj1,4,5)();
demo.fn();//demo
demo.fn.call(obj1);//leon1
demo.fn.apply(obj2);//leon2
demo.fn.bind(obj1)();//leon1
三者的第一个参数都是传递你需要指向的对象,后面是传递的参数。在使用bind的时候需要注意下兼容性主流都支持,IE11才开始支持这个方法。
其他改变指向方法
var other = {
test:'1234',
fn:function(){
// var self = this;
setTimeout(function(){
// console.log(self.test);
console.log(this.test);
},100)
}
}
other.fn();
在settimeout中,由于是window调用setTimeOut,所以this指向了window,输出的结果undefined。如果执行var self = this时,this的指向为other对象,通过self变量保存起来。此时在setTimeOut中使用self.test时,从other对象中找到test。ES6中的箭头函数中,this的使用则完全颠覆上面所说的this始终指向最后调用它的对象。在箭头函数中,this绑定按照所在函数在哪个对象下面,多层嵌套下,this指向最外层。
如果有写的不对的,理解错的请指出,谢谢