用ES5的方式实现const

ES5中的两种属性类型:数据属性和访问器属性;

数据属性:包含一个数据值的位置,在这个位置可以读取和写入值;有4个描述其行为的特性;

Configuarable: 能否通过delete删除属性,并且重新定义属性,

Enumerable: 能否通过for-in循环返回该属性,

Writable: 能否修改属性的值;

Value: 这个属性的数据值,默认为undefined

根据定义对象的方式不同,Configurable,Enumerable,Writable默认值也不同

方式1: var person = {name: '张三'}

则person对象的name属性的属性描述符对象中的Configurable,Enumerable,Writable 值均默认为true

方式2:

var person = {}

Object.defineProperty(person,'name',{

value: '张三'

})

则person对象的name属性的属性描述符对象中的Configurable,Enumerable,Writable 值均默认为false

    // "use strict"
    var person = {}
    Object.defineProperty(person, 'name', {
      value: '张三'
    })
    console.log(person.name); //张三
    //启用严格模式时: "use strict"; Uncaught TypeError: Cannot assign to read only property 'name' of object '#'
    person.name = '李四'; 
    console.log(person.name);   //张三 
  

访问器属性:不包含数据值,包含一对儿的getter和setter函数

Configuarable: 能否通过delete删除属性,并且重新定义属性,

Enumerable: 能否通过for-in循环返回该属性,

Get: 在读取属性时调用的函数,默认为undefined

Set: 在写入属性时调用的函数,默认为undefined

访问器属性不能直接定义,必须使用Object.defineProperty()来定义

 

// 1. 自定义容器充当数据的存储
    var constObj = {}
    function getConst(key, val) {
      constObj[key] = val;
      Object.defineProperty(constObj, key, {
        value: val,
        configurable: false, //配置信息是否可修改
        writable: false, //是否可修改改属性值
        enumerable: true //是否可枚举
      })
    }
    getConst('a', 10)
    constObj.a = 20;
    console.log(constObj.a);    //10

   // 2. 挂载到window上面
    function getConst2(constKey, constVal) {
      window[constKey] = constVal;
      Object.defineProperty(window, constKey,{
        get: function() {   //如果设置了 set 或 get, 就不能设置 writable 和 value 中的任何一个,否则报错
          return constVal;
        },
        enumerable: true, //是否可枚举
        configurable: false,  //是否可修改当前描述的配置信息
      })
    }
    getConst2('b', 30);
    getConst2('c', 50);
    console.log(window.b);    //30
    console.log(window.c);    //50
    window.b = 66
    console.log(window.b);    //30

 

你可能感兴趣的:(JavaScript)