视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Javascript闭包用法实例分析_javascript技巧
2020-11-27 21:33:24 责编:小采
文档


本文实例分析了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程序设计有所帮助。

    下载本文
  • 显示全文
    专题