【面試題】JavaScript不要用name作全局變量名

這是2020海康威視的一道筆試題

var obj = {
	name: 'zpj',
	sayHello: ()=>'Hello ' + this.name
}
obj.sayHello(); // ?

1. 分析:

  1. this指向取決於函數的調用方式。如果是function函數,當作方法調用打印的應該是’zpj’
var obj = {
	name: 'zpj',
	sayHello: function(){return 'Hello ' + this.name;}
}
obj.sayHello(); // 'zpj'
  1. 箭頭函數的this指向繼承自外部環境的this指向。這裏指向window,所以是在輸出window.name。我們並沒有var name;顯式聲明,所以認爲window.name = undefined,猜測輸出的應該是'Hello undefined',但是事實上輸出的卻是‘Hello ’
var obj = {
	name: 'zpj',
	sayHello: ()=>'Hello ' + this.name
}
obj.sayHello(); // ‘Hello ’
  1. 直接輸出window.name發現輸出不是undefined而是空字符串""
  2. 原來,window.name是每個網頁默認有的屬性,記錄open方法或iframe給定的name屬性
window.open('https://www.baidu.com', 'mywin');
// 然後在新的頁面裏
window.name === 'mywin'; // true
  1. 如果變量名不是特殊的name,輸出就會“如您所願”了
var obj = {
	_name: 'zpj',
	sayHello: ()=>'Hello ' + this._name
}
obj.sayHello(); // 'Hello undefined'
  1. 可以使用call來改變this指向使得輸出正確嗎?答案是NO!箭頭函數的this指向無法改變。
var obj = {
	_name: 'zpj',
	sayHello: ()=>'Hello ' + this._name
}
obj.sayHello.call(obj); // 'Hello undefined'

2. 總結

  1. 全局環境下定義的變量會自動註冊爲window的屬性
  2. name, self, top, location, status 等不要作爲全局變量名,因爲他們都是window的屬性
  3. 對象方法不要使用箭頭函數定義,this指向會錯誤
  4. 箭頭函數this指向無法改變
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章