最近有点闲暇时间,就来总结js中this的指向问题,如有不对,请指出。
this指向,网上做多的描述是指向那个最终调用的对象。对于这句话,一直不太明白。下面我们用几个例子来理解这个问题。
function a(){
console.log(this.user)
};
var user = 'alisa';
a()//alisa
此时a的调用者是 window ,所以会取定义在全局的user;
例子1.
function a(){
this.user = 'mfz';
console.log(this.user)
}
var user = 'alisa';
a()//mfz;
function a(){
this.user = 'mfz';
user = 'milk';
console.log(this.user)
}
var user = 'alisa';
a()//milk;
例子2.
var a ={
user:'alisa',
fn:function(){
console.log(this.user)
}
}
a.fn();//alisa
箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),而不是执行时的对象, 定义它的时候,可能环境是window;
var a = {
user:'alisa',
fn:()=>{
console.log(this.user);
}
};
var user = ‘mfz’;
a.fn();//mfz;
下面看下 settimeout 和setinterval 的例子
var a= {
say: function () {
setTimeout(function () {
console.log(this)
});
}
}
a.say();//window
var q= {
say: function () {
setTimeout(() => {
console.log(this)
});
}
}
q.say(); // say()
此时的 this继承自q, 指的是定义它的对象q, 而不是 window!
{
console.log(1,this);//1,window
var xx = "bb"
var obj={
xx:"aa",
foo:()=>{
console.log(2,this,this.xx);//2,window ,bb
}
};
obj.foo()// 此时的this是和 console.log(1,this); 指向一致 所以会打出 bb 而不是aa
}
如果不是箭头函数
{
console.log(1,this);//1,window
var xx = "bb"
var obj={
xx:"aa",
foo:function(){
console.log(2,this,this.xx);//2,obj,aa
}
};
obj.foo()// 此时的this是指向的obj 所以会打印出 aa
}
当有对象形式声明函数时,不存在作用域,里面的匿名函数始终与 最外层指向一致,通过call pllay bind 一些也无法改变其指向
{
console.log(1,this);
var xx = "bb";
var obj={
xx:"aa",
foo:()=>{
console.log(2,this,this.xx);
}
};
var obj2 = {xx:"obj2-xx"}
obj.foo.call(obj2)//无法改变其指向,还是和console.log(1,this)同一层
}
{
console.log(1,this);
var xx = "bb";
var obj={
xx:"aa",
foo:function(){
console.log(2,this,this.xx);
}
};
var obj2 = {xx:"obj2-xx"}
obj.foo.call(obj2)//指向改变 ,打印出 2,obj2,obj2-xx
}
但是在函数作用域内情况就不一样了 。
下面看两个例子
//普通函数
function foo(){
setTimeout(function(){
console.log(this.id);// 22,指向window
},100);
console.log(this.id)//43 函数作用域问题,只有外面一层受影响
}
var id = 22;
foo.call({id:43});//22 ,43 foo的调用函数始终指向window
//箭头函数
function foo(){
setTimeout(() => {
console.log(this.id);//id 是指向foo父级
},100);
}
var id = 22;
foo.call({id:43});//43