// f2能够访问f1内的局部变量,因此返回f2就能在外部访问f1内的局部变量 - f2就是闭包
function f1() {
var n = 999;
function f2() {
console.log(n);
}
return f2;
}
var result = f1();
result(); // 999
// 注意闭包返回f2与f2()的区别 - 带上括号返回的是函数调用,不带括号仅函数名返回的是函数
function f1() {
var n = 999;
function f2() {
console.log(n);
}
return f2();
}
var result = f1(); // 999
1.2 作用
读取函数内部的变量
变量的值始终保持在内存中 - 保存变量现场
封装 - 信息隐藏
// Example1
function f1() {
var n = 999;
nAdd = function () {
n += 1
}
function f2() {
alert(n);
}
return f2;
}
var result = f1();
result(); // 999
// nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量,但是需要先调用一次f1()才会生成全局变量nAdd。
nAdd();
// f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收,因此f1的局部变量n也一直保存在内存中。
result(); // 1000
// ES5
let a = 'hello <b>' + basket.count + '</b>';
// ES6 - 多行字符串所有的空格和缩进都会被保留在输出之中
let a = `hello <b> ${basket.count} </b>`;
let a = `
<ul>
<li>first</li>
<li>second</li>
</ul>
`;
模板字符串紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。
let message = SaferHTML`<p>${sender} has sent you a message.</p>`;
function SaferHTML(templateData) {
let s = templateData[0];
for (let i = 1; i < arguments.length; i++) {
let arg = String(arguments[i]);
// Escape special characters in the substitution.
s += arg.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
// Don't escape special characters in the template.
s += templateData[i];
}
return s;
}
// 普通的add函数
function add(x, y) {
return x + y
}
// Currying后
function curryingAdd(x) {
return function (y) {
return x + y
}
}
add(1, 2) // 3
curryingAdd(1)(2) // 3