如何用es5实现const

最近看到一个面试题
在这里插入图片描述
第一题就把我撂倒了
—— 用ES5实现const,

const – es6中定义制只读常量的关键字。

const PI = 3.141592653

1、对象属性

先看一下这个对象

 var student ={};
    student.name = 'cxx';
    student.age = '16';

然后我们修改一下

 student.age = '16';

我们修改了属性age的值,我们可以修改属性age的值,也可以删除属性age,这些操作称为对象属性的性质。所以如果我们想要设置成const ,把这个属性设置成不能修改的不就可以了吗,所以了解一下属性的性质的修改方法。

2、认识Object.defineProperty()方法。

Object.defineProperty()方法会在一个对象上定义一个新的属性,或者修改一个对象的现有属性,并返回此对象。

需要注意的是:应当直接在Object构造器对象上调用此方法,而不是再任意一个Object类型的实例上调用。

语法如下:

Object.defineProperty(obj, prop, descriptor)

obj
要定义属性的对象
prop
要定义或修改属性名称或symbol
descriptor
要定义或修改属性描述符

Object.defineProperty() 方法可以定义对象属性的数据描述和存储描述,这里我们只讲数据描述符,不对存储描述符讲解,数据描述符有以下选项:

扫描二维码关注公众号,回复: 11539138 查看本文章
属性描述符 说明
value 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
get 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined .默认为undefined
set 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法 默认为undefined
writable 当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false
enumerable enumerable定义了对象的属性是否可以在 for…in 循环和 Object.keys() 中被枚举
Configurable configurable特性表示对象的属性是否可以被删除,以及除value和writable特性外的其他特性是否可以被修改

对位const不可修改的属性,我们可以用writable属性来实现

function _const(key, value) {
        const desc = {
            value,
            writable:false
        };

        Object.defineProperty(window, key, desc);

    }

    _const('obj', {a: 1});   //定义obj
    obj.b = 2;               //可以正常给obj的属性赋值
    obj = {}                //抛出错误,提示对象read-only

3、实现const定义

      var __const = function __const (data, value) {
        window.data = value // 把要定义的data挂载到window下,并赋值value
        Object.defineProperty(window, data, { // 利用Object.defineProperty的能力劫持当前对象,并修改其属性描述符
          enumerable: false,
          configurable: false,
          get: function () {
            return value
          },
          set: function (data) {
            if (data !== value) { // 当要对当前属性进行赋值时,则抛出错误!
              throw new TypeError('Assignment to constant variable.')
            } else {
              return value
            }
          }
        })
      }
      __const('a', 10)
      console.log(a)
      delete a
      console.log(a)
      for (let item in window) { // 因为const定义的属性在global下也是不存在的,所以用到了enumerable: false来模拟这一功能
        if (item === 'a') { // 因为不可枚举,所以不执行
          console.log(window[item])
        }
      }
      a = 20 // 报错

参考
1、https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty 2、https://juejin.im/post/6844903745562607623

猜你喜欢

转载自blog.csdn.net/Alive_tree/article/details/107839058
ES5