Javascript闭包用法实例分析

本文实例分析了Javascript闭包的概念及用法。分享给大家供大家参考。具体如下:

提到闭包,想必大家都早有耳闻,下面说下我的简单理解。
说实话平时工作中实际手动写闭包的场景并不多,但是项目中用到的第三方框架和组件或多或少用到了闭包。
所以,了解闭包是非常必要的。呵呵...

一、什么是闭包

简而言之,就是能够读取其他函数内部变量的函数。
由于JS变量作用域的特性,外部不能访问内部变量,内部可以外部变量。

二、使用场景

1. 实现私有成员。
2. 保护命名空间,避免污染全局变量。
3. 缓存变量。

先看一个封装的例子:

代码如下:

var person = function () {
    // 变量作用域为函数内部,外部无法访问
    var name = "default";

return {
        getName: function () {
            return name;
        },
        setName: function (newName) {
            name = newName;
        }
    }
}();

console.log(person.name); // 直接访问,结果为:undefined
console.log(person.getName()); // 结果为:default
console.log(person.setName("langjt"));
console.log(person.getName()); // 结果为:langjt

再看循环中常用闭包解决引用外部变量问题:

代码如下:

var aLi = document.getElementsByTagName('li');
for (var i=0, len=aLi.length; i<len; i++) {
   aLi[i].onclick = function() {
     alert(i); // 无论点击哪个<li>元素,弹出的值都为len,表明这里的i和在for之后打印i的值是一样的。
   };
}

使用闭包后:

代码如下:

var aLi = document.getElementsByTagName('li');
for (var i=0, len=aLi.length; i<len; i++) {
  aLi[i].onclick = (function(i) {
    return function() {
      alert(i); // 此时点击<li>元素,就会弹出对应的下标了。
    }
  })(i);
}

三、注意事项

1. 内存泄漏

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题。
比如:

代码如下:

function foo() {
   var oDiv = document.getElementById(‘J_DIV');
   var id = oDiv.id;
   oDiv.onclick = function() {
     // alert(oDiv.id); 这里存在循环引用,IE低版本页面关闭后oDiv仍在内存中。所以尽可能缓存基本类型而不是对象。
     alert(id);
   };
   oDiv = null;
}

2. 变量命名

如果内部函数的变量和外部函数的变量名相同时,那么内部函数再也无法指向外部函数那个同名的变量。
比如:

代码如下:

function foo(num) {
  return function(num) {
    console.log(num);
  }
}
var f = new foo(9);
f(); // undefined

其实上面的用法,专业术语叫函数柯里化(Currying),就是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。本质上也利用了闭包可以缓存的特性,比如:

代码如下:

var adder = function(num) {
    return function(y) {
        return num+y;
    };
};

var inc = adder(1);
var dec = adder(-1);
//inc, dec现在是两个新的函数,作用是将传入的参数值 (+/‐)1
alert(inc(99));//100
alert(dec(101));//100
alert(adder(100)(2));//102
alert(adder(2)(100));//102

再比如阿里玉伯的seaJS源码中:

代码如下:

/**
 * util-lang.js - The minimal language enhancement
 */
function isType(type) {
  return function(obj) {
    return {}.toString.call(obj) == "[object " + type + "]"
  }
}

var isObject = isType("Object");
var isString = isType("String");

希望本文所述对大家的javascript程序设计有所帮助。

(0)

相关推荐

  • 深入理解javascript作用域和闭包

    作用域 作用域是一个变量和函数的作用范围,javascript中函数内声明的所有变量在函数体内始终是可见的,在javascript中有全局作用域和局部作用域,但是没有块级作用域,局部变量的优先级高于全局变量,通过几个示例来了解下javascript中作用域的那些"潜规则"(这些也是在前端面试中经常问到的问题). 1. 变量声明提前 示例1: var scope="global"; function scopeTest(){ console.log(scope); v

  • Javascript的setTimeout()使用闭包特性时需要注意的问题

    setTimeout经常被用于延迟执行某个函数,用法为: 复制代码 代码如下: setTimeout(function(){ - }, timeout); 有时为了进行异步处理,而使用setTimeout(function-,0):比如: 复制代码 代码如下: function f(){ - // get ready setTimeout(function(){ -. // do something }, 0);   return -; } 在setTimeout设定的函数处理器之前,函数f返回

  • javascript闭包入门示例

    1. 复制代码 代码如下: functionsay667(){varnum=666;varsayAlert=function(){alert(num);}num++;returnsayAlert;} varsayAlert=say667();sayAlert(); 2. 复制代码 代码如下: functionsetUpSomeGlobals(){varnum=666;gAlertNumber=function(){alert(num);}gIncreaseNumber=function(){nu

  • 详谈JavaScript 匿名函数及闭包

    1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没有函数名的函数. 1.1 函数的定义,首先简单介绍一下函数的定义,大致可分为三种方式 第一种:这也是最常规的一种 复制代码 代码如下: function double(x){     return 2 * x;   } 第二种:这种方法使用了Function构造函数,把参数列表和函数体都作为字符串,很不方便,不建议使用. 复制代码 代码如下: var double = new Functio

  • JavaScript中的闭包(Closure)详细介绍

    闭包是JavaScript中一个重要的特性,其最大的作用在于保存函数运行过程中的信息.在JavaScript中,闭包的诸多特性源自函数调用过程中的作用域链上. 函数调用对象与变量的作用域链 对于JavaScript中的每一次函数调用,JavaScript都会创建一个局部对象以储存在该函数中定义的局部变量:如果在该函数内部还有一个嵌套定义的函数(nested function),那么JavaScript会在已经定义的局部对象之上再定义一个嵌套局部对象.对于一个函数,其内部有多少层的嵌套函数定义,也

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

    闭包是指有权访问另一个函数作用域中的变量的函数,但作用域的配置机制有一个需要注意的地方,即闭包只能取得包含函数中任何变量的最后一个值. 如以下案例: function create(){     var arr = new Array();        for (var i=0; i<10; i++){         arr[i] = function(){             return i;         };      }       return arr; }   var c

  • Javascript的闭包详解

    前言:还是一篇入门文章.Javascript中有几个非常重要的语言特性--对象.原型继承.闭包.其中闭包 对于那些使用传统静态语言C/C++的程序员来说是一个新的语言特性.本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAScript语言规范来使读者可以更深入的理解闭包. 注:本文是入门文章,例子素材整理于网络,如果你是高手,欢迎针对文章提出技术性建议和意见.本文讨论的是Javascript,不想做语言对比,如果您对Javascript天生不适,请自行绕道. 什么是闭

  • 5个可以帮你理解JavaScript核心闭包和作用域的小例子

    这里有5个小脚本,有助于你真正理解JavaScript核心–闭包和作用域.没有在控制台运行之前,尝试回答每个案例中会弹出什么内容,然后你可以创建一个测试文件去核对你的答案.你准备好了吗? 1. 复制代码 代码如下: if (!("a" in window)) {      var a = 1;  }  alert(a); 2. 复制代码 代码如下: var a = 1,      b = function a(x) {          x && a(--x);    

  • javascript中的return和闭包函数浅析

    高手绕道!这跟闭包本身没什么大的关系,也不知道怎么取标题,随便凑了个数,望见谅! 今天一个刚学js的朋友给了我一段代码问为什么方法不执行,代码如下: 复制代码 代码如下: function makefunc(x) { return function (){  return x; }}alert(makefunc(0)); 其实不是不执行,只是朋友的意思这里alert出来的应该是"0",而不是function (){return x;}.不是脚本写错了,只是没搞懂return,从当前函数

  • Javascript闭包用法实例分析

    本文实例分析了Javascript闭包的概念及用法.分享给大家供大家参考.具体如下: 提到闭包,想必大家都早有耳闻,下面说下我的简单理解. 说实话平时工作中实际手动写闭包的场景并不多,但是项目中用到的第三方框架和组件或多或少用到了闭包. 所以,了解闭包是非常必要的.呵呵... 一.什么是闭包 简而言之,就是能够读取其他函数内部变量的函数. 由于JS变量作用域的特性,外部不能访问内部变量,内部可以外部变量. 二.使用场景 1. 实现私有成员. 2. 保护命名空间,避免污染全局变量. 3. 缓存变量

  • JS闭包用法实例分析

    本文实例讲述了JS闭包用法.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script type="text/javascript"> // 第一,函数作为返回值 function fn(){ var m

  • Python lambda函数基本用法实例分析

    本文实例讲述了Python lambda函数基本用法.分享给大家供大家参考,具体如下: 这里我们简单学习一下python lambda函数. 首先,看一下python lambda函数的语法,如下: f=lambda [parameter1,parameter2,--]:expression lambda语句中,冒号前是参数,可以有0个或多个,用逗号隔开,冒号右边是返回值.lambda语句构建的其实是一个函数对象. 1>无参数 f=lambda :'python lambda!' >>&

  • Python iter()函数用法实例分析

    本文实例讲述了Python iter()函数用法.分享给大家供大家参考,具体如下: python中的迭代器用起来非常灵巧,不仅可以迭代序列,也可以迭代表现出序列行为的对象,例如字典的键.一个文件的行,等等. 迭代器就是有一个next()方法的对象,而不是通过索引来计数.当使用一个循环机制需要下一个项时,调用迭代器的next()方法,迭代完后引发一个StopIteration异常. 但是迭代器只能向后移动.不能回到开始.再次迭代只能创建另一个新的迭代对象. 反序迭代工具:reversed()将返回

  • Python callable()函数用法实例分析

    本文实例讲述了Python callable()函数用法.分享给大家供大家参考,具体如下: python中的内建函数callable( ) ,可以检查一个对象是否是可调用的 . 对于函数, 方法, lambda 函数式, 类, 以及实现了 _ _call_ _ 方法的类实例, 它都返回 True. >>> help(callable) Help on built-in function callable in module __builtin__: callable(...) calla

  • Tensorflow tf.tile()的用法实例分析

    tf.tile()应用于需要张量扩展的场景,具体说来就是: 如果现有一个形状如[width, height]的张量,需要得到一个基于原张量的,形状如[batch_size,width,height]的张量,其中每一个batch的内容都和原张量一模一样.tf.tile使用方法如: tile( input, multiples, name=None ) import tensorflow as tf a = tf.constant([7,19]) a1 = tf.tile(a,multiples=[

  • java队列之queue用法实例分析

    Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构 Queue接口与List.Set同一级别,都是继承了Collection接口.LinkedList实现了Deque接 口. Queue的实现 1.没有实现的阻塞接口的LinkedList: 实现了java.util.Queue接口和java.util.AbstractQueue接口 内置的不阻塞队列: PriorityQueue 和 ConcurrentLinkedQueue PriorityQueue 和 Concurren

  • php redis的scan用法实例分析

    在删除缓存的时候,我们在一些场景下需要批量删除,但不确定具体的key值,可通过匹配的方式进行查询后删除. 但是使用keys会导致redis服务器宕机.慎用... 一般公司也会禁用keys等比较敏感的命令的. 所以工作中会使用scan命令来进行匹配查询 SCAN cursor [MATCH pattern] [COUNT count] 比如 # 从游标 0 开始扫描 匹配 test1:* 的键值,一次扫描1000条 scan 0 match test1:* count 1000 1) 表示下一次扫

  • javascript闭包功能与用法实例分析

    本文实例讲述了javascript闭包功能与用法.分享给大家供大家参考,具体如下: 理解闭包 闭包这个东西,确实是很麻烦.之前我自己的理解也是有一点误差,所以今天将文章修改修改,争取将自己的理解进一步准确化. 闭包说得通熟易懂一点,就是指有权访问另一个函数作用域的变量的函数.创建闭包的常见方式,就是在一个函数内部创建另外一个函数,并返回. 我们这里举一个例子来说明,首先我们在函数f1内部定义一个函数f2. function f1(){ var n=999; function f2(){ aler

  • JavaScript闭包原理与用法实例分析

    本文实例讲述了JavaScript闭包原理与用法.分享给大家供大家参考,具体如下: 1.与闭包有关的两个概念: 1) 变量的作用域 不带有关键字var的变量会成为全局变量: 在函数中使用关键字var声明的变量是局部变量. 局部变量只有在函数内部才能访问到,在函数外面是访问不到的.但在函数内部可以通过作用域链一直向上搜索直到全局对象,也就是说,函数内部可以访问函数外部的变量. 2) 变量的生存周期 对于全局变量,其生存周期是永久的,除非主动销毁这个全局变量: 而对于在函数内用关键字var声明的局部

随机推荐