zoukankan      html  css  js  c++  java
  • [读书笔记]JavaScript 闭包(Closures)

    1. 什么是闭包?

    参考MDN

    2. 闭包的使用示例

    2.1 示例1

     1     <div>1</div>
     2     <div>2</div>
     3     <div>3</div>
     4     <script>
     5         var nodes = document.getElementsByTagName('div');
     6         for (var i = 0, len = nodes.length; i < len; i++) {
     7             /* 注意这里 */ 
     8             (function (i) {
     9 
    10                 nodes[i].onclick = function () {
    11                     console.log(i + 1);
    12                 };
    13 
    14             })(i);
    15 
    16         };
    17     </script>

    2.2 延伸

    1 var Type = {};
    2 for (var i = 0, type; type = ['Number', 'String', 'Boolean', 'Array', 'Function',
    3     'RegExp', 'Date', 'Undefined', 'Null','Error'][i++];) {
    4     (function (type) {
    5         Type['is' + type] = function (obj) {
    6             return Object.prototype.toString.call(obj) === '[object ' + type + ']';
    7         }
    8     })(type);
    9 };

    说明:对于本例来说仅能判断类型,并不能保证类型的合法性,如判断Date如下所示:

    1 function isValidDate(d) {
    2     if (Object.prototype.toString.call(d) !== "[object Date]") {
    3         return false;
    4     }
    5     return !isNaN(d.getTime());
    6 }

    3. 闭包的更多作用及示例

    3.1 封装变量

    在闭包块中实现“私有变量”

     1 var mult = (function () {
     2     var cache = {}, // “制表法”缓存结果集,避免重复的运算
     3         // 封闭calculate 函数
     4         calculate = function () { 
     5         var a = 1;
     6         for (var i = 0, l = arguments.length; i < l; i++) {
     7             a = a * arguments[i];
     8         }
     9 
    10         return a;
    11     };
    12 
    13     return function () {
    14         var args = Array.prototype.join.call(arguments, ',');
    15         if (args in cache) {
    16             return cache[args];
    17         }
    18 
    19         return cache[args] = calculate.apply(null, arguments);
    20     };
    21 })();

     MDN的例子用闭包模拟私有方法,也是模块模式的基础。

    3.2 延续局部变量的寿命

    1 var report = function( src ){
    2 var img = new Image();
    3 img.src = src;
    4 };
    5 report( 'www.xxx.com/stat' );
    有问题的代码

    为了解决函数局部变量在函数执行后立即被销毁的问题,可以用闭包来保存对局部变量的引用以达到延续局部变量生命周期。

     1 var report = (function () {
     2     var imgs = [];
     3 
     4     return function (src) {
     5         var img = new Image();
     6         imgs.push(img);
     7         img.src = src;
     8     }
     9 })();
    10 
    11 report('www.xxx.com/stat');

    3.3 闭包和面向对象设计

     1  // 闭包写法
     2  var extent = function () {
     3      var value = 0;
     4      return {
     5          call: function () {
     6              value++;
     7              console.log(value);
     8          }
     9      };
    10  };
    11  var extent1 = extent(),
    12      extent2 = extent();
    13  extent1.call(); // 输出:1
    14  extent1.call(); // 输出:2
    15  extent1.call(); // 输出:3
    16 
    17  extent2.call(); // 输出:1
    18 
    19  var Extent = function () {
    20      this.value = 0;
    21  };
    22 
    23  // 面向对象的写法 
    24  Extent.prototype.call = function () {
    25      this.value++;
    26      console.info(this.value);
    27  };
    28  var myExtent1 = new Extent();
    29  myExtent1.call();
    30  myExtent1.call();
    31  myExtent1.call();
    32 
    33  var myExtent2 = new Extent();
    34  myExtent2.call();

    说明:本文代码来自《JavaScript设计模式与开发实践》和网络。

  • 相关阅读:
    oracle之sqlplus讲解
    oracle数据库--启动和关闭
    linux下使用SSL代理(SSLedge)
    Titanium系列--利用js动态获取当前时间
    Titanium系列--利用Titanium开发android App实战总结
    Titanium系列--我常用的Titanium的快捷键(持续更新中。。)
    Titanium系列--安装Titanium Studio 中的Android SDK,JDK以及环境变量的配置(二)
    Titanium系列--Titanium的简介、Titanium Studio安装和配置(一)
    Happymenu新的开始
    对IEnumerable<T>和IQueryable<T>的一点见解
  • 原文地址:https://www.cnblogs.com/January/p/5427385.html
Copyright © 2011-2022 走看看