深入理解函数内部原理(5)——闭包

    xiaoxiao2021-03-25  126

    什么是闭包

    其实通过前面几篇博客系统的介绍了函数的定义调用执行过程之后,带现在应该可以隐隐约约的感觉的闭包的存在了。 什么是闭包呢?我的理解就是 函数定义的时候的作用域链在函数调用的时候依然有效,这就是闭包。 那么js内部是怎么实现的呢?还记得函数对象有一个内部属性是[Scope]吗?挡在函数创建的时候,这个内部属性背赋一个值,这个值就是函数所在的执行环境的此法环境也就是说外部的作用域,对于具名的函数表达式特殊一点,不过仅仅是在外部的作用域前年有多加了一个用来描述这个函数的词法环境而已,所以说函数在定义的时候本身就保存的作用域链。

    在函数调用的时候,创建这个函数的执行环境,同时执行环境对应的词法环境中外部词法环境属性就是这个函数内部属性[Scope]的值,这就将这个函数的作用域链接到定义时的作用域链中,所以通过作用域链的查找,是的定义时外部的环境中定义变量依然存在依然能够访问。

    闭包缺点就是,创建闭包必然要多创建执行环境、词法环境等耗费内存。

    说的有点抽象,可以通过这一篇博客感受一下[Scope]强大:http://blog.csdn.net/wmaoshu/article/details/60766030

    闭包的一些实用技巧

    模仿块级作用域

    (function(){ })();

    这个主要应用在创建命名空间上,防止不同的开发人员之间命名发生冲突。

    私有变量

    每次函数调用,执行函数 都会将该函数内的变量重新创建一份

    function MyObject(value){ //私有变量和私有函数 var privateVariable = value; function privateFunction(){ return privateVariable; } //特权方法 this.publicMethod = function(){ privateVariable++; return privateFunction(); }; } var o = new MyObject(20); console.log(o.publicMethod()); var o2 = new MyObject(30); console.log(o2.publicMethod());

    私有变量privateVariable 在每一个MyObject实例中都不一样,因为创建的执行环境不用,对应的作用于也就不一样。缺点就是每一次构造新对象都会执行一边函数定义,浪费内存。

    function constrfunc(){ var funcs=[]; for(var i =0; i<10; i++){ funcs[i] = (function(i){ return function(){ return i; } })(i); } return funcs; }

    静态私有变量

    只执行一次

    var MyObject = null; (function (){ var privateVariable = 10; function privateFunction(){ return privateVariable; }; MyObject = function(){ }; MyObject.prototype.publicMethod = function(){ privateVariable++; return privateFunction(); }; })(); var o = new MyObject(); console.log(o.publicMethod()); var o2 = new MyObject(); console.log(o2.publicMethod());

    正式因为表述的是静态的量,所以这两个MyObject实例为一个值

    模块模式

    var singletion = function(){ var privateVariable = 10; function privateFunction(){ return privateVariable; }; return { publicMethod :function(){ privateVariable++; return privateFunction(); }; } }

    增强版本适用于某些单例必须是某种类型的实例。

    var singletion = function(){ var privateVariable = 10; function privateFunction(){ return privateVariable; }; var obj = new CustomType(); obj.publicMethod =function(){ privateVariable++; return privateFunction(); }; return obj; }

    高阶函数

    将传入介个函数作为参数,将这个这些函数视为模块重新定义的过程

    function compose(f,g){ return function(){ return f.call(this,g.apply(this,arguments)); }; } var square = function(x){return x*x;}; var sum = function(x,y){return x+y;}; var squareofsum = compose(square,sum); console.log(squareofsum(2,3));

    记忆

    缓存的作用 function memorize(f){ var cache = {}; return function(){ var key = arguments.length+Array.prototype.join.call(arguments,”,”); if(key in cache)return cache[key]; else return cache[key] = f.apply(this,arguments); }; }

    var factorial = memorize(function f(n){ return (n<=1) ? 1:n*f(n-1); }); console.log(factorial(5));
    转载请注明原文地址: https://ju.6miu.com/read-2448.html

    最新回复(0)