Fe-interview: [js] 第14天 什么是闭包?优缺点分别是什么?

Created on 29 Apr 2019  ·  15Comments  ·  Source: haizlin/fe-interview

第14天 什么是闭包?优缺点分别是什么?

js

Most helpful comment

闭包是可以访问另一个函数作用域的函数。由于 javascript 的特性,外层的函数无法访问内部函数的变量;而内部函数可以访问外部函数的变量(即作用域链)。

function a(){
    var b = 1;
    var c = 2;
    // 这个函数就是个闭包,可以访问外层 a 函数的变量
    return function(){
        var d = 3;
        return b + c + d;
    }
}

var e = a();
console.log(e());

因此,使用闭包可以隐藏变量以及防止变量被篡改和作用域的污染,从而实现封装。
而缺点就是由于保留了作用域链,会增加内存的开销。因此需要注意内存的使用,并且防止内存泄露的问题。

All 15 comments

(fucntion(){

})()
function(){
  var a = 0;
 return function(){
   return a++
 }
}

上面就是闭包,有独立的作用域,且作用域的变量不会在程序中释放

closure:关闭
关闭变量或者说是隐藏一个变量
我们函数套函数其实相当于形成了一个局部作用域,就达到了隐藏的目的
仅此而已

  1. 首先,在函数外部是无法访问函数内部的变量的。
  2. 为了解决上述问题,则引入了闭包。简单来说就是为了能访问函数A内部的变量值,需要在函数A中定义一个其他的函数B,并且将B返回给外部变量,那么外部变量就可以通过B来访问到函数A中的变量了。这就是闭包。
  3. 闭包方便访问函数内部的变量,但同时也会导致原来函数A中的变量无法及时销毁,导致内存占用过高。并且如果没有及时销毁的话,也存在内存泄露问题。

闭包:在局部作用域引用上层作用域(非全局)的变量
优点:防止变量污染作用域
缺点:不释放则会导致内存泄漏

闭包是可以访问另一个函数作用域的函数。由于 javascript 的特性,外层的函数无法访问内部函数的变量;而内部函数可以访问外部函数的变量(即作用域链)。

function a(){
    var b = 1;
    var c = 2;
    // 这个函数就是个闭包,可以访问外层 a 函数的变量
    return function(){
        var d = 3;
        return b + c + d;
    }
}

var e = a();
console.log(e());

因此,使用闭包可以隐藏变量以及防止变量被篡改和作用域的污染,从而实现封装。
而缺点就是由于保留了作用域链,会增加内存的开销。因此需要注意内存的使用,并且防止内存泄露的问题。

https://cnodejs.org/topic/5d39c5259969a529571d73a8

感谢大佬的分享,讲的十分透彻。

闭包的定义:从外部访问或者操作函数内部变量的的方式,缓存数据,延长作用域链(JS是函数作用域)

例子:定义了一个内部变量,但是不想使这些变量不能被外部随意修改,同时又可以通过指定的函数接口来操作来访问,闭包的作用常常用来「间接访问一个变量」。换句话说,「隐藏一个变量」

缺点:函数中的变量不能及时的释放

function Foo(){
 var name = "fooname";  //需要从外部访问这些变量
 var age = 12;

 this.getFoo = function(){  //设置访问方法
  return name;
 }

 this.setFoo = function(){
  return age;
 }
 this.xgFoo = function(new){
  name = new;
 }
}

var foo = new Foo();
foo.getFoo();  //访问name变量。
foo.xgFoo("liz") //从外部修改nage变量

当函数能够记住并访问所在的词法作用域,即使函数是在当时词法作用域之外执行,这是就产生了闭包。

词法作用域是变量或函数声明时,在词法解析阶段所在的作用域。

function foo() {
  var a = 2;

  function bar() {
    console.log(a)
  }

  return bar
}

var baz = foo()

bar() // 2
  1. 编译器进行词法解析阶段就已经确定 foo 函数的作用域内有 abar 标识符。
  2. foo 函数执行,将 bar 函数的引用返回
  3. 在全局作用域调用 bar 函数,也就是在 bar 函数词法作用域(foo) 之外调用。按理说 foo 函数调用完结束后就应该被销毁了。但是闭包能够让 bar 函数一直引用着它在词法阶段所在的作用域 foo,这个引用就是闭包。所以可以正常访问变量 a

这个 bar 函数在定义的词法作用域以外的地方被调用。闭包使得函数能够继续访问定义时的词法作用域。

无论通过何种手段将内部函数传递到所在的词法作用域以外,它都会持有对原始定义作用域的引用,无论何时执行这个函数都会使用闭包。

定义

看黑体字:
函数wrapper_func内 返回一个函数inner_func, 外部通过inner_func可以访问wrapper_func函数内变量(作用域链)。

用法

函数返回函数,形成局部作用域

优点

局部作用域,防止变量污染

缺点

内存泄露

面试官会问的在那里使用:

命名空间/for循环取第i个处理为什么返回同一个i值(可以搜一下,老面试题了)

闭包是一个函数,这个函数可以访问另一个函数的变量。(当你创建一个函数时你就创建了一个闭包)
优点:由于闭包里可以访问外部变量,但是外部不能访问闭包里的变量,所以可以保护一些重要的不能被修改的变量。
缺点:在老IE6使用闭包可能会造成内存泄漏

闭包就是声明在函数内部的函数(或者是可以访问外部函数变量的函数)
优点:希望一个变量长期存储在内存中,避免全局变量的污染,私有成员的存在
缺点:会导致内存占量过高,容易造成内存泄露

函数中裹着函数就产生闭包,父函数访问子函数就是借用闭包的作用
子函数访问父函数就是顺着作用域链
有点类似vue框架的父能传参给子组件,而子组件只能this.emit才行

第14天 什么是闭包?优缺点分别是什么?

函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在 JavaScript 中,每当函数被创建,就会在函数生成时生成闭包。

闭包:在局部作用域引用上层作用域(非全局)的变量
优点:防止变量污染作用域
缺点:不释放则会导致内存泄漏

Was this page helpful?
0 / 5 - 0 ratings