1. 程式人生 > >JS this指向總結

JS this指向總結

settime 參數 構造函數 而不是 stc 用途 let body 有一個

使用 JavaScript 開發的時候,很多開發者多多少少會被 this 的指向搞蒙圈,但是實際上,關於 this 的指向,記住最核心的一句話:哪個對象調用函數,函數裏面的this指向哪個對象。

下面分幾種情況談論下

1、普通函數調用

這個情況沒特殊意外,就是指向全局對象-window。

let username=‘cn‘
function fn(){
alert(this.username);//undefined
}
fn();

可能大家會困惑,為什麽不是輸出守候,但是在細看一看,我聲明的方式是let,不會是window對象

如果輸出守候,要這樣寫

var username=‘cn‘
function fn(){
alert(this.username);//cn
}
fu();
//---------------
window.username=‘cn‘
function fn(){
alert(this.username);//cn
}
fn();
//可以理解為
//window.fn();
---------------------
作者:weixin_37722222
來源:CSDN
原文:https://blog.csdn.net/weixin_37722222/article/details/81625826
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


2、對象函數調用

這個相信不難理解,就是那個函數調用,this指向哪裏

window.b=2222
let obj={
a:111,
fn:function(){
alert(this.a);//111
alert(this.b);//undefined
}
}
obj.fn();


很明顯,第一次就是輸出obj.a,就是111。而第二次,obj沒有b這個屬性,所以輸出undefined,因為this指向obj。

但是下面這個情況得註意

let obj1={
a:222
};
let obj2={
a:111,
fn:function(){
alert(this.a);
}
}
obj1.fn=obj2.fn;
obj1.fn();//222


這個相信也不難理解,雖然obj1.fn是從obj2.fn賦值而來,但是調用函數的是obj1,所以this指向obj1。

3、構造函數調用

let TestClass=function(){
this.name=‘111‘;
}
let subClass=new TestClass();
subClass.name=‘cn‘;
console.log(subClass.name);//cn
let subClass1=new TestClass();
console.log(subClass1.name)//111


這個也是不難理解,回憶下(new的四個步驟)就差不多了!

但是有一個坑,雖然一般不會出現,但是有必要提一下。

在構造函數裏面返回一個對象,會直接返回這個對象,而不是執行構造函數後創建的對象

apply和call調用

apply和call簡單來說就是會改變傳入函數的this。

let obj1={
a:222
};
let obj2={
a:111,
fn:function(){
alert(this.a);
}
}
obj2.fn.call(obj1);復制代碼


此時雖然是 obj2 調用方法,但是使用 了call,動態的把 this 指向到 obj1。相當於這個 obj2.fn 這個執行環境是 obj1 。apply 和 call 詳細內容在下面提及。

5、箭頭函數調用

首先不得不說,ES6 提供了箭頭函數,增加了我們的開發效率,但是在箭頭函數裏面,沒有 this ,箭頭函數裏面的 this 是繼承外面的環境。

一個例子

let obj={
a:222,
fn:function(){
setTimeout(function(){console.log(this.a)})
}
};
obj.fn();//undefined


不難發現,雖然 fn() 裏面的 this 是指向 obj ,但是,傳給 setTimeout 的是普通函數, this 指向是 window , window 下面沒有 a ,所以這裏輸出 undefined。

換成箭頭函數

let obj={
a:222,
fn:function(){
setTimeout(()=>{console.log(this.a)});
}
};
obj.fn();//222


這次輸出 222 是因為,傳給 setTimeout 的是箭頭函數,然後箭頭函數裏面沒有 this ,所以要向上層作用域查找,在這個例子上, setTimeout 的上層作用域是 fn。而 fn 裏面的 this 指向 obj ,所以 setTimeout 裏面的箭頭函數的 this ,指向 obj 。所以輸出 222 。

call和apply
call 和 apply 的作用,完全一樣,唯一的區別就是在參數上面。
call 接收的參數不固定,第一個參數是函數體內 this 的指向,第二個參數以下是依次傳入的參數。
apply接收兩個參數,第一個參數也是函數體內 this 的指向。第二個參數是一個集合對象(數組或者類數組)

let fn=function(a,b,c){
console.log(a,b,c);
}
let arr=[1,2,3];


如上面這個例子

let obj1={
a:222
};
let obj2={
a:111,
fn:function(){
alert(this.a);
}
}
obj2.fn.call(obj1);


call 和 apply 兩個主要用途就是

1.改變 this 的指向(把 this 從 obj2 指向到 obj1 )

2.方法借用( obj1 沒有 fn ,只是借用 obj2 方法)
---------------------
原文:https://blog.csdn.net/weixin_37722222/article/details/81625826

JS this指向總結