jsjs匿名函数和闭包 一个函数

js的闭包,局部变量,函数定义问题 - ITeye问答
(function(){
var number = 10;
function getNumber() {
var num = function () {
&&& alert( number );
&&& var number = 20;&&
&&& return getNumber();
&&& function getNumber() {
num();
})();
为什么会alert出undefined 而把下面的那个var number =20去掉就可以打印出10.
求教育....望各位大牛们指点迷津问题补充Bronar 写道貌似因为JS会把var声名的变量预定义为undefined
function a(){
&&& alert(test);
&&& //删掉这句会有不同结果..
}
a();
嗯 但是我后面那个num 声明定义了,并且已经赋值为20.难道alert()比赋值操作先执行?
问题补充yarmyarch 写道这个问题跟闭包没关系,仅是简单的js变量作用域问题。
在一个{}域内声明变量时,
这个代码块(比如此处你的num方法)在初始化的过程中,会将传入参数、这个block中用到的局部变量(用var关键字指定)全部初始化,用于开辟这个block运行所需要的内存空间。(如果你用firebug进行debug,在运行到num方法第一行时,看看局部变量列表,你会找到“number”)。
此处仅仅是为了开辟代码块的运行空间,也就是新开了一块内存区域,但是在执行“var number=20”之前这块区域并没有被初始化。所以你尝试在第一行访问这个区域当然就返回undefined了。
您说的初始化的过程中,会将传入参数 小弟不太明白?我打印 arguments出来是空。你后面说的初始化,开辟内存空间
其实这样写比较好理解,他们都是一样的:(第一行我只是声明了,并没有赋值(声明+赋值=初始化)),所以没有初始化,也就没有开辟您所谓的运行空间和内存区域。
var num = function () {
&&& alert( number );
&&& number = 20;&&
&&& return getNumber();
&&& function getNumber() {
};问题补充owenzhster 写道js的作用域问题,js执行前会先进行语法解析,这个解析是按块来进行的,也就是说var num = function ()后面的东西会被一起解析,那里面有var number = 20;所以number被重新定义了,而这句之前的alert自然就没有东西了。如果去掉var number = 20;,通过作用域链会找到下一个定义,也就是var number = 10;,所以打印出10来了。
您说的解析语法时,只是重新声明了number这样一个变量?并没有把20存到内存里去 是吧?问题补充jessige_27 写道代码能写成这样 真不容易
什么意思?这只是个题目,不是我写的代码..呵呵& 你是说写的很差劲吧..
var num = function () {
&&& alert( number );
&&& var number = 20;&&
&&& return getNumber();
&&& function getNumber() {
这段代码在执行的时候其实是这样的
var num = function () {
&&&
&&& alert( number ); //这里之前会自动声明一个未初始化的变量,此时打印值,肯定是undefined
&&& number = 20;&&
&&& return getNumber();
&&& function getNumber() {
var num = function () {
alert( number );
var number = 20;
return getNumber();
function getNumber() {
js跟python的原理类似,都是优先解释顶层无缩进的变量声明,就好比在JAVA中,不管你将变量的声明定义在何处,都是会优先编译这些变量声明的
The rule that all variables declared in a function are defined throughout the function can cause surprising results. The following code illustrates this:
var scope = "global";
function f( ) {
&&& alert(scope);&&&&&&&& // Displays "undefined", not "global"
&&& var scope = "local";& // Variable initialized here, but defined everywhere
&&& alert(scope);&&&&&&&& // Displays "local"
}
f( );
You might think that the first call to alert( ) would display "global", because the var statement declaring the local variable has not yet been executed. Because of the scope rules, however, this is not what happens. The local variable is defined throughout the body of the function, which means the global variable by the same name is hidden throughout the function. Although the local variable is defined throughout, it is not actually initialized until the var statement is executed. Thus, the function f in the previous example is equivalent to the following:
function f( ) {
&&&&&&&&& // Local variable is declared at the start of the function
&&& alert(scope);&&& // It exists here, but still has "undefined" value
&&& scope = "local"; // Now we initialize it and give it a value
&&& alert(scope);&&& // And here it has a value
}
This example illustrates why it is good programming practice to place all your variable declarations together at the start of any function.
这是截取自《JavaScript权威指南第5版》里面的一段内容,LZ看下,就应该会明白了。
已解决问题
未解决问题让你一句话理解闭包(简单易懂)
&更新时间:日 09:51:45 & 投稿:jingxian
下面小编就为大家带来一篇一句话理解闭包(简单易懂)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
接触javascript很久了,每次理解闭包都似是而非,最近在找Web前端的工作,所以需要把基础夯实一下。
本文是参照了joy_lee的博客 闭包 在她这篇博客的基础上以批注的形式力争把我的理解阐述出来,如果有不当之处,欢迎批评指正。
《高级程序设计》上,这样说:当在函数内部定义了其他函数时候,就创建了闭包。闭包有权访问包含函数内部的所有变量。
(这句话怎么理解呢?照这句话理解的话,闭包就是一个嵌套函数嘛!嵌套函数对包含它的函数的变量当然可以访问,这是没有问题的。)
一般来说,内部函数是能够访问到上一级乃至全局的的变量的,那么就有人这样理解:通过闭包,可以实现外部访问函数局部内的变量。
(如果我们把作用域简单的分个级的话,假设全局作用域作为第一级,其中定义的函数体内部作用域作为第二级,在第二级作用域内嵌套定义的函数体内部作用域作为第三级,....等等,传统意义上,第一级不能访问第二级的变量(这种变量叫做局部变量),第二级不能访问第三级,...,而反过来是可以的,这就是作用域链。本级作用域内找不到再到上一级找,直至第一级全局。而闭包这种机制可以在第一级作用域中通过第三级作用域引用到第二级作用域中的变量,而方法就是在第二级作用域向第一级作用域返回拥有第三级作用域的函数引用。 这个引用才是关键,因为这个引用的存在,相关的第三作用域与第二作用域都成了这个引用运行的上下文,迫使垃圾回收机制GC不能回收这条链上所占用的资源。而如果没有这个引用,则跟一般函数一样,函数运行完资源就会被回收。而我的疑惑也在于此,闭包单指函数中的嵌套函数还是指被第一级引用了的嵌套函数?还是都是?还是说闭包并不是嵌套函数而是嵌套函数被第一级作用域引用时所形成的这种机制?)
function a(){
function b(){
alert(++i);
 var c = a();
即,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。
由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。
那么,如果a不返回函数b,情况就完全不同了。因为a执行完后,b没有被返回给a的外界,只是被a所引用,而此时a也只会被b引用,因此函数a和b互相引用但又不被外界打扰(被外界引用),函数a和b就会被GC回收。
实际上是就是闭包延长变量的生命周期。通常函数的作用域即变量会在函数执行结束后被销毁,但当函数返回一个闭包,只要闭包不被释放,整条作用域链都会占用内存。(闭包延长变量的生命周期,这是指被第一级引用的情况。但如果没有这个引用,闭包还能称其为闭包吗?)
说道作用域链:即 函数自己的作用域、上一层的函数的作用域....和全局作用域。访问一个变量时,自己的没有,就一层层往上找,直至全局,若还没有,就报错。
(很想吐槽一句,闭包的作用域链是弯的。)
PS: 有网友推荐了另一篇文章,是不是权威暂且不提,总算有一个明确的概念:
说了这么多,闭包到底是什么,下面做一下总结:
闭包是一个概念,它描述了函数执行完毕内存释放后,依然内存驻留的一个现象,只要把握这个核心概念,闭包就不难理解了。
以上这篇让你一句话理解闭包(简单易懂)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具使用JS闭包,编写一段函数_百度知道
使用JS闭包,编写一段函数
o写一个functionmakeAccount(n)程序varaccount=makeAccount(100);account(10);//给帐号存钱account(-10);//给帐号扣钱account();//显示当前账户余额o采用部分应用技术,支持多个币种'R...
o 写一个 function makeAccount(n) 程序var account = makeAccount(100); account(10); //给帐号存钱 account(-10); //给帐号扣钱 account(); //显示当前账户余额o 采用部分应用技术,支持多个币种 'RMB' 'EURO' '$'var rmbAccount = makeAccount('RMB'); var account = rmbAccount(10);
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
采纳数:105
获赞数:149
擅长:暂未定制
function&makeAccount(n){ var&type,account&=&0; if(n&in&{&EURO&:&1&,&$&:&2&,&RMB&:&3&}){
type&=&n; }else{
n&=&parseFloat(n);
if(isNaN(n)){
throw&&unknow&value&
account&=&n;
} } return&function(v){
v&=&parseFloat(v);
if(arguments.length&==&0){
console.log(account);
}else&if(isNaN(v)){
throw&&unknow&value&
account&+=&v;
为什么TYPE这个变量没有用到,我该怎么输出多个币种情况下的余额呢
为你推荐:
其他类似问题
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。闭包是函数和声明该函数的词法环境的组合。
词法作用域
考虑如下情况:
function init() {
var name = "Mozilla"; // name 是一个被 init 创建的局部变量
function displayName() { // displayName() 是内部函数,一个闭包
alert(name); // 使用了父函数中声明的变量
displayName();
init() 创建了一个局部变量 name 和一个名为 displayName() 的函数。displayName() 是定义在 init() 里的内部函数,仅在该函数体内可用。displayName() 内没有自己的局部变量,然而它可以访问到外部函数的变量,所以 displayName() 可以使用父函数 init() 中声明的变量 name 。但是,如果有同名变量 name 在 displayName() 中被定义,则会使用 displayName() 中定义的 name 。
代码可以发现 displayName() 内的 alert() 语句成功的显示了在其父函数中声明的 name 变量的值。这个词法作用域的例子介绍了引擎是如何解析函数嵌套中的变量的。词法作用域中使用的域,是变量在代码中声明的位置所决定的。嵌套的函数可以访问在其外部声明的变量。
现在来考虑如下例子 :
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
return displayN
var myFunc = makeFunc();
运行这段代码和之前的 init() 示例的效果完全一样。其中的不同 — 也是有意思的地方 — 在于内部函数 displayName() 在执行前,被外部函数返回。
第一眼看上去,也许不能直观的看出这段代码能够正常运行。在一些编程语言中,函数中的局部变量仅在函数的执行期间可用。一旦 makeFunc() 执行完毕,我们会认为 name 变量将不能被访问。然而,因为代码运行得没问题,所以很显然在 JavaScript 中并不是这样的。
这个谜题的答案是,JavaScript中的函数会形成闭包。 闭包是由函数以及创建该函数的词法环境组合而成。这个环境包含了这个闭包创建时所能访问的所有局部变量。在我们的例子中,myFunc 是执行 makeFunc 时创建的 displayName 函数实例的引用,而 displayName 实例仍可访问其词法作用域中的变量,即可以访问到 name 。由此,当 myFunc 被调用时,name 仍可被访问,其值 Mozilla 就被传递到alert中。
下面是一个更有意思的示例 — makeAdder 函数:
function makeAdder(x) {
return function(y) {
return x +
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2));
console.log(add10(2)); // 12
在这个示例中,我们定义了 makeAdder(x) 函数,它接受一个参数 x ,并返回一个新的函数。返回的函数接受一个参数 y,并返回x+y的值。
从本质上讲,makeAdder 是一个函数工厂 — 他创建了将指定的值和它的参数相加求和的函数。在上面的示例中,我们使用函数工厂创建了两个新函数 — 一个将其参数和 5 求和,另一个和 10 求和。
add5 和 add10 都是闭包。它们共享相同的函数定义,但是保存了不同的词法环境。在 add5 的环境中,x 为 5。而在 add10 中,x 则为 10。
实用的闭包
闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来。这显然类似于面向对象编程。在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。
因此,通常你使用只有一个方法的对象的地方,都可以使用闭包。
在 Web 中,你想要这样做的情况特别常见。大部分我们所写的 JavaScript 代码都是基于事件的 — 定义某种行为,然后将其添加到用户触发的事件之上(比如点击或者按键)。我们的代码通常作为回调:为响应事件而执行的函数。
假如,我们想在页面上添加一些可以调整字号的按钮。一种方法是以像素为单位指定 body 元素的 font-size,然后通过相对的 em 单位设置页面中其它元素(例如header)的字号:
font-family: Helvetica, Arial, sans-
font-size: 12
font-size: 1.5
font-size: 1.2
我们的文本尺寸调整按钮可以修改 body 元素的 font-size 属性,由于我们使用相对单位,页面中的其它元素也会相应地调整。
以下是 JavaScript:
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
size12,size14 和 size16 三个函数将分别把 body 文本调整为 12,14,16 像素。我们可以将它们分别添加到按钮的点击事件上。如下所示:
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
&a href="#" id="size-12"&12&/a&
&a href="#" id="size-14"&14&/a&
&a href="#" id="size-16"&16&/a&
用闭包模拟私有方法
编程语言中,比如 Java,是支持将方法声明为私有的,即它们只能被同一个类中的其它方法所调用。
而 JavaScript 没有这种原生支持,但我们可以使用闭包来模拟私有方法。私有方法不仅仅有利于限制对代码的访问:还提供了管理全局命名空间的强大能力,避免非核心的方法弄乱了代码的公共接口部分。
下面的示例展现了如何使用闭包来定义公共函数,并令其可以访问私有函数和变量。这个方式也称为
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter +=
increment: function() {
changeBy(1);
decrement: function() {
changeBy(-1);
value: function() {
return privateC
console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */
在之前的示例中,每个闭包都有它自己的词法环境;而这次我们只创建了一个词法环境,为三个函数所共享:Counter.increment,Counter.decrement 和 Counter.value。
该共享环境创建于一个立即执行的匿名函数体内。这个环境中包含两个私有项:名为 privateCounter 的变量和名为 changeBy 的函数。这两项都无法在这个匿名函数外部直接访问。必须通过匿名函数返回的三个公共函数访问。
这三个公共函数是共享同一个环境的闭包。多亏 JavaScript 的词法作用域,它们都可以访问 privateCounter 变量和 changeBy 函数。
你应该注意到我们定义了一个匿名函数,用于创建一个计数器。我们立即执行了这个匿名函数,并将他的值赋给了变量counter。我们可以把这个函数储存在另外一个变量makeCounter中,并用他来创建多个计数器。
var makeCounter = function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter +=
increment: function() {
changeBy(1);
decrement: function() {
changeBy(-1);
value: function() {
return privateC
var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */
请注意两个计数器 counter1 和 counter2 是如何维护它们各自的独立性的。每个闭包都是引用自己词法作用域内的变量 privateCounter 。
每次调用其中一个计数器时,通过改变这个变量的值,会改变这个闭包的词法环境。然而在一个闭包内对变量的修改,不会影响到另外一个闭包中的变量。
以这种方式使用闭包,提供了许多与面向对象编程相关的好处 —— 特别是数据隐藏和封装。
在循环中创建闭包:一个常见错误
在 ECMAScript 2015 引入
之前,在循环中有一个常见的闭包创建问题。参考下面的示例:
&p id="help"&Helpful notes will appear here&/p&
&p&E-mail: &input type="text" id="email" name="email"&&/p&
&p&Name: &input type="text" id="name" name="name"&&/p&
&p&Age: &input type="text" id="age" name="age"&&/p&
function showHelp(help) {
document.getElementById('help').innerHTML =
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
for (var i = 0; i & helpText. i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
setupHelp();
数组 helpText 中定义了三个有用的提示信息,每一个都关联于对应的文档中的input 的 ID。通过循环这三项定义,依次为相应input添加了一个 onfocus
事件处理函数,以便显示帮助信息。
运行这段代码后,您会发现它没有达到想要的效果。无论焦点在哪个input上,显示的都是关于年龄的信息。
原因是赋值给 onfocus 的是闭包。这些闭包是由他们的函数定义和在 setupHelp 作用域中捕获的环境所组成的。这三个闭包在循环中被创建,但他们共享了同一个词法作用域,在这个作用域中存在一个变量item。当onfocus的回调执行时,item.help的值被决定。由于循环在事件触发之前早已执行完毕,变量对象item(被三个闭包所共享)已经指向了helpText的最后一项。
解决这个问题的一种方案是使用更多的闭包:特别是使用前面所述的函数工厂:
function showHelp(help) {
document.getElementById('help').innerHTML =
function makeHelpCallback(help) {
return function() {
showHelp(help);
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
for (var i = 0; i & helpText. i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
setupHelp();
这段代码可以如我们所期望的那样工作。所有的回调不再共享同一个环境, makeHelpCallback 函数为每一个回调创建一个新的词法环境。在这些环境中,help 指向 helpText 数组中对应的字符串。
另一种方法使用了匿名闭包:
function showHelp(help) {
document.getElementById('help').innerHTML =
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
for (var i = 0; i & helpText. i++) {
(function() {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
})(); // 马上把当前循环项的item与事件回调相关联起来
setupHelp();
避免使用过多的闭包,可以用let关键词:
function showHelp(help) {
document.getElementById('help').innerHTML =
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
for (var i = 0; i & helpText. i++) {
let item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
setupHelp();
这个例子使用let而不是var,因此每个闭包都绑定了块作用域的变量,这意味着不再需要额外的闭包。
如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。
例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。原因是这将导致每次构造器被调用时,方法都会被重新赋值一次(也就是,每个对象的创建)。
考虑以下示例:
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
this.getName = function() {
return this.
this.getMessage = function() {
return this.
上面的代码并未利用到闭包的好处,我们可以修改成如下:
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
MyObject.prototype = {
getName: function() {
return this.
getMessage: function() {
return this.
但我们不建议重新定义原型。可改成如下例子:
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
MyObject.prototype.getName = function() {
return this.
MyObject.prototype.getMessage = function() {
return this.
在前面的两个示例中,继承的原型可以为所有对象共享,不必在每一次创建对象时定义方法。参见
一章可以了解更为详细的信息。
文档标签和贡献者
此页面的贡献者:
最后编辑者:
Jul 16, :12 PM
电子邮件地址
我接受 Mozilla 按照所述的方式处理我的信息。
谢谢!请检查您的收件箱以确认您的订阅。
如果您以前未确认过订阅 Mozilla 相关的新闻简报,您可能必须这样做。请检查您的收件箱或垃圾邮件箱并找到我们发给您的电子邮件。
隐藏新闻报注册javascript –
从基本函数到闭包详解
1)函数定义、
函数:一种代码的分组形式,可以通过这种形式赋予某组代码一个名字,以便日后重用时调用。
2)、函数组成、
a. function 子句(数据类型)。
b. 函数名字,也可以没有函数,称为匿名函数。
c. 函数所要执行的代码块,称为函数体。
d. 函数参数,0到多个,每个浏览器都不一样,谷歌最大可以支持10多万个。调用的时候可以不传和多传,不传参数为undefined,多传忽略.每个函数都有一个内建的arguments数组,它能返回函数接受到的所有参数。
e. return 子句,函数通常都有返回值,没有显示返回就返回undefined。
3)、申明函数
首先函数在JavaScript中其实是一种数据类型,对函数变量调用typeof,会返回function。
申明有俩中方式:
a. function foo(){return 1;}
b. var foo = function(){return 1;}
第二种申明方式通常被称为函数标识记法。
函数有2个特性
a. 他们所包含的是代码。
b. 他们是可以执行的。
由于函数也是赋值给变量的一种数据,我们可以使用delete删除函数 delete foo。
调用函数只要在方法名后面加上(),就可以了。(匿名函数定义后自行执行一次。需要在后面加上()才会执行。)
4)、函数几个特别形式
a.匿名函数
匿名函数顾名思义,没有给函数定义名字。
其实在javascript中一个数据类型的对象既没有赋值给变量,也没有被赋予任何名字,就是匿名数据,就好比我们下面代码
这些代码我们都可以称为一段匿名数据。
匿名函数主要有俩个用处,
第一个是匿名回调函数,将匿名函数作为参数传递给其他函数。(在jquery中经常出现参数就一段代码.)
主要优点:
1,有可以在不命名变量的情况下传递函数,意味这可以节省全局变量。
2,我们可以将一个函数调用操作委托给另一个函数。
3,有助于提升性能(私有的区域来存储数据,执行后即销毁,避免常驻内存。)。
第二个是自调函数,函数在定义后自行执行。执行某些一次性或初始化任务。
主要优点:不会产生任何全局变量。
主要缺点:无法重复执行(除非放在循环或者其他函数内)
b.内部函数
内部函数就是在申明全局函数的同时,在其内部也申明一个函数,由于作用域的关系,内部函数在父函数外部是不可见的,我们也可以称这个内部函数为私有函数。
私有函数的优点:
1,有助于我们确保全局名字空间的纯净性。
2,私有性-这使我们可以选择只将一些必要的函数暴露给调用者,隐藏自己私有行为,起到了封装的效果。
c.返回函数的函数
函数总会有一个返回值,若不显示返回就返回一个undefined,之前提到函数其实也是数据,所以函数的返回值也可以是一个函数。
下面的例子很有意思.
function foo(){
alert('A');
return function(){
alert('B');
var f = foo();
执行var f = foo();时,只会弹出’A’,执行f()才会弹出‘B’,要想一句代码连续弹出A和B,可以这么写 var f=foo()();同时调用俩次。
d.重写自己的函数
由于一个函数可以返回另外一个,因此我们可以使用新的函数来覆盖旧的。
前面一个例子就可以这样写:
function foo(){
alert('A');
return function(){
alert('B');
foo = foo();
这句话也就是先弹出A,然后直接使用返回函数覆盖foo。
上面是外部重写自己的函数,当然也可以内部覆盖,如下:
function foo(){
alert('A');
foo = function(){
alert('B');
foo 在外部定义是全局变量,在函数内部可以直接使用。
说闭包之前先说下javaScript的作用域和词法作用域。
a)、作用域:
javaScript不存在大括号级的作用域,但是有函数作用域,也就是说,在函数内部定义的变量,在函数外面是不可见的。但是在函数外面定义的变量,在函数内部是可以见的。
定义在函数外面的变量,相对函数来说是”父级“作用域,函数可以操作”父级“作用域变量,反过来不行。
b)、词法作用域
在javaScript中,每个函数都有一个自己的词法作用域。也就是说,每个函数在被定义时(而非执行时)都会有一个属于自己的环境(即作用域)。一个函数只能访问自身和全局作用域中的内容。
c)、利用闭包突破作用域链
如何突破作用域链,我们只需要将他们升级为全局变量(不使用var 语句)或通过函数传递(或返回)给全局变量即可。
函数所绑定的作用域本身,而不是该作用域中的变量或变量当前所返回的值。(说明下,只要闭包函数执行完成,如果多个闭包外的对象指向闭包内的同一个变量,那么闭包外的对象值都是一样的因为都是同一个引用)
var getValue,setV
(function(){
var secret = 0;
getValue = function(){
setValue = function(v) {
闭包确实有很多好处,但是也有缺点,容易造成内存泄露,开销大的问题。
JS闭包函数和回调函数
一、闭包闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。闭包就是能够读取其他函数内部变量的函数。可以把闭包简单理解成”定义在一个函数内部的函数”...
function 函数传参,不定参,return返回值
function fn(形参){
console.log(形参);
不定参: arguments
arguments: 不定参
函数的所有...
js function中返回function
window.onload = function(){
function a(){
for(var i =1;i
jQuery闭包函数
其实javascript里的闭包概念很简单,就是函数用到外部变量,不需要传参就可以获取。
举个例子:
var sMessage = &Hello world&;
闭包详解一
在正式学习闭包之前,请各位同学一定要确保自己对词法作用域已经非常的熟悉了,如果对词法作用域还不够熟悉的话,可以先看:深入理解闭包之前置知识—-作用域与词法作用域前言现在去面试前端开发的岗位,如果你的面...
JavaScript函数-内部函数
1、代码实现function outer(param) {
var inner = function(theinput) {
return theinput * 2;
return ...
js闭包函数结果值获取
js闭包函数这样写不能获取到返回值,原因:AJAX是一个异步的,想要操作request获取到的结果需在success中写。
var welcomeUrl__ = (function(){
应用闭包:将函数作为返回值
我们也可以将 Adder 返回的函数存到变量中
package main
import &fmt&
func main() {
// make an Add2 fun...
js 函数作为返回值输出
js 函数作为返回值输出
jQuery 闭包
闭包的特点:
1.函数里面的函数
2.能够让里层的函数可以使用外层函数的局部变量和形参;
3.被里层函数所引用到的变量...
没有更多推荐了,}

我要回帖

更多关于 js闭包的理解 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信