使用ES5尽可能的实现ES6 let和const关键字

509 阅读1分钟

前文提示

  • 实现let
    • 具有块级作用域
    • 具有暂时性死区(未能实现,但有无法提前使用的特点)
    • 没有变量提升(未能实现)
    • 不能重复声明(未能实现)
  • 实现const
    • 具有块级作用域(由于 ES5 环境没有 block 的概念,所以是无法百分百实现 const,只能是挂载到某个对象下,要么是全局的 window,要么就是自定义一个 object 来当容器)
    • 具有暂时性死区(未能实现,但有无法提前使用的特点)
    • 没有变量提升(未能实现)
    • 不能重复声明(但是会导致,即使在不同的作用域变量名也永远只能使用一次)
    • 声明常量必须赋值
    • 声明后非对象类型无法修改

let 实现

(function () {
  var a = 1;
  console.log(a); // 1
})()

const 实现

  var _const = (function () {
    var obj = {}
    return function (key, value) {
      if (arguments.length == 2) {
        if (!(key in obj)) {
          obj[key] = value
          Object.defineProperty(obj, key, {
            get() {
              return value
            },
            set(newValue) {
              throw new TypeError('Assignment to constant variable.')
            }
          })
        } else {
          throw new TypeError("Identifier 'a' has already been declared")
        }
        return obj
      } else {
        throw new SyntaxError('Missing initializer in const declaration')
      }
    }
  })()

  function fn() {
    var obj = _const("a", { b: 1 });
    obj.a.b = 2
    if (true) {
      var obj = _const("a", 1);
    }
    console.log('obj', obj);
  }
  fn();