全局環境中thisnode
.node中this至關於全局對象 global。 .在JavaScript文件中, this等同於 module.exports而不是 global。bash
函數中的this 函數中的 this值一般是由函數的調用方來定義。app
function rajat() {
//this === window
}
複製代碼
方法中的「this」函數
當函數做爲對象的方法被調用時, this指向的是該對象,也稱爲函數調用的接收器(receiver)。ui
const hero = {
heroName: "Batman",
dialogue() {
console.log(`I am ${this.heroName}!`);
}
};
hero.dialogue();
複製代碼
構造函數中的「this」this
構造函數被調用時,會建立一個新對象並將其設置爲函數的 this參數。構造函數會隱式的返回這個對象,除非咱們明確的返回了另一個對象。 在 hero函數內部添加下面的 return語句:spa
function Hero(heroName, realName) {
return {
heroName: "Batman",
realName: "Bruce Wayne",
};
}
new Hero();//{heroName: "Batman", realName: "Bruce Wayne"}
function Hero(heroName, realName) {
heroName: "Batman";
realName: "Bruce Wayne";
}
new Hero();//Hero {}
複製代碼
call() 和 apply()code
在調用函數時也可使用 call()和 apply()明確設置 this參數。對象
function dialogue () {
console.log (`I am ${this.heroName}`);
}
const hero = {
heroName: 'Batman',
};
複製代碼
若是要將 hero對象做爲 dialogue函數的接收器,咱們能夠這樣使用 call()或 apply() :ip
dialogue.call(hero)
// or
dialogue.apply(hero)
複製代碼
bind()
當咱們將一個方法做爲回調函數傳遞給另外一個函數時,老是存在丟失方法的原有接收器的風險,使得 this參數指向全局對象。 bind()方法能夠將 this參數固定的綁定到一個值上。 下面的代碼片斷, bind會建立一個新的 dialogue函數,並將 this值設置爲 hero 。 (譯者注:bind()方法會建立一個新函數,稱爲綁定函數-bound function-BF,當調用這個綁定函數時,綁定函數會以建立它時傳入 bind()方法的第一個參數做爲 this,傳入 bind() 方法的第二個以及之後的參數加上綁定函數運行時自己的參數按照順序做爲原函數的參數來調用原函數。)
const hero = {
heroName: "Batman",
dialogue() {
console.log(`I am ${this.heroName}`);
}
};
setTimeOut(hero.dialogue.bind(hero), 1000);
複製代碼
使用 call或 apply方法也沒法改變 this的值 。
箭頭函數中的「this」
箭頭函數引用的是箭頭函數在建立時設置的 this值,不是執行時環境this。 箭頭函數會永久地捕獲 this值,阻止 apply或 call後續更改它。 爲了解釋箭頭函數中的 this是如何工做的,咱們來寫一個箭頭函數:
const batman = this;
const bruce = () => {
console.log(this === batman);//true
};
bruce();
複製代碼
(譯者注:箭頭函數中沒有this綁定,必須經過查找做用域鏈來決定它的值,若是箭頭函數被非箭頭函數包裹,那麼this值由外圍最近一層非箭頭函數決定,不然爲undefined。) 箭頭函數也不能用做構造函數。所以,咱們也不能在箭頭函數內給 this設置屬性。 那麼箭頭函數對 this 能夠作什麼呢? 箭頭函數可使咱們在回調函數中訪問 this 。
const counter = {
count: 0,
increase() {
setInterval(function() {
console.log(++this.count);
//只會獲得一個 NaN的列表。這是由於 this.count已經不是指向 counter對象了。
//它實際上指向的爲 global對象。
}, 1000);
}
}
counter.increase();
//使用箭頭函數
const counter = {
count: 0,
increase () {
setInterval (() => {
console.log (++this.count);
}, 1000);
},
};
counter.increase();
複製代碼
Class中的「this」
類一般包含一個 constructor , this能夠指向任何新建立的對象。 不過在做爲方法時,若是該方法做爲普通函數被調用, this也能夠指向任何其餘值。與方法同樣,類也可能失去對接收器的跟蹤。
class Hero {
constructor(heroName) {
this.heroName = heroName;
}
dialogue() {
console.log(`I am ${this.heroName}`)
}
}
const batman = new Hero("Batman");
batman.dialogue();
複製代碼
構造函數裏的 this指向新建立的 類實例。當咱們調用 batman.dialogue()時, dialogue()做爲方法被調用, batman是它的接收器。 可是若是咱們將 dialogue()方法的引用存儲起來,並稍後將其做爲函數調用,咱們會丟失該方法的接收器,此時 this參數指向 undefined 。
const say = batman.dialogue;
say();
複製代碼
出現錯誤的緣由是JavaScript 類是隱式的運行在嚴格模式下的。咱們是在沒有任何自動綁定的狀況下調用 say()函數的。要解決這個問題,咱們須要手動使用 bind()將 dialogue()函數與 batman綁定在一塊兒。
const say = batman.dialogue.bind(batman);
say();
複製代碼
咱們也能夠在 構造函數方法中作這個綁定。