直播网站建设书籍,曹县住房和城乡建设部网站,wordpress缓存首页不正常,精美免费ppt模板下载什么是闭包#xff1f; 当函数可以记住并访问所在的词法作用域时#xff0c;就产生了闭包#xff0c;即使函数是在当前词法作用域之外执行的。下面用一些代码来解释这个定义#xff1a; function foo() {var a 2;function bar() {console.log(a); // 2}bar();
}foo(); 这… 什么是闭包 当函数可以记住并访问所在的词法作用域时就产生了闭包即使函数是在当前词法作用域之外执行的。下面用一些代码来解释这个定义 function foo() {var a 2;function bar() {console.log(a); // 2}bar();
}foo(); 这是闭包吗技术上来讲也许是。但根据前面的定义确切地说并不是。最准确地来解释 bar() 对 a 的应用方法是词法作用域的查找规则即在 bar() 的函数作用域中无法找到 a,则向上一级所嵌套的 foo() 的作用域中查找而这些规则只是闭包的一部分。下面再看一段代码清晰地展示了闭包 function foo() {var a 2;function bar() {console.log(a);}return bar;
}var baz foo();baz(); // 2 这就是闭包的效果 函数 bar() 的词法作用域能够访问 foo() 的内部作用域然后将 bar() 函数本身作为一个值类型进行传递。在这段代码中我们将 bar 所引用的函数对象本身作为返回值。在 foo() 执行后其返回值赋值给变量 baz 并调用 baz()实际上只是通过不同的标识符引用调用了内部函数 bar()。在 foo() 执行后通常会期待 foo() 的整个内部作用域都被销毁。而闭包的神奇之处可以阻止作用域被销毁被回收。那么是谁再使用这个内部作用域是 bar() 本身在使用。bar() 拥有覆盖 foo() 内部作用域的闭包使得该作用域能够一直存活以供 bar() 在之后任何时间进行引用。这个引用就叫做闭包。再据两个例子 function foo() {var a 2;function baz() {console.log(a); //2}bar(baz);
}function bar(fn) {fn(); // 这就是闭包
} function wait(message) {setTimeout(function timer(){console.log(message);},1000);
}wait(Hello World); 循环和闭包 先看下面的例子 for(var i1; i5; i){setTimeout(function timer() {console.log(i);},i*1000);
} 这段代码在运行时会以每秒一次的频率输出五次6.为什么会这样呢首先解释6是怎么来的。这个循环的终止条件是 i5。条件首次成立时 i 的值是6.因此输出显示的是循环结束时 i 的最终值。延迟函数的回调会在循环结束时才执行当定时器运行时即使每个迭代中执行的是 setTimeout(..,0)所有的回调函数依然是在勋魂结束后才会执行因此每次都输出6.根据作用域的工作原理实际情况是尽管循环中的五个函数是在各个迭代中分别定义的但是它们都是被封闭在一个共享的全局作用域中因此实际上只有一个 i。再看下一个代码给上一代码加入更多的词法作用域且要加入实质内容才能起作用。 for(var i1; i5; i){(function() {var j i;setTimeout(function timer(){console.log(j);},j*1000)})();
} 现在就能正常分别输出数字1~5每秒一次每次一个。