1. 什么是面向对象
- Object,在英文中,是一切事务的总成,和面向对象编程的抽象思维有互通之处。
- 人类思维下的对象:
对象这一概念在人类的幼儿期形成,远早于变成逻辑中常用的值、过程等概念。 在幼年期,我们先认识到某一个苹果能吃(这里的某一个苹果就是一个对象),继而认识到所有的苹果都可以吃(这里的所有苹果,就是一个类),再到后来才意识到三个苹果和三个梨之间的联系,进而产生数字”3”(值)的概念。
- 《面向对象如分析与设计》中,Grady Booch总结,认为对象应该是下列事物之一:
- 一个可以触摸或者可以看见的东西
- 人的智力可以理解的东西
- 可以知道思考或行动(进行想象或施加动作)的东西。
2. JavaScript对象的特征
- 总结来看,对象具有如下几个特点:
- 对象具有唯一的标识性:即使完全相同的两个对象,也并非同一个对象。
- 对象有状态:对象具有状态,同一对象可能处于不同状态之下。
- 对象具有行为:即对象的状态,可能因为它的行为产生变迁。
第一个特征-对象具有唯一的标识性:
- 一般而言,各种语言的对象唯一标识性都是用内存地址来体现的,对象具有唯一标识的内存地址,所以具有唯一的标识。
- 所以任何不同的JavaScript对象其实是互不相等的,如下:
var o1 = { a: 1 };
var o2 = { a: 1 };
console.log(o1 == o2); //false
第二第三个特征-状态和行为,不用语言会用不同的术语抽象描述他们,比如C++中称他们为“成员变量”和“成员函数”,Java中称为“属性”和“方法”。
在JavaScript中,将状态和行为统一抽象为属性
,考虑到JavaScript中将函数设计成一种特殊的对象,所以JavaScript中的行为和状态都能用属性来抽象。
下面代码就是展示了普通属性和函数作为属性的一个例子,其中o是对象,d是一个属性,而函数f也是一个属性,虽然写法不一样,但对JavaScript来说,d和f就是两个普通属性。var o = {
d: 1,
f() {
console.log(this.d);
}
};
总结来看:JavaScript中,对象的状态和行为其实都被抽象为了属性。Java和它设计思路虽然有一定的差别,但是二者都很好地表现了对象的基本特征:标识性、状态和行为。
- 在实现对象基本特征的基础上,JavaScript中对象独有的特色是:对象具有高度的动态性,这是因为JavaScript赋予了使用者在运行时为对象添改状态和行为的能力。
比如,JavaScript允许运行时向对象添加属性,这就跟绝大多数基于类的、静态的对象设计完全不同。比如Java。
下面代码展示了运
行时向一个对象添加属性,一开始定义了一个对象o,定义完成之后,再添加属性b,这样是没问题的:var o = { a: 1 };
o.b = 2;
console.log(o.a, o.b); // 1 2
为了提高抽象能力,JavaScript的属性被设计成比别的语言更加复杂的形式,它提供了数据属性和访问器属性(getter/setter)两类。
3. JavaScript对象的两类属性
- 对JavaScript来说,属性并非知识简单的名称和值,JavaScript用一组特征(attribute)来描述属性(property)。
- 第一类属性:数据属性。他比较接近于其他语言的属性概念,数据属性具有四个特征:
- value:就是属性的值。
- writable:决定属性能否被赋值。
- enumerable:决定for in能否枚举该属性。
- configurable:决定该属性能否被删除或者改变特征值。
3. 第二类属性:访问器(getter/setter)属性,它也有四个特征。 - getter:函数或undefined,在取属性值时被调用。
- setter:函数或undefined,在设置属性值时被调用。
- enumerable:决定for in能否枚举该属性。
- configurable:决定该属性能否被删除或者改变特征值。
`Object.getOwnPropertyDescripter````javascript 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````javascript
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: fasle, configurable: true}
javascript
var o = { get a() {return 1 } };
console.log(o.a); // 1
4. 结语
- 理解JavaScript的对象,必须回到人类对象的朴素认知和面向对象的语言无关基础理论,我们就能够李杰JavaScript面向对象设计的思路。