跳到主要内容

变量、闭包

变量

var

  1. var 可以重复声明
  2. 作用域:全局作用域 和 函数作用域
  3. 会进行预解析

let

  1. 统一作用域下不能重复声明
  2. 作用域:全局作用域 和 块级作用域
  3. 不进行预解析

letvar 比较

  1. var 声明的变量只能是全局或者整个函数块的
  2. let 允许声明一个在作用域限制在块级的变量、语句或者表达式(块级作用域)
  3. let 不能重复声明
  4. let 存在临时死区(temporal dead zone)
  5. let 不会被预解析(hoisting)

const

  1. let 有的它也有
  2. 初始化必须赋值
  3. 赋值后不能改动类型

暂时性死区

只要块级作用域内存在 let/const 命令,它所声明的变量就绑定这个区域,不再受外部的影响。在代码块内,使用 let/const 声明变量之前,该变量都是不可用的,所以叫 “暂时性死区”。

函数作用域和块级作用域

  • 函数作用域:在 JavaScript 中定义一个函数,函数内部的变量只能通过函数内部访问,同时它可以修改和影响外部变量。
  • 块级作用域:变量在离开定义的块级代码后立即被回收,存在暂时性死区的特性。块语句用于组合零个或者多个语句,这个块由一对大括号 界定。
提示

在 ES5 中只有全局作用域和函数作用域,没有块级作用域,这会带来些许麻烦:

  1. 内层变量覆盖外层变量
  2. 循环的变量泄露为全局变量
  • ES5 形成块级作用域的方法
(function () {
var a = 1;
})();
  • ES6 通过 界定
{
var x = 1; // 或者 const x = 1;
}

闭包

当通过调用一个外部函数返回一个内部函数后,即使该外部函数已经执行结束了,但是内部函数引用外部函数的变量依然保存在内存中,我们就把这些变量的集合称为闭包。

  • 简单来说:在函数 A 中还有函数 B,函数 B 调用了函数 A 中的变量,那么函数 B 就称为函数 A 的闭包

闭包好处和坏处

  • 好处:

    1. 缓存。将变量隐藏起来不被 GC 回收。
    2. 实现柯里化。利用闭包特性完成柯里化
  • 坏处:

    1. 内存消耗。闭包产生的变量无法被销毁。
    2. 性能问题。由于闭包内部变量优先级高于外部变量,所以需要多查找作用域链的一个层次,一定程度影响查找速度

this

important
  • this 永远指向最后调用它的那个对象
  • 普通函数中 this 的指向,是 this 执行时的上下文
  • 箭头函数中 this 的指向,是 this 定义时的上下文