JavaScript之ES6学习一(ES3、ES5与ES6常量定义对比)

1、JavaScript常量定义

(1)、常规定义对象参考

//定义对象obj,并制定属性name,age
var obj = {};
obj.name = "张三";
obj.age = 20;

//等价于
var obj = {
  name = "张三";
  age = 20;
} 

//等价于 
var obj = {}; 
Object.defineProperty(obj, "name", { 
  value: "张三"
, //初始值
  writable: true, //可写
  configurable: true, //可配置
  enumerable: true //可枚举 }); Object.defineProperty(obj, "age", { value: 20, //初始值 writable: true, //可写 configurable: true, //可配置 enumerable: true //可枚举 });

  这里涉及到了一个方法,Object.defineProperty(),该方法是ES5规范中的,该方法的作用是在对象上定义一个新属性,或者修改对象的一个现有属性,并对该属性加以描述,返回这个对象。

Object.defineProperty()方法可以定义对象属性的数据描述和存储描述,以下是数据描选项:

  configurable:当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,也能够被删除。默认为 false;
  enumerable:当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false;
  value:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined;
  writable:当且仅当该属性的 writable 为 true 时,该属性才能被赋值运算符改变。默认为 false

注意:

  当我们用常规方法定义属性的时候,其除 value 以外的数据描述符默认均为 true ,当我们用 Object.defineProperty() 定义属性的时候,默认为 false。也就是说,当我们把 writable 设置为 false 的时候,该属性是只读的,也就满足了常量了性质,我们把常量封装在CONST命名空间里面

var CONST = {};
Object.defineProperty(CONST, "NUM", {
     value: 1,
     writable: false, //设置属性只读
     configurable: true,
     enumerable: true
});
console.log(CONST.NUM);  //1
CONST.NUM = 2; //在严格模式下会抛错,在非严格模式下静默失败,修改无效。

  但是这样定义的常量不是绝对的,因为我们依然可以通过修改属性的数据描述符来修改属性值:

var CONST = {};
Object.defineProperty(CONST, "NUM", {
     value: 1,
     writable: false,
     configurable: true,
     enumerable: true
});
Object.defineProperty(CONST, "NUM", {
     value: 2,
     writable: true,  //恢复属性的可写状态
     configurable: true,
     enumerable: true
})
console.log(CONST.NUM);  //2
CONST.NUM = 0;
console.log(CONST.NUM);  //0

  想要做到真正的常量,还需要将属性设置为不可配置:

var CONST = {};
Object.defineProperty(CONST, "NUM", {
     value: 1,
     writable: false,        //设置属性只读
     configurable: false,    //设置属性不可配置
     enumerable: true
});
console.log(CONST.NUM);  //1
CONST.NUM = 2;  //错误!属性只读
Object.defineProperty(CONST, "NUM", {
     value: 2,
     writable: true, 
     configurable: true,
     enumerable: true
});  //错误!属性不可配置

  但是如果只设置属性为不可配置状态,依然可以对属性值进行修改:

var CONST = {};
Object.defineProperty(CONST, "NUM", {
     value: 1,
     writable: true,         //设置可写
     configurable: false,    //设置属性不可配置
     enumerable: true
});
console.log(CONST.NUM);  //1
CONST.A = 2;
console.log(CONST.NUM);  //2

  进而我们可以推断出,configurable 描述符仅冻结属性的描述符,不会对属性值产生影响,也就是说该描述符会冻结 writable、configurable、enumerable 的状态,不会对属性值加以限制:

 var CONST = {};
Object.defineProperty(CONST, "NUM", {
     value: 1,
     writable: false,         //设置不可写
     configurable: false,     //设置属性不可配置
     enumerable: false        //设置不可枚举
});
Object.defineProperty(CONST, "NUM", {
     value: 2,                //该属性本身不受 configurable 的影响,但由于属性不可写,受 writable 的限制
     writable: true,          //错误!属性不可配置
     configurable: true,      //错误!属性不可配置
     enumerable: true         //错误!属性不可配置
});

  但是 configurable 的限制有一个特例,就是 writable 可以由 true 改为 false,不能由 false 改为 true:

var CONST = {};
Object.defineProperty(CONST, "NUM", {
     value: 1,
     writable: true,          //设置可写
     configurable: false,     //设置属性不可配置
     enumerable: false        //设置不可枚举
});
Object.defineProperty(CONST, "NUM", {
     value: 2,  //该属性本身不受 configurable 的影响,由于属性可写,修改成功
     writable: false, 
     configurable: false, 
     enumerable: false 
});
console.log(CONST.NUM);  //2
CONST.NUM = 0;  //错误!属性只读

  可枚举描述符用于配置属性是否可以枚举,也就是是否会出现在 for ... in ... 语句中:

var CONST = {};
Object.defineProperty(CONST, "NUM", {
     value: 1,
     writable: false,
     configurable: false,
     enumerable: true  //可枚举
});
Object.defineProperty(CONST, "NUM", {
     value: 2,
     writable: false,
     configurable: false,
     enumerable: false  //不可枚举
});
for (var key in CONST) {
     console.log(CONST[key]);  //1
};

  有了以上的基础,我们也就学会一种定义常量的方法,使用属性的数据描述符,下次我们需要用到常量的时候,就可以定义一个 CONST 命名空间,将常量封装在该命名空间里面,由于属性描述符默认为 false,所以我们也可以这样定义:

var CONST = {};
Object.defineProperty(CONST, "NUM", {
     value: 1,
     enumerable: true
});
Object.defineProperty(CONST, "NUM", {
     value: 2,
     enumerable: true
});

(2)ES6中常量的定义

const NUM = 1
console.log(NUM)
NUM = 2; //错误,属性为只读

 

posted on 2018-10-14 18:21  Zkai-007  阅读(696)  评论(0编辑  收藏  举报

导航