🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
ES5扩展了Object对象的接口,增加了几个特别的函数,可以在程序运行时影响解释器的行为。如:defineProperty,seal,freeze...等等。 实际上这些函数改变的是对象的内部状态,解释器在解释对象时会根据他的内部状态改变自己的行为,这些状态被称为特性(attribute)。 ES5能直接操作对象的属性描述,一个普通属性拥有四种特性。 * value。访问属性时的值。 * writable。表示属性value的可写性。 * enumerable。表示属性可枚举。 * configurable。表示属性描述可配置。 使用getOwnPropertyDescriptor函数可以获取属性的描述。 ~~~ var foo = { a: 0 }; var desc = Object.getOwnPropertyDescriptor(foo, 'a'); console.dir(desc); ~~~ ![](https://box.kancloud.cn/81d686122b29b83f7be24b12812929f3_183x102.jpg) 可见除了value被设置了,其他特性默认值为true。 通过defineProperty或defineProperties可以定义或修改属性的描述。如 ~~~ var foo = {}; Object.defineProperties(foo, { a: { value: 0, writable: false, } }); console.dir(foo);//{a:0} foo.a = 666; console.dir(foo);//{a:0} ~~~ 可见,当writable为false时,该属性就不可写。 ES5内置的其他特性也会影响解释器的行为,具体此处不再详述。 # 访问器属性 在ES5还提供了一种叫访问器的属性,而之前ES默认使用的属性被称为数据属性。 访问器属性的描述有四种特性。 * get。获取属性值时触发的函数。 * set。设置属性值时触发的函数。 * enumerable。表示属性可枚举。 * configurable。表示属性的可配置。 事实上,我们可以把访问器属性看作是特殊的函数,不过一个属性有可能被分为两个函数。 ~~~ var foo = {}; Object.defineProperties(foo, { a: { set: function (v) { console.info('set'); console.dir(v); }, get: function () { return 'get'; } } }); foo.a = 123; console.info(foo.a); ~~~ ![](https://box.kancloud.cn/69459cf31ac6838843976bf953fac76e_109x64.jpg) # 以属性描述为起点 在一些高级语言里,也有特性的概念。如C#的特性,JAVA的注解,他们也能在运行时影响解释器的行为。而C#/JAVA中的特性更为强大,不仅能描述属性,还能描述类,描述函数……等等,又或是添加自定义的特性,在运行中反射特性为自己所用,却可以不改变已有代码的结构。这也是所谓的AOP(面向切面编程)。 目前来说,ES的特性(attribute)只有一些简单的功能,但可以想象的是,ES未来发展一定会逐步完善特性。