首页  >  文章  >  web前端  >  Javascript闭包用法实例分析_javascript技巧

Javascript闭包用法实例分析_javascript技巧

WBOY
WBOY原创
2016-05-16 16:18:241115浏览

本文实例分析了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    aLi[i].onclick = function() {
     alert(i); // 无论点击哪个
  • 元素,弹出的值都为len,表明这里的i和在for之后打印i的值是一样的。
       };
    }

  • 使用闭包后:
    复制代码 代码如下:
    var aLi = document.getElementsByTagName('li');
    for (var i=0, len=aLi.length; i   aLi[i].onclick = (function(i) {
        return function() {
          alert(i); // 此时点击
  • 元素,就会弹出对应的下标了。
        }
      })(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程序设计有所帮助。

    声明:
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn