首先,感性的认知一下对象。
Object 在英文中表示东西, (可看见或者触摸到的)实物。可以理解为实体的一切事物。
编程语言里的对象是顺着人类思维模式产生的一种抽象(于是面向对象编程也被认为是:更接近人类思维模式的一种编程范式)。
在 Javascript 里,属性并非只是简单的名称和值,对象可以被看作是一组属性的集合。
用对象字面量语法来定义一个对象时,会自动初始化一组属性。(也就是说,如果你定义了一个对象,var a = {},那么a就会自动有 a.hasOwnProperty 及 a.constructor 等属性和方法。)而后,这些属性还可以被增减。
属性的值可以是任意类型,包括具有复杂数据结构的对象。属性以字符串或者 Symbol 为 key,以数据属性特征值或者访问器属性特征值为 value。
先来说第一类属性,数据属性也就是数据描述符。
- value:就是属性的值。
- writeable:决定属性能否被赋值。
- enumerble:决定 for in 能否枚举该属性。
- configurable:决定该属性能否被删除或者改变特征值。
第二类属性,访问器属性也就是存取描述符
- getter:函数或 undefined,在取属性值时被调用。
- setter:函数或 undefined,在设置属性值时被调用。
- enumerble:决定 for in 能否枚举该属性。
- configurable:决定该属性能否被删除或者改变特征值。
访问器属性使得属性在读和写时执行代码,它允许使用者在写和读属性时,得到完全不同的值。
var o = {
a: 7,
get b() {
return this.a + 1;
},
set c(x) {
this.a = x / 2
}
};
console.log(o.a); // 7
console.log(o.b); // 8
o.c = 50;
console.log(o.a); // 25
我们可以使用内置函数 Object.getOwnPropertyDescripter 来查看对象属性,如以下代码所示:
var o = { a: 1 };
o.b = 2;
//a 和 b 皆为数据属性
Object.getOwnPropertyDescriptor(o,"a") // {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o,"b") // {value: 2, writable: true, enumerable: true, configurable: true}
如果我们要想改变属性的特征,或者定义访问器属性,我们可以使用 Object.defineProperty,示例如下:
var o = { a: 1 };
Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true});
//a 和 b 都是数据属性,但特征值变化了
Object.getOwnPropertyDescriptor(o,"a"); // {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o,"b"); // {value: 2, writable: false, enumerable: false, configurable: true}
o.b = 3;
console.log(o.b); // 2
有没有发现什么很熟悉,Object.defineProperty 。
vue目前的双向数据绑定就是通过 Object.defineProperty 改变 get 和 set 在里面添加 observer 来实现的。
还有其实 Object.freeze(obj) 就是改变obj的 writable,configurable 为 false