-
函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是
其声明时所在的作用域
,与其运行时所在的作用域无关。(与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语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 一、变量...