前言:写这篇文章是因为我面试栽在了这个问题上,说起来可笑,我一直觉得自己对这个问题理解的很透彻,其实诶!!!!。闲话不多说,希望大家看完之后有所收获不再栽跟头。。
题目:一句话说明什么是闭包?
说法一:闭包是指有权访问另外函数作用域中的变量的函数。---《js高级程序设计》函数表达式章节的解释。
说法二:闭包是函数和声明该函数的词法环境的组合。这个环境包含了这个闭包创建时所能访问的所有局部变量---《MDN网站的解释》(官方)
说法三:通俗一点讲,就是一个函数里面声明的内部函数,这个内部函数有权访问它外部函数的环境变量。(不够严谨)
闭包的特点:
1、闭包就是能够读取其他函数内部变量的函数,函数没有被释放,整条作用域链上的局部变量都将得到保留
2、用闭包模拟私有方法
引入MDN网站代码的例子说明,代码如下
var makeCounter = function() { var privateCounter = 0; function changeBy(val) { privateCounter += val; } return { increment: function() { changeBy(1); }, decrement: function() { changeBy(-1); }, value: function() { return privateCounter; } } };var Counter1 = makeCounter();var Counter2 = makeCounter();console.log(Counter1.value()); /* logs 0 */Counter1.increment();Counter1.increment();console.log(Counter1.value()); /* logs 2 */Counter1.decrement();console.log(Counter1.value()); /* logs 1 */console.log(Counter2.value()); /* logs 0 */复制代码
上述代码中分别两次引用了makeCounter,生成的两个计数器。这两个计数器就是两个闭包,他们具有各自的独立性。每个闭包都是引用自己词法作用域内的变量 privateCounter
。以这种方式使用闭包,提供了许多与面向对象编程相关的好处 —— 特别是数据隐藏和封装。
关于性能方面的考量
如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。
例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。原因是这将导致每次构造器被调用时,方法都会被重新赋值一次(也就是,每个对象的创建)。