欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JS面试题:ES5实现let 和const

程序员文章站 2022-06-09 18:46:55
...

JS面试题:ES5实现let 和const

最近面试的时候碰到一道面试题,如何用ES5实现const,一时间竟没有思路,于是面试后有了这篇文章。

ES6中新增的let和const都是定义变量的字段。

let

let的特性

首先我们来看看let的特性,let用来声明一个变量:

  • 在块级作用域内有效
  • 不能重复声明
  • 不能预处理,不存在变量提升,即未声明之前的代码不能调用

如何实现

我们可以通过匿名函数和闭包的形式来模拟let

(function(){
  var c =3
  console.log(c) //1
})()
console.log(c)  //c is not defined

如上面的代码,用匿名函数的作用域来模拟块级作用域,将用到let的代码放到匿名函数中,就不会造成变量污染了

const

const的特性

const用于声明一个常量,

  • 在块级作用域内有效
  • 不能重复声明
  • 不能预处理,不存在变量提升,即未声明之前的代码不能调用

他除了有和let一样的特性外,还有自己的特性:

  • 不能修改(要注意,数组和对象属于引用数据类型,const保存的是指向对象的指针,所以修改其中的属性时指针不变,可以修改)
  • 使用时必须初始化(必须赋值)
//即不能是
const c
//必须
const c =1

如何实现const

这个是今天的重头戏,要实现const我们必须了解js中的数据属性和访问器属性,了解了之后说不定你自己已经有思路实现const了

数据属性

定义在对象内部的数据有四个特征:

  • configurable:是否可以被 delete 删除或者改变特征值
  • enumerable:是否能通过 for-in 循环遍历返回属性
  • writable:是否可以修改属性的值
  • value:保存这个属性的数据值

访问器属性

指以下四个属性:

  • configurable:能否通过 delete 删除,能否修改属性特性
  • enumerable:能否通过 for-in 循环返回属性
  • getter:读取属性时调用的函数,默认为 undefined
  • setter:写入属性时调用的函数,默认为 undefined

用对象直接创建的属性,其writable、enumerable和configurable 都是默认为true

看到这里可能你已经有思路了,就是去改变这几个属性,还有在getter和setter中做文章

对于不可重复赋值,我们可以设置其configurable为false,同时 set中判断是否重复赋值,如果是即报错,而块级作用域可以用对象作为容器创造函数作用域代替

而如何修改这些属性呢,可以使用Object.defineProperty() 方法

Object.defineProperty(obj, prop, descriptor):会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

obj:要定义属性的对象

prop:要定义或修改的属性的名称

descriptor:要定义或修改的属性描述符

function _const(key, value) {
  window[key] = value;
  Object.defineProperty(window, key, {
    enumerable: false,
    configurable: false,
    get: function () {
      return value;
    },
    set: function (newValue) {
      if (newValue !== value) {
        throw TypeError("这是只读变量,不可修改");
      } else {
        return value;
      }
    },
  });
}

结语

到这里你应该已经了解了如何实现let和const了,但关于这两个字段相关的知识点还有很多,可以去了解一下作用域、执行上下文和变量声明过程,相信你会对js有更深的认识。学无止境,让我们一起冲!