-
函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是
其声明时所在的作用域
,与其运行时所在的作用域无关。(与this不一样)var a = 1111; var x = function () { console.log(a); }; function f() { var a = 2222; x(); } f() // 1111
- 函数x是在函数f的外部声明的,所以它的作用域绑定外层,内部变量a不会到函数f体内取值,所以输出1111,而不是2222。
- 总之,函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域。
-
闭包
function f1() { var n = 123; } console.log(n) // Uncaught ReferenceError: n is not defined // 函数f1内部声明的变量n,函数外是无法读取的。
-
正常情况下,这是办不到的,只有通过变通方法才能实现。那就是在函数的内部,再定义一个函数。
function f1() { var n = 123; function f2() { console.log(n); // 123 } }
-
JavaScript语言特有的”链式作用域”结构(chain scope)
,子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
-
-
f2可以读取f1的局部变量,那么只要把f2作为返回值,在f1的外部读取f1定义变量的值
```js function f1() { var n = 123; function f2() { console.log(n); } return f2; } var result = f1(); result(); // 123 ```
闭包最大的特点,就是它可以“记住”诞生的环境,比如f2记住了它诞生的环境f1,所以从f2可以得到f1的内部变量。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
-
-
闭包和私有数据
const uniqueId = (function() { let count = 0; return function() { ++count; return id_${count}; }; })(); console.log(uniqueId()); // "id_1" console.log(uniqueId()); // "id_2" console.log(uniqueId()); // "id_3"
在IIEF之外无法访问这个计数变量count。除了从IIEF中返回的函数,别人无法读写该变量。这样就能创建真正的私有状态,它只能以受控的方式进行修改。
const counter = (function() { let counterValue = 0; return { increment() { ++counterValue; }, get value() { return counterValue; } }; })(); counter.increment(); console.log(counter.value); // 1 counter.increment(); counter.increment(); console.log(counter.value); // 3
函数闭包的理解
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 一、变量...