专栏首页kyle的专栏闭包(Closure)

闭包(Closure)

一、作用域及执行环境

要搞懂闭包首先得搞懂什么是作用域,作用域分为全局作用域局部(函数)作用域,每个作用域都有与他关联的变量对象(定义的所有变量和函数),作用域简单理解就是变量执行时的环境。

二、作用域链

当代码在一个环境中执行时,会创建变量对象的一个作用域链作用域链最前端是当前执行代码的所在的环境变量对象。之后是他的外部作用域,之后是外部的外部作用域,直到作用域链终点为全局执行环境。

示例如下代码:
var name = 'kayle'
function getName () {
  // var name = 'innerKayle'
  console.log(name) // kayle
}
getName()

函数getName当他被调用时会创建一个执行环境及相应的作用域链,然后arguments和其他命名参数的值来初始化函数的活动对象。可以在函数内部访问到变量name,是因为能够在作用域链中找到它。

三、闭包

闭包是一个定义在其他函数内部的函数,他由函数及创建该函数的词法环境组合而成,这个环境包含了这个闭包创建时所能访问的所有局部变量。闭包可以访问三种作用域中的变量:

  1. 自身函数内声明的变量
  2. 父函数作用域中的变量
  3. 全局中声明的变量
在 JavaScript 中所有函数都是闭包的,因为他们都可以访问外部作用域
缺点:

外部调用函数完毕后,作用域链中任然占用其内部函数对象,会使得内部父函数中的变量也都被保存在内存中,内存消耗很大(直到解除该函数的引用)。

闭包例子

  var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      return function(){
        return this.name;
      };

    }

  };

  alert(object.getNameFunc()()); //The Window

这里之所以输出了The Window是因为原型链中找到了全局中的变量name

  var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };

    }

  };

  alert(object.getNameFunc()()); //My Object

不要为了闭包而闭包

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}

修改后

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 有效的字母异位词

    输入: s = "anagram", t = "nagaram" 输出: true

    _kyle
  • 反转字符串

    编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

    _kyle
  • 两个数组的交集 II

    输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。 我们可以不考虑输出结果的顺序。

    _kyle
  • Laravel 5.5 为响应请求提供的可响应接口

    Laravel 5.5 的路由中增加了一种新的返回类型:可相应接口(Responsable)。该接口允许对象在从控制器或者闭包路由中返回时自动被转化为标准的 H...

    小李刀刀
  • 带你真正了解 JavaScript 中的 this

    任何情况下,this 都不会默认指向函数自己,除非使用 bind 绑定的方式修改 this 为函数自己。

    石燕平
  • 一文理解 this、call、apply、bind

    记得差不多在两年多之前写过一篇文章 两句话理解js中的this,当时总结的两句话原话是这样的:

    木子星兮
  • Javascript 组合继承 原型链继承 寄生继承

    该继承通过构造函数继承原型链的方法和父类的属性,但该方法会有两次调用父类,第一次是在继承原型链,第二次在继承属性。

    菜的黑人牙膏
  • [高大上的DL] Deep Learning中常用loss function损失函数的小结

    在前面我们分享的如何来训练CNN中,提到了BP算法,还记得BP算法是怎么更新参数w,b的吗?当我们给网络一个输入,乘以w的初值,然后经过激活函数得到一个输出。然...

    用户1622570
  • 8个有用的JavaScript技巧

    这些技巧可能大家大部分都用过了,如果用过就当作加深点映像,如果没有遇到过,就当作学会了几个技巧。

    行云博客
  • 8个有用的JS技巧

    这些技巧可能大家大部分都用过了,如果用过就当作加深点映像,如果没有遇到过,就当作学会了几个技巧。

    前端小智@大迁世界

扫码关注云+社区

领取腾讯云代金券