1. 什么是面向对象

    1. Object,在英文中,是一切事务的总成,和面向对象编程的抽象思维有互通之处。
    2. 人类思维下的对象:

      对象这一概念在人类的幼儿期形成,远早于变成逻辑中常用的值、过程等概念。 在幼年期,我们先认识到某一个苹果能吃(这里的某一个苹果就是一个对象),继而认识到所有的苹果都可以吃(这里的所有苹果,就是一个类),再到后来才意识到三个苹果和三个梨之间的联系,进而产生数字”3”(值)的概念。

    1. 《面向对象如分析与设计》中,Grady Booch总结,认为对象应该是下列事物之一:
      • 一个可以触摸或者可以看见的东西
      • 人的智力可以理解的东西
      • 可以知道思考或行动(进行想象或施加动作)的东西。

    2. JavaScript对象的特征

    1. 总结来看,对象具有如下几个特点:
      • 对象具有唯一的标识性:即使完全相同的两个对象,也并非同一个对象。
      • 对象有状态:对象具有状态,同一对象可能处于不同状态之下。
      • 对象具有行为:即对象的状态,可能因为它的行为产生变迁。
    2. 第一个特征-对象具有唯一的标识性:

      1. 一般而言,各种语言的对象唯一标识性都是用内存地址来体现的,对象具有唯一标识的内存地址,所以具有唯一的标识。
      2. 所以任何不同的JavaScript对象其实是互不相等的,如下:
        1. var o1 = { a: 1 };
        2. var o2 = { a: 1 };
        3. console.log(o1 == o2); //false
    3. 第二第三个特征-状态和行为,不用语言会用不同的术语抽象描述他们,比如C++中称他们为“成员变量”和“成员函数”,Java中称为“属性”和“方法”。
      在JavaScript中,将状态和行为统一抽象为属性,考虑到JavaScript中将函数设计成一种特殊的对象,所以JavaScript中的行为和状态都能用属性来抽象。
      下面代码就是展示了普通属性和函数作为属性的一个例子,其中o是对象,d是一个属性,而函数f也是一个属性,虽然写法不一样,但对JavaScript来说,d和f就是两个普通属性。

      1. var o = {
      2. d: 1,
      3. f() {
      4. console.log(this.d);
      5. }
      6. };
    4. 总结来看:JavaScript中,对象的状态和行为其实都被抽象为了属性。Java和它设计思路虽然有一定的差别,但是二者都很好地表现了对象的基本特征:标识性、状态和行为。

    5. 在实现对象基本特征的基础上,JavaScript中对象独有的特色是:对象具有高度的动态性,这是因为JavaScript赋予了使用者在运行时为对象添改状态和行为的能力。
      比如,JavaScript允许运行时向对象添加属性,这就跟绝大多数基于类的、静态的对象设计完全不同。比如Java。
      下面代码展示了运
      行时向一个对象添加属性,一开始定义了一个对象o,定义完成之后,再添加属性b,这样是没问题的:
      1. var o = { a: 1 };
      2. o.b = 2;
      3. console.log(o.a, o.b); // 1 2


    为了提高抽象能力,JavaScript的属性被设计成比别的语言更加复杂的形式,它提供了数据属性和访问器属性(getter/setter)两类。

    3. JavaScript对象的两类属性

    1. 对JavaScript来说,属性并非知识简单的名称和值,JavaScript用一组特征(attribute)来描述属性(property)。
    2. 第一类属性:数据属性。他比较接近于其他语言的属性概念,数据属性具有四个特征:
      • 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}

    1. `Object.defineProperty````javascript
    2. var o = { a: 1 };
    3. Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true});
    4. // a 和 b都是数据属性,但特征值变化了
    5. Object.getOwnPropertyDescriptor(o, "a"); // {value: 1, writable: true, enumerable: true, configurable: true}
    6. 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. 结语

    1. 理解JavaScript的对象,必须回到人类对象的朴素认知和面向对象的语言无关基础理论,我们就能够李杰JavaScript面向对象设计的思路。