【四】JavaScript对象:面向对象还是基于对象?
2019-02-12 本文已影响0人
alanwhy
提出问题
- 为什么 JavaScript(直到 ES6)有对象的概念,但是却没有像其他的语言那样,有类的概念呢
- 为什么在JS对象里可以自由添加属性,而其他语言却不可以呢?
明确定义
- JS标准中是这样定义的:语言和宿主的基础设施由对象来提供,并且JS程序即是一系列互相通讯的对象集合。
什么是对象
Object即对象,指一切事物的总称,这里和面向对象编程的抽象思维有互通之处
在《面向对象分析与设计》中,作者Grady Booch 给出了定义:
1.一个可以接触或者可以看见的东西;
2.人的智力可以理解的东西;
3.可以指导思考或者行动(进行想象或施加动作)的东西;
JS对象的特征
- 对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象
代码如下:
var o1 = { a: 1 };
var o2 = { a: 1 };
console.log(o1 == o2); // false
- 对象有状态:对象具有状态,同一对象可能处于不同状态之下
在JS中状态和行为统一抽象为“属性”,考虑到JS中将函数设计成一种特殊对象,所以JS中的行为和状态都能用属性来抽象
代码如下:
var o = {
d: 1,
f() {
console.log(this.d);
}
};
- 对象具有行为:即对象的状态,可能因为它的行为产生变迁
JS中的对象独有的特色就是它的对象具有高度的动态性,这是因为JS赋予了使用者在运行时为对象添改状态和行为的能力。
代码如下:
var o = { a: 1 };
o.b = 2;
console.log(o.a, o.b); //1 2
为了提高抽象能力,JS提供了数据属性和访问器属性(getter/setter)两类
JS对象的两类属性
JS用一组特征来描述属性。
- 数据属性
- 访问器属性
首先是数据属性:
- value:属性的值
- writable:决定属性能否被赋值
- enumerable:决定for in 能否枚举该属性
- configurable:决定该属性能否被删除或者改变特征值
第二类:访问器属性
- getter:函数或者undefined,在取属性值时被调用
- setter:函数或者undefined,在设置属性值时被调用
- enumerable:决定for in 能否枚举该属性
- configurable:决定该属性能否被删除或者改变特征值
通常来说:我们定义属性的代码会产生数据属性,其中的writable、enumerable、configurable都默认是true
代码:
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