1、首先
- 首先要解釋下,函式體內變數的作用域是在函式定義的時候就確定的,而不是運行時;
- 函式的背景關系是在呼叫時確定的,函式體內的this指向其背景關系;
- 箭頭函式沒有自己的this,它的this指向的是它上級的this,而它上級的this指向的是上級的背景關系,
2、普通函式的this,指向其呼叫者,箭頭函式this,指向其上級this
let app = {
a: 1,
fn: function () {
console.log('app.fn:', this, this.a);
// this指向需要函式被呼叫時才能確定,當app.fn()執行,
// 確定其背景關系為app,所以this指向app物件
// this.a = app.a = 1
}
}
window.a = 0
let app2 = {
a: 2,
fn: () => {
console.log('app2.fn:', this, this.a);
// app2.fn()執行,背景關系為app2,this本應指向app2物件,
// 但是fn是箭頭函式,所以this指向它上級的this,也就是
// 指向app2的this,由于app2的this指向的是其背景關系,所以這里就是window,
// this.a = window.a = 0
}
}
拓展:var、let和const宣告的資料,作用域不同,var宣告的物件可以在global全域作用域下查找,也就是賦值給了window物件;而let和const宣告的物件只能在script作用域下查找,所以window物件上不會顯示宣告的app等物件和函式,var宣告的物件和function函式都可以在global全域作用域下找到,
說到了script,多個script在瀏覽器中一般是分塊編譯的,不是同時編譯,但是作用域只有一個,就是script作用域,
3、seiTimeout中的this,指向window,箭頭函式this,指向其上級this
let app3 = {
a: 3,
fn: function () {
setTimeout(() => {
console.log('app3.fn:', this, this.a);
// app3.fn()執行,但輸出陳述句在setTimeout中,
// this本應指向window,但箭頭函式的this指向其上級的this,
// 所以this指向fn的this,也就是fn的背景關系,this指向app3物件
// this.a = app3.a = 3
}, 1000);
}
}
let app4 = {
a: 4,
fn: ()=> {
setTimeout(() => {
console.log('app4.fn:', this, this.a);
// app4.fn()執行,this本應指向window,
// 但箭頭函式的this指向fn的this,fn的this指向app4的this,
// app4的this指向app4的背景關系
// 所以this指向app4的背景關系,this指向window
// this.a = window.a = 0
}, 1000);
}
}
let app5 = {
a:5,
fn:function(){
setTimeout(() => {
console.log('app5.fn:', this, this.a);
// app5.fn()執行,this指向fn的this,
// fn的this指向fn的背景關系,也就是this指向app5
// this.a = app5.a = 5
}, 1000);
}
}
4、陣列中的函式,呼叫后的this,指向該陣列
function app6() {
console.log('app6.fn:', this, this.a);
}
let arr = [0, 1, 2, app6]
arr[3]() // 函式執行,背景關系是arr陣列,this指向arr,
// this.a = undefined, this[0] = 0
5、事件處理函式的this,指向觸發事件的物件
6、可用call、apply和bind改變this指向
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/545976.html
標籤:其他
