最近有點(diǎn)閑暇時(shí)間片拍,就來(lái)總結(jié)js中this的指向問(wèn)題煌集,如有不對(duì),請(qǐng)指出捌省。
this指向苫纤,網(wǎng)上做多的描述是指向那個(gè)最終調(diào)用的對(duì)象。對(duì)于這句話(huà)纲缓,一直不太明白卷拘。下面我們用幾個(gè)例子來(lái)理解這個(gè)問(wèn)題。
function a(){
console.log(this.user)
};
var user = 'alisa';
a()//alisa
此時(shí)a的調(diào)用者是 window 祝高,所以會(huì)取定義在全局的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
箭頭函數(shù)沒(méi)有自己的this, 它的this是繼承而來(lái); 默認(rèn)指向在定義它時(shí)所處的對(duì)象(宿主對(duì)象),而不是執(zhí)行時(shí)的對(duì)象, 定義它的時(shí)候,可能環(huán)境是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()
此時(shí)的 this繼承自q, 指的是定義它的對(duì)象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()// 此時(shí)的this是和 console.log(1,this); 指向一致 所以會(huì)打出 bb 而不是aa
}
如果不是箭頭函數(shù)
{
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()// 此時(shí)的this是指向的obj 所以會(huì)打印出 aa
}
當(dāng)有對(duì)象形式聲明函數(shù)時(shí)雷厂,不存在作用域,里面的匿名函數(shù)始終與 最外層指向一致叠殷,通過(guò)call pllay bind 一些也無(wú)法改變其指向
{
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)//無(wú)法改變其指向改鲫,還是和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
}
但是在函數(shù)作用域內(nèi)情況就不一樣了 。
下面看兩個(gè)例子
//普通函數(shù)
function foo(){
setTimeout(function(){
console.log(this.id);// 22诊县,指向window
},100);
console.log(this.id)//43 函數(shù)作用域問(wèn)題,只有外面一層受影響
}
var id = 22;
foo.call({id:43});//22 ,43 foo的調(diào)用函數(shù)始終指向window
//箭頭函數(shù)
function foo(){
setTimeout(() => {
console.log(this.id);//id 是指向foo父級(jí)
},100);
}
var id = 22;
foo.call({id:43});//43