請寫出輸出內容閉包
var fullname = "aaa";
var obj = {
fullname: "bbb",
getFullName: () => this.fullname,
prop: {
fullname: "ccc",
getFullName: function() {
return this.fullname;
}
}
};
console.log(obj.prop.getFullName());
console.log(obj.getFullName());
var func1 = obj.prop.getFullName;
console.log(func1());
var func2 = obj.getFullName;
console.log(func2());
複製代碼
很顯然,這道題就是在考察this 綁定的問題。來複習一下關於 this 的知識點ide
在絕大多數狀況下,函數的調用方式決定了this的值。this不能在執行期間被賦值,而且在每次函數被調用時this的值也可能會不一樣。
函數
簡單說就是this 會指向調用者的對象ui
so easy,答案很簡單this
第一,調用者是 obj.prop, 應該是 cccspa
第二和第四,由於綁定了 obj,因此都是 bbbcode
第三,調用者是 window,因此是 aaa對象
"ccc", "bbb", "aaa", "bbb";
複製代碼
等等,是否是太順利了,果真翻開答案一看事件
"ccc", "aaa", "aaa", "aaa";
複製代碼
誒?箭頭函數不是綁定父級做用域的麼,難道出現了幻覺?爲何會綁定到 window 上呢?ip
先查一下 MDN,在箭頭函數中,this 與封閉詞法環境的 this 保持一致
那好,先來查一下封閉詞法環境(enclosing lexical context)是什麼東東。
A function serves as a closure in JavaScript, and thus creates a scope, so that (for example) a variable defined exclusively within the function cannot be accessed from outside the function or within other functions
函數在JavaScript中被解析爲一個閉包,從而建立了一個做用域,使其在一個函數內定義的變量不能從函數外訪問或從其餘函數內訪問。
那麼難道是說只有函數才能建立做用域,其餘變量都是不行的麼?咱們來驗證一下
var fullname = "aaa";
var obj = {
fullname: "bbb",
prop: {
fullname: "ccc",
getFullName: () => this.fullname
}
};
console.log(obj.prop.getFullName());
function A() {
this.fullname = "bbb";
}
var a = new A();
a.getFullName = () => this.fullname;
console.log(a.getFullName());
// 'aaa' 'aaa'
複製代碼
結果代表,無論是字面量仍是 new 出來的對象都是沒法建立做用域的
那麼問題來了 this 的做用域在會隨着上層函數的做用域變化而變化麼?讓咱們來驗證一下
var fullname = "aaa";
var obj = {
fullname: "bbb",
getFullName: function() {
return (() => this.fullname)();
}
};
console.log(obj.getFullName());
var getFullName = obj.getFullName;
console.log(getFullName());
// 'bbb', 'aaa'
複製代碼
答案是確定的。好了,新知識 get 到手。
箭頭函數的 this 指向父級函數的 this,對象沒法建立做用域
最後來複習一下關於 this 的相關知識,這裏祭出MDN 大法