深入理解函数内部原理(5)——闭包
来源:互联网 发布:i like it what is it 编辑:程序博客网 时间:2024/06/06 01:38
什么是闭包
其实通过前面几篇博客系统的介绍了函数的定义调用执行过程之后,带现在应该可以隐隐约约的感觉的闭包的存在了。
什么是闭包呢?我的理解就是 函数定义的时候的作用域链在函数调用的时候依然有效,这就是闭包。
那么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));
- 深入理解函数内部原理(5)——闭包
- 深入理解函数内部原理(六)——函数的内部方法call、apply、bind
- 深入理解函数内部原理(1)——函数定义、调用、解析、执行
- 深入理解函数内部原理(4)——通过new操作符调用构造函数
- 深入理解函数内部原理(3)——动态的this
- 深入理解函数内部原理(2)——对一个函数实例进行深入的分析
- 深入理解javascript原型和闭包系列 深入理解javascript原型和闭包(5)——instanceof
- 深入理解javascript原型和闭包系列 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- 深入理解javascript原型和闭包(2)——函数和对象的关系
- VS2013常用快捷键
- SQL集合函数中case when then 使用技巧
- 使用jQuery插件时避免重复引入jquery.js文件(jQuery 重复加载错误以及修复方法)
- 43. Multiply Strings
- 幻读和不可重复读的区别
- 深入理解函数内部原理(5)——闭包
- 虚继承下对象的内存分布
- 近200篇机器学习&深度学习资料分享(含各种文档,视频,源码等)
- 对于 RxJava2 的 认知与直接应用(一)
- codeforces Educational Round 16 E. Generate a String
- 关于RabbitMQ的远程ip访问的解决方法
- Token
- 自动补全插件 jquery.autocomplete
- stm32笔记--1硬件