js的闭包

Wikipedia对闭包的定义是这样的:
In computer science, a closure is a function
together with a referencing environment for the nonlocal names (free variables)
of that function.

从技术上来讲,在JS中,每个function都是闭包,因为它总是能访问在它外部定义的数据。

var a=[];
function test()
{
for(var i=0;i<6;i++)
{
a[i]=i;
}
}
test();
for(var j in a)
{
document.write(a[j]+‘</br>‘);
}

这个如果按照定义也算是闭包了,但是我们普通也可以访问a.

由于普通函数外部定义的变量都可以访问,因此一般只有嵌套的函数我们才会重点研究,大家常说的也是嵌套的是闭包。

在我理解看来嵌套函数的闭包有两个作用:

① 保证对外函数内部的变量访问,保证变量一直存在在内存里,这样还能保证数据的安全性。

 function a(){      var i=0;      function b(){     i++;//可以对a内部的变量修改,同时还可以通过return b来返回i,保证了i长存内存内,还能进行修改,还能访问到i        alert(i);      }      return b;    }    var c = a();    c();

② 解决块级域带来的函数执行时外部变量的值是有运行时决定,而不是定义的时候决定的,例如如下例子:

var tasks = [];
for (var i = 0; i < 5; i++) {
tasks[tasks.length] = function () {
document.write(‘Current cursor is at ‘ + i + ‘</br>‘);
};
}

var len = tasks.length;
while (len--) {
tasks[len]();
}

var tasks = [];
for (var i = 0; i < 5; i++) {
tasks[tasks.length] = (function(i){
return function () {
document.write(‘Current cursor is at ‘ + i + ‘</br>‘);
}
})(i);
}

var len = tasks.length;
while (len--) {
tasks[len]();
}

结果打印

Current cursor is at 5
Current cursor is at 5
Current cursor is at 5
Current cursor is at 5
Current cursor is at 5
Current cursor is at 4
Current cursor is at 3
Current cursor is at 2
Current cursor is at 1
Current cursor is at 0

我们看到了,其实第一个函数,运行后和我们预期是不一样的,这是Lift效应,因此加一个闭包,将i外部变量作为参数传进来,打破了这种问题。

这是目前我遇到的两种作用

时间: 2024-12-14 18:16:29

js的闭包的相关文章

JS之闭包

闭包是很多语言都具备的特性,在js中,闭包主要涉及到js的几个其他的特性: 1)作用域链 2)垃圾(内存)回收机制 3)函数嵌套...等等. 首先理解一下作用域链的含义,简单来说,作用域链就是函数在定义的时候创建的,用于寻找使用到的变量的值的一个索引. 而他内部的规则是,把函数自身的本地变量放在最前面,把自身的父级函数中的变量放在其次,把再高一级函数中的变量放在更后面,以此类推直至全局对象为止. 当函数中需要查询一个变量的值的时候,js解释器会去作用域链去查找,从最前面的本地变量中先找,如果没有

关于js中闭包的理解

1.以前很不理解js中闭包的概念及使用,下面来看一下 function foo() { var a = 123; var b = 456; return function () { return a; } } var fn = foo(); 上面的代码只能访问 a和b,但是不能修改,这是js中闭包的技术之一 function foo() { var a = 123; var b = 456; return { get_a: function () { return a; }, set_a: fu

JS基础——闭包

有关JS中闭包的理解和使用. 一.简介 子函数可以使用父函数中的局部变量,这种行为就叫做闭包.通常指,有权访问另一个函数作用域中的变量的函数.创建时,通常在一个函数中创建另一个函数,通过另一个函数访问这个函数的局部变量. function box() { var user = 'Lee'; return function () { //通过匿名函数返回 box()局部变量 return user; }; } alert(box()()); 这里通过一个匿名函数来访问父函数中的user变量,并且返

js:深入闭包(作用域)

/** * 闭包的作用域 */ fn1(); //fn1 能够执行,不会报错,对于通过function func_name()这种写法来定义的函数,永远都会被最先初始化. function fn1(){ console.log("fn1"); } fn2(); //报错:fn2 is not a function /** *使用如下方式定义函数,不会被先执行,如果在定义之前调用,报错. *这种函数的定义方式是先在内存中创建一块区域,之后通过一个fn2的变量指向这块区域, *这块区域的函

JS高级——闭包

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <script type="text/javascrip

js:深入闭包(作用域:下)

函数功能:该函数将一个字符串转为字形下标的数组.此函数可用来确定一种字体里是否存在某个字形 控制台下代码: #include "stdafx.h" #include <windows.h> #include"stdio.h" void main() { char ch[] = {'0'}; WORD chnl[20] = {0}; HDC hdc; hdc = GetWindowDC(0); int n = GetGlyphIndicesA(hdc,ch

[Js]JavaScript闭包和范围的快速测试

1. if (!("a" in window)) { var a = 1; } alert(a); [分析]代码含义:如果window不包含属性a,就声明一个变量a并赋值为1 ①Js引擎会先扫描所有的变量声明 ②所有的全局变量都是window的属性 ③变量声明和赋值一起用时,Js引擎会自动将它分成两部分:变量声明提前,变量赋值没有(不将赋值提前是因为他有可能影响代码执行出不可预期的结果) 所以代码执行顺序等价于 var a; if(!("a" in window))

js的闭包概念

一.变量的作用域要懂得闭包,起首必须懂得Javascript特别的变量作用域.变量的作用域无非就是两种:全局变量和局部变量.Javascript说话的特别之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999另一方面,在函数外部天然无法读取函数内的局部变量.Js代码 function f1(){ var n=999; } alert(n); // error这里有一个处所须要重视,函数内部声明变量

对js中闭包,作用域,原型的理解

前几天,和朋友聊天,聊到一些js的基础的时候,有一种‘好像知道,好像又不不知道怎么讲的感觉’...于是捡起书,自己理一理,欢迎拍砖. 闭包 理解闭包首先要理解,js垃圾回收机制,也就是当一个函数被执行完后,其作用域会被收回,如果形成了闭包,执行完后其作用域就不会被收回. 如果某个函数被他的父函数之外的一个变量引用,就会形成闭包 闭包的作用,就是保存自己私有的变量,通过提供的接口(方法)给外部使用,但外部不能直接访问该变量. 例子(使用闭包): var test=(function(){ var

从面试题谈谈js的闭包,原型

最近群里有小伙伴分享了两道面试题,这里我谈谈自己的理解,废话不多说,上第一题: var n = 10; var obj = { n:20, fn:(function(){ this.n += 2; n *= 3; return function(){ this.n *= 2; n += 1; console.log(n) } })(n) } var fn = obj.fn; fn(); obj.fn() console.log(n,obj.n) 这个题目中,定义的obj对象的fn属性是个自执行的