请写出输出内容闭包
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 大法