相关文章推荐
腹黑的鸵鸟  ·  java.time包 LocalDate ...·  1 年前    · 
俊秀的滑板  ·  Mysql数据分组GROUP BY ...·  1 年前    · 
喝醉的草稿纸  ·  Perl ...·  1 年前    · 

最近在工作中遇到一个让人头疼的问题,需要定义21个函数,函数的主体是一样的,功能也是一致的,仅仅是返回值不同。基本的结构是这样的

var arr = ["a","b","c","d"];
var funcArr = [];
for (var i = 0; i < 4; i++) {
	funcArr[i] = function(){
		return arr[i];
var result = funcArr[0]();
console.log(result);    //undefined

表面上看,每个函数都应该基于自己在数组中的位置返回不同的值,但是实际上,每次返回的都是undefined。这是为什么呢?

纠结了很久没解决掉。过了大概一个月的时间,在《js高程》上看到了一个相似的例子。

function createFunctions(){
	var result = new Array();
	for(var i=0; i<10; i++){
		result[i] = function(){
			return i;
	return return

    这个函数返回一个函数数组。还有一点点闭包的意味,但是这不是重点,重点是书上这就话“闭包只能取得包含函数中任何变量的最后一个值”。作用链的这种机制,注定了在循环中定义函数会产生这种副作用。虽然在实际中我并没有用到闭包,但是原理是一样的,都是作用域联的问题。当createFunctions()函数返回时,i的值为10,此时每个函数都引用着保存变量i的同一个变量对象,所以每个函数内部i的值都是10。

    换做我遇到的问题。函数在应用时,循环早已停止,当前的i值是4,函数返回值是arr[4],就是undefined。

    解决方案是创建另一个匿名函数强制让闭包行为符合预期。应用到我的例子就是这样:

var arr = ["a","b","c","d"];
var funcArr = [];
for (var i = 0; i < 4; i++) {
	funcArr[i] = function(num){
		return function(){
			return arr[num];
var result = funcArr[0]();
console.log(result);    //"a"

    立即执行函数保证了每个函数中的i是当时循环到的i值,即使循环结束,i值在循环中已经以副本num的形式确定下来了。

//2018-03-29******

    可以使用ES6的新的声明变量的方法解决这个问题,简单优雅,看代码:

var arr = ["a","b","c","d"];
var funcArr = [];
//使用let代替var
for (let i = 0; i < 4; i++) {
	funcArr[i] = function(){
		return arr[i];
var result = funcArr[0]();
console.log(result);    //"a"
    let声明的变量是块级作用域的。循环中不会共享一个i值。 在JavaScript1.2之前,函数定义是只允许在顶层全局代码,但1.2的JavaScript可以嵌套函数定义其他函数也是可以的。 仍然存在的函数定义可以循环或条件之内不会出现限制。在函数定义这些限制只适用于函数声明与函数语句。 函数文本(在JavaScript1.2引入的另一个功能)可能出现在任何JavaScript表达式,这意味着它们可以出现在if else语句内。 下面就是我们两个嵌套函数的例子。这可能会有点混乱,但它的工作原理完全正常: [removed] function hypotenuse(a, b) { 或一个函数的重复命名的参数(例如,function foo(val1, val2, val1){})时抛出一个错误,从而捕捉到你的代码几乎肯定是一个错误,否则你可能会浪费很多时间去追踪。最重要的是,在严格模式下,在eval()语句声明的变量和函数不会在包含的范围内创建。事实上,JavaScript的许多微妙之处导致了许多常见问题,这些问题阻碍了它的工作——我们在这里讨论了其的10个问题,在成为一名优秀的JavaScript开发人员的过程,需要注意和避免这些问题。==(而不是==和! 最近项目有个需求,动态写入节点(产品)并监听,如果用户点击后重新计算费用,但事先不知道产品的数量和内容,所以jsp的勾选框是动态生成的,生成jsp的勾选框后,又要动态生成js function,对每一个勾选框分别监听,监听到用户点击后,改变那个框的值,并执行计算费用的程序。 这里用动态js的目的是不希望增加后台服务器的负担,所以请求一次后,所有后续操作的计算都在js里计算,不再请求后台 解决思... javascript ----- forEach()循环函数: forEachl()添加的函数循环的次数是数组的长度,每次循环传入三个实参。 var arr = [1,2,3,4,5,6]; //浏览器传进三个实参, // 第一个是数组的每个元素, // 第二个是索引下标, // 第三个是整个数组 arr.forEach(function(a,b,c){ alert(a+" "+" "+b+" "+ 自定义函数的关键字:function函数名区分大小写,且不能相同,更不能使用JavaScript关键字。在function关键字之前不能指定返回值的数据。函数定义[ ]是指可选的,也就是说,自定义的函数可以带参数,也可以不带参数。如果有参数,参数可以是变量、常量或表达式。自定义的函数可以有返回值,也可以没有,如果省略了return语句,则函数返回undefined。函数必须放在标签之间。定义函数时并不执行组成该函数的代码,只有调用函数时才执行代码。调用函数函数名和“( )”必须书写。 用 Function 类直接创建函数的语法如下: var function_name = new function(arg1, arg2, ..., argN, function_body) 在上面的形式,每个 arg 都是一个参数,最后一个参数是函数主体(要执行的代码)。这些参数必须是字符串。 大多数情况下,这都可以被一般的传参式创建所替代,但是有些特别的情况只能使用上述方 上篇博客我们已经知道了,程序运行的三大结构,顺序结构,选择机构,现在我们要来学习选循环结构。 2、循环结构 字面理解,循环,就是重复的做某件事情,循环使用环保袋子,循环听一首歌,天道循环,周而复始。总而言之,言而总之,循环就是在满足某些条件下重复的执行某一个操作。 3、循环的特点: 1、循环结构: 循环起始值,包括循环条件,循环自增量(每次增加的量) ,循环操作。 2、语法: for... 笔者最近做了很多的应聘笔试题,其有一个让我印象特备深刻,关于在一个for循环里边些函数运用到for循环里边定义的变量的问题,废话不多说,先上代码,大家可以看看这段代码最后的结果是什么:vararray=[];//定义一个数组,空的 for(vari=0;i<3;i++){ array[i]=function(){ alert(i);