javascript 函数初探 (六)--- 闭包初探#4
2016-08-27 16:10
316 查看
循环中的闭包:
让我们来看一下一个会循环三次的操作,她在每次迭代中都会创建一个返回当前序列号的新函数,该函数会被添加到一个数组中,并最终返回:
显然这不是我们想要的结果。为啥呢?
原来我们在三次循环中创建了三个闭包,而他们最终都指向了一个共同的局部变量i。但是闭包不会记录她们的值(上文说过),她们有的只不过是相关域在创建时的一个链接(引用)。
在这个例子中,变量i恰巧存在于定义这三个函数作用域中。对于这三个函数而言,当她们要获取某个变量时,她会从其所在的域开始逐级向上找那个距离最近的i,由于循环结束时i值为3,所以这三个值同时指向了这一个i值。
如何纠正这种行为呢?答案是换一种闭包形式:
这里我们不再直接创建一个返回i的函数了,而是将i传递给了另一个即时函数,在即使函数中i就被赋值给了局部变量x,这样一来每次循环都会有不同作用域的局部变量x,那么以来每个函数中的x值都会不同了。
或者我们可以来个正常点的:
目的是为了使中间函数将i值本地化。
假如我们不想把一个变量暴露到全局作用域中,因为这样的话,其他代码就会有修改她们的可能,所以我们会把这个变量保护到相关函数内部,然后提供两个额外的函数, getter(),setter()。一个用来获取变量,另一个用来对变量赋值。
下面一些章节我们来探讨一下对象,敬请期待。。。
让我们来看一下一个会循环三次的操作,她在每次迭代中都会创建一个返回当前序列号的新函数,该函数会被添加到一个数组中,并最终返回:
function F(){ var arr = [], i; for(i=0; i<3; i++){ arr[i] = function(){ return i; } } return arr; } var arr = F(); arr[0](); // 3 arr[1](); // 3 arr[2](); // 3
显然这不是我们想要的结果。为啥呢?
原来我们在三次循环中创建了三个闭包,而他们最终都指向了一个共同的局部变量i。但是闭包不会记录她们的值(上文说过),她们有的只不过是相关域在创建时的一个链接(引用)。
在这个例子中,变量i恰巧存在于定义这三个函数作用域中。对于这三个函数而言,当她们要获取某个变量时,她会从其所在的域开始逐级向上找那个距离最近的i,由于循环结束时i值为3,所以这三个值同时指向了这一个i值。
如何纠正这种行为呢?答案是换一种闭包形式:
function F(){ var arr = [], i; for(i=0; i<3; i++){ arr[i] = (function(x){ return function(){ return x; } })(i); } return arr; } var arr = F(); arr[0](); // 0 arr[1](); // 1 arr[2](); // 2
这里我们不再直接创建一个返回i的函数了,而是将i传递给了另一个即时函数,在即使函数中i就被赋值给了局部变量x,这样一来每次循环都会有不同作用域的局部变量x,那么以来每个函数中的x值都会不同了。
或者我们可以来个正常点的:
function F(){ fucntion her(x){ return function(){ return x; }; }; var arr = [], i; for(i=0; i<3; i++){ arr[i] = her(i); }; return arr; }
目的是为了使中间函数将i值本地化。
假如我们不想把一个变量暴露到全局作用域中,因为这样的话,其他代码就会有修改她们的可能,所以我们会把这个变量保护到相关函数内部,然后提供两个额外的函数, getter(),setter()。一个用来获取变量,另一个用来对变量赋值。
var gets, sets; (function(){ var a = 0; getValue = function(){ return a; } setValue = function(v){ if(typeof v === 'number'){ a = v } } })(); setValue(1); getValue(); // 1
下面一些章节我们来探讨一下对象,敬请期待。。。
相关文章推荐
- JS精确计算bug
- javascript创建对象
- javascript 函数初探 (六)--- 闭包初探#3
- json返回日期格式化的解决
- javascript 函数初探 (六)--- 闭包初探#2
- js select实现省市区联动选择
- 服务器端解决JS跨域调用问题
- javascript 函数初探 (六)--- 闭包初探#1
- 【 D3.js 入门系列 --- 2 】 如何使用数据和选择元素
- [Javascript] Promise
- JSON对象
- JavaScript setTimeout() clearTimeout() 方法
- JS插件检测
- jsp页面表格中<textarea>标签的菜鸟级错误
- 通过Ajax技术,将数组类型数据转换为JSON格式的对象
- 轻松掌握JavaScript装饰者模式
- linkbutton.js
- canvas动画之文字粒子效果
- 图片懒加载解决方案 lazyload.js
- javascript Date format(js日期格式化)