`

javascript的闭包和变量

阅读更多

for(var i=0;i<10;i++) {
setTimeout(function() {
console.log(i);
}, 300);
}
运 行它可以发现,连续输出了10个10.为什么呢?因为 “i” 这个变量在内存里只保存了一份。当调用settimeout方法时,往js事件线程的等待队列排入了十个执行函数,一直到每个300ms结束,这十个执行 函数才被调用,此时内存里的 “i” 这个变量经过十次循环最终值已变成了10 。所以就输出了10个10了。那怎么样输出0-9呢?我们可以用闭包把代码稍微改造下:
for(var i=0;i<10;i++) {
setTimeout((function(j) {
return function() {
console.log(j);
}
})(i), 300);
}
此 时就会输出我们想要的结果了,为什么?因为我们在给settimeout传参前,先使用闭包重新生成了一个执行函数,并且把当时循环里的"i"的值作为参 数传入到闭包函数中,结果函数无论什么时候执行,都打出的是当时被传入的那个值。由此说明:在给函数传参时,如果传入的参数是位于栈内存上的时候,会将栈 内存值复制一份传入到函数中。
那如果所传参数是个对象,也就是存在于堆内存上时会怎么办,我们接着做一个实验,这次的循环对象是一个对象字面量:
var obj = {j:0};
for(var i=0;i<10;i++) {
obj.j++;
setTimeout((function(o) {
return function() {
console.log(o.j);
}
})(obj), 300);
}
输出了什么?还是10个10!为什么?虽然还是使用闭包将当前循环的对象状态作为参数传入执行函数中,但传入的只是栈内存上的变量指针,位于堆内存上的内存仍然只有一份,所以这10个等待任务最终开始执行时,输出的都是同一份内存值。
由此我们得出几个最终结论:
1、对于基础数据类型,函数传参的时候会将变量值复制一份传入到函数中。
2、对于对象数据类型,函数传参时是将变量的指针复制一份,真正的变量值只有一份。
由于变量指针和基础类型变量都位于栈内存上,所以传参就是将栈内存复制一遍,堆内存不变。

4
4
分享到:
评论
5 楼 w497480098h 2014-03-27  
用闭包来解释引用和值传递,这例子有点绕啊!
4 楼 RebornVip 2013-07-25  
明白了   
3 楼 自己人 2013-07-23  
不错  通俗易懂啊
2 楼 lvwenwen 2013-06-24  
好深奥,看不懂
1 楼 yq5858588 2013-06-24  
好深奥,看不懂

相关推荐

    JavaScript闭包研究及典型应用.pdf

    本文将介绍 JavaScript 闭包的定义、使用场景和典型应用。 闭包函数的定义和使用场景 在 JavaScript 语言中,闭包函数是指在函数顶层可定义函数,即函数可以嵌套的。简单地说,闭包也就是内层函数可以引用存在于...

    基于JavaScript闭包的Web图片浏览控件的实现.pdf

    JavaScript闭包是一个拥有许多变量和绑定这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。 JavaScript闭包可以让开发者在函数内部访问外部变量,从而实现函数的重用。 2. JavaScript...

    JavaScript闭包函数访问外部变量的方法

    总结来说,JavaScript闭包函数访问外部变量的主要方法包括直接引用和通过匿名函数捕获变量。直接引用时需要注意闭包中变量的生命周期问题,而通过匿名函数捕获变量可以有效解决这一问题,使得每个闭包都能拥有外部...

    javascript闭包的理解

    标题《JavaScript闭包的理解》涉及的知识点主要围绕JavaScript编程中的一个重要概念——闭包。闭包是一个高级且复杂的话题,它是JavaScript语言的核心特性之一,同时也是一大难点。要想熟练运用JavaScript,掌握闭包...

    Javascript 闭包完整解释

    ### JavaScript闭包完整解释 #### 一、闭包的基本概念 **闭包**是一个非常重要的JavaScript概念,它指的是一个函数能够记住并访问其外部作用域中的变量的能力,即使该函数在其外部作用域之外被调用也是如此。具体...

    JavaScript知识点总结(十六)之Javascript闭包(Closure)代码详解

    在JavaScript中,变量的作用域分为两种:全局变量和局部变量。全局变量是在函数外部定义的变量,可以在JavaScript程序的任何地方被访问。局部变量则是在函数内部定义的变量,只能在该函数内部访问。当在函数内部访问...

    【JavaScript源代码】详解JavaScript闭包问题.docx

    详解JavaScript闭包问题  闭包是纯函数式编程语言的传统特性之一。通过将闭包视为核心语言构件的组成部分,JavaScript语言展示了其与函数式编程语言的紧密联系。由于能够简化复杂的操作,闭包在主流JavaScript库...

    基于javascript 闭包基础分享

    1. 模拟私有变量和方法:在面向对象编程中,有时需要封装某些变量和方法,使其对外不可见。在JavaScript中,利用闭包可以实现私有成员,外部无法直接访问,但可以通过闭包提供的接口进行间接访问。 2. 提升代码的...

    Javascript闭包实例详解

    1. **模块化**:通过闭包创建私有变量和函数,实现模块间的隔离。 2. **数据持久化**:在异步操作中,闭包可以保持状态,例如定时器回调中的变量。 3. **内存管理**:通过闭包,可以避免过早释放某些需要长期使用的...

    javascript 闭包实例下载

    JavaScript 闭包是一种高级编程概念,它在JavaScript中扮演着至关重要的角色,特别是在函数式编程和模块化设计中。闭包本质上是函数和其能够访问...通过学习这些实例,你将能够更好地掌握JavaScript闭包这一核心概念。

    javaScript闭包技术资料

    ### JavaScript闭包技术详解 #### 一、闭包的基本概念 **闭包**是JavaScript中一个重要的概念,它涉及到函数的执行环境、作用域链等关键要素。简单来说,闭包是一个函数及其相关的引用环境的组合。具体而言,当一...

    javaScript闭包的理解

    ### JavaScript闭包的理解 #### 一、闭包的定义与特点 闭包是JavaScript中一个非常重要的概念,它指的是一个函数能够访问并操作其外部作用域中的变量的能力。这一特性使得JavaScript具有了一些其他语言不具备的...

    js代码-闭包隐藏变量

    JavaScript中的闭包是一种强大的特性,它允许函数访问并操作其外部作用域的变量,即使在函数执行完毕后这些变量仍然存在。这个特性使得闭包在处理数据隐私、模块化和记忆化等方面非常有用。让我们深入探讨一下闭包的...

    javascript闭包高级教程

    ### JavaScript闭包高级教程 #### 简介 在JavaScript编程中,“闭包”是一个非常重要的概念,尤其对于希望深入理解和高效使用JavaScript的开发者来说。简单地说,闭包是一种能够记住并访问其创建时周围环境的函数...

    揭开Javascript闭包的真实面目

    - **活动对象(Call Object)**:在执行环境中,活动对象保存了函数的参数、局部变量和函数声明。 - **作用域(Scope)**:指的是变量的可见范围,决定了变量在哪些地方可以被访问。 - **作用域链(Scope Chain)**...

    JavaScript闭包(closure).pdf

    即使外部函数执行完毕,内部函数依然可以访问外部函数的变量和参数,即使外部函数的变量在其他地方已被销毁。 闭包的用途: 1. 数据隐藏与封装:闭包可以用来创建私有变量,防止变量被全局作用域污染,避免与其他...

    JavaScript闭包详解1

    JavaScript中的闭包是一种高级特性,它允许一个函数访问并操作其外部作用域的变量,即使在外部函数已经执行完毕后。这种机制的核心在于,当内部函数引用了外部函数的变量时,JavaScript会保持对外部作用域的引用,...

    javascript闭包的高级使用方法实例

    JavaScript 闭包是一种强大的特性,它允许函数访问和操作其外部作用域中的变量,即使在外部函数执行完毕后,这些变量仍然保持活动状态。在高级使用中,闭包可以用于实现模块化、数据封装、方法扩展和重载、以及创建...

Global site tag (gtag.js) - Google Analytics