《你不知道的JavaScript(上卷)》筆記:作用域閉包
阿新 • • 發佈:2019-02-17
- 當函式可以記住並訪問所在的詞法作用域時,就產生了閉包,即使函式是在當前詞法作用域之外執行。
function foo() {
var a = 2;
function bar(){
console.log(a);
}
return bar;
}
var baz = foo();
baz(); // 2
- 無論通過何種手段將內部函式傳遞到所在的詞法作用域意以外,他都會持有對原始定義作用域的引用,無論在何處執行這個函式,都會使用閉包。
- 無論何時何地,如果將函式當作第一級的值型別併到處傳遞,就會看到閉包在這些函式的應用。只要使用了回撥函式,實際上就是在使用閉包。
for迴圈中的閉包
for (var i = 0; i < 5; i++) { (function (j) { setTimeout(function timer() { console.log(j); }, 1000 * j); })(i); }
模組
- 基礎
function CoolModule() {
var something = 'cool';
var another = [1,2,4];
function doSomething() {
console.log( something );
}
function doAnother() {
console.log(another.join(' ! '));
}
return {
doSomething: doSomething,
doAnother: doAnother
}
}
var foo = CoolModule();
foo.doSomething();
foo.doAnother();
- 單例模式
var foo = (function CoolModule() {
var something = 'cool';
var another = [1,2,4];
function doSomething() {
console.log( something );
}
function doAnother() {
console.log(another.join(' ! '));
}
return {
doSomething: doSomething,
doAnother: doAnother
}
})();
foo.doSomething();
foo.doAnother();
- 修改公共API
var foo = (function CoolModule(id) {
function change() {
publicAPI.identify = identify2;
}
function identify1() {
console.log( id );
}
function identify2() {
console.log(id.toUpperCase);
}
var publicAPI = {
change: change,
identify: identify1
}
return publicAPI;
})('foo module');
foo.identify(); //foo module
foo.change();
foo.identify(); // FOO MODULE
- 現代模組機制
var MyModules = (function Manager(){
var modules = {};
// name:模組明 deps:依賴模組 impl:模組實現的功能
function define(name, deps, impl) {
for(var i = 0; i < deps.length; i++){
deps[i] = modules[deps[i]];
}
modules[name] = impl.apply(impl, deps);
}
function get(name) {
return modules[name];
}
})();
MyModules.define("bar", [], function(){
function hello(who) {
return "Let me introduce: " + who;
}
return {
hello: hello
}
})
MyModules.define("foo", ['bar'], function() {
var hungry = "Hippo";
function awesome() {
console.log(bar.hello(hungry).toUpperCase());
}
return {
awesome: awesome
}
});
var bar = Mymodules.get("bar");
var foo = Mymodules.get("foo");
// let me introduce: hippo
console.log( bar.hello("hippo") );
// LET ME INTRODUCE: HIPPO
foo.awesome();
- 未來模組機制:import、export、module
小結
- 當函式可以記住並訪問所在的詞法作用域,即使函式上在當前詞法作用域之外執行,這時就產生了閉包。
- 模組有2個主要特徵:(1)為建立內部作用域而呼叫了一個包裝函式;(2)包裝函式的返回值必須至少包含一個對內部函式的引用,這樣就會建立涵蓋整個包裝函式內部作用域的閉包。