什么是面向对象
  1. 一个可以触摸或者可以看见的东西
  2. 人的智力可以理解的东西
  3. 可以指导思考或行动(进行想象或施加动作)的东西

最为成功的描述对象的流派是基于“类”,比如Java和C++

JS选择了原型来实现类,但是因为公司的政治原因和当年Java的火爆,管理层要求JS之父Brendan Eich模仿Java,于是JS也加入了new、this等特性

对象有以下三个特点

  1. 对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。
  2. 对象有状态:对象具有状态,同一对象可能处于不同状态之下。
  3. 对象具有行为:即对象的状态,可能因为它的行为产生变迁。

首先对象具有唯一标识性。JS中不同的对象是不相等的,即便它们长得一摸一样,但是指向的地址不同

 let o1 = { a: 1 };    
 let o2 = { a: 1 };    
 console.log(o1 === o2); // false复制代码

关于特征和行为。不同的语言有不同的描述方式

C++中称为成员变量和成员函数,Java中称为属性和方法,JS中,统一称为属性

JS的对象

JavaScript满足了对象的三个基本特征,同时又有着自己的特色

JavaScript的对象具有高度动态性,可以在运行时为对象添加状态和行为

//定义完再添加let o={a:1}
o.b=2复制代码

JavaScript对象具有两类属性

  1. 数据属性
  • value:就是属性的值。
  • writable:决定属性能否被赋值。
  • enumerable:决定 for in 能否枚举该属性。
  • configurable:决定该属性能否被删除或者改变特征值。
访问器属性
  • getter:函数或 undefined,在取属性值时被调用。
  • setter:函数或 undefined,在设置属性值时被调用。
  • enumerable:决定 for in 能否枚举该属性。
  • configurable:决定该属性能否被删除或者改变特征值。

writable、enumerable、configurable都默认为true,可以用getOwnPropertyDescriptor查看

   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复制代码

JavaScript对象的运行时其实就是一个属性的集合,属性以字符串或者Symbol为key,对象是一个属性的索引结构

总结

JavaScript的对象设计与主流的基于类的对象的差异很大,所以会有JavaScript不是面向对象之争。但是JavaScript提供了完全运行时的对象系统,所以它可以模仿多数面向对象编程范式,所以它是正统的面向对象语言