這是2020海康威視的一道筆試題
var obj = {
name: 'zpj',
sayHello: ()=>'Hello ' + this.name
}
obj.sayHello();
1. 分析:
- this指向取決於函數的調用方式。如果是function函數,當作方法調用打印的應該是’zpj’
var obj = {
name: 'zpj',
sayHello: function(){return 'Hello ' + this.name;}
}
obj.sayHello();
- 箭頭函數的this指向繼承自外部環境的
this
指向。這裏指向window
,所以是在輸出window.name
。我們並沒有var name;
顯式聲明,所以認爲window.name = undefined
,猜測輸出的應該是'Hello undefined'
,但是事實上輸出的卻是‘Hello ’
var obj = {
name: 'zpj',
sayHello: ()=>'Hello ' + this.name
}
obj.sayHello();
- 直接輸出
window.name
發現輸出不是undefined
而是空字符串""
- 原來,
window.name
是每個網頁默認有的屬性,記錄open
方法或iframe
給定的name
屬性
window.open('https://www.baidu.com', 'mywin');
window.name === 'mywin';
- 如果變量名不是特殊的name,輸出就會“如您所願”了
var obj = {
_name: 'zpj',
sayHello: ()=>'Hello ' + this._name
}
obj.sayHello();
- 可以使用call來改變this指向使得輸出正確嗎?答案是NO!箭頭函數的this指向無法改變。
var obj = {
_name: 'zpj',
sayHello: ()=>'Hello ' + this._name
}
obj.sayHello.call(obj);
2. 總結
- 全局環境下定義的變量會自動註冊爲
window
的屬性
name
, self
, top
, location
, status
等不要作爲全局變量名,因爲他們都是window
的屬性
- 對象方法不要使用箭頭函數定義,
this
指向會錯誤
- 箭頭函數this指向無法改變