6.3 闭包
一个“变量”只是 环境记录 这个特殊的内部对象的一个属性。“获取或修改变量”意味着“获取或修改词法环境的一个属性”。
所有的函数在“诞生”时都会记住创建它们的词法环境。
闭包 是指内部函数总是可以访问其所在的外部函数中声明的变量和参数,即使在其外部函数被返回(寿命终结)了之后。
函数将从内到外依次在对应的词法环境中寻找目标变量,它使用最新的值。
6.4 var
var 只有函数作用域和全局作用域,没有块级作用域
var 允许重复声明
var 变量声明会提升,但赋值不会
IIFE 立即执行函数创建私有变量(现在已不使用)
// 创建 IIFE 的方法
(function() {
alert("Parentheses around the function");
})();
(function() {
alert("Parentheses around the whole thing");
}());
!function() {
alert("Bitwise NOT operator starts the expression");
}();
+function() {
alert("Unary plus starts the expression");
}();
6.6 函数 NFE
命名函数表达式(NFE,Named Function Expression)
方便函数自己调用自己,且该名称不能在外部访问
let sayHi = function func(who) {
if (who) {
alert(`Hello, ${who}`);
} else {
func("Guest"); // 使用 func 再次调用函数自身
}
};
sayHi(); // Hello, Guest
// 但这不工作:
func(); // Error, func is not defined(在函数外不可见)
6.7 new Function([arg1,arg2], functionbody)
使用 new Function 创建的函数,它的 [[Environment]] 指向全局词法环境,而不是函数所在的外部词法环境。
因此,我们不能在 new Function 中直接使用外部变量。
6.8 调度函数
任何 setTimeout 都只会在当前代码执行完毕之后才会执行。
6.10 函数绑定
一个函数不能被重绑定(re-bound)
function f() {
alert(this.name);
}
f = f.bind({ name: "John" }).bind({ name: "Pete" });
f(); // John
bind 的结果是另一个对象。
function sayHi() {
alert(this.name);
}
sayHi.test = 5;
let bound = sayHi.bind({
name: "John",
});
alert(bound.test); // undefined