JavaScript:面向对象与原型

一、什么是面向对象

  对象并不是计算机领域凭空造出来的概念,它是顺着人类思维模式产生的一种抽象,面向对象编程也被认为是:更接近人类思维模式的一种编程范式。

  对象有如下几个特征:

  1. 对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。各种语言的对象唯一标识性都是用内存地址来体现的
  2. 对象有状态:同一对象可能处于不同状态之下。
  3. 对象具有行为:对象的状态,可能因为它的行为产生变迁

  在JavaScript中,任何不同的 JavaScript 对象其实是互不相等的。关于对象的“状态和行为”,JavaScript 中的行为和状态都能用属性来抽象。

  JavaScript还有其独有的特点:对象具有高度的动态性,这是因为 JS 赋予了使用者在运行时为对象添改状态和行为的能力。

  JavaScript有两种属性:数据属性和访问器属性。

  数据属性:

  • value:就是属性的值。
  • writable:决定属性能否被赋值。
  • enumerable:决定 for in 能否枚举该属性。
  • configurable:决定该属性能否被删除或者改变特征值。

  访问器属性:(创建对象时可以使用get和set关键字来创建访问器属性)

  • getter:函数或 undefined,在取属性值时被调用。
  • setter:函数或 undefined,在设置属性值时被调用。
  • enumerable:决定 for in 能否枚举该属性。
  • configurable:决定该属性能否被删除或者改变特征值。

二、JavaScript的原型系统

  在不同的编程语言中,设计者也利用各种不同的语言特性来抽象描述对象。最为成功的流派是使用“类”的方式来描述对象,这诞生了诸如 C++、Java 等流行的编程语言。这个流派叫做基于类的编程语言。还有一种就是基于原型的编程语言,它们利用原型来描述对象,比如JavaScript。

  • “基于类”的编程提倡使用一个关注分类和类之间关系开发模型。
  • “基于原型”的编程看起来更为提倡程序员去关注一系列对象实例的行为,而后才去关心如何将这些对象,而不是将它们分成类。

  从 ES6 开始,JavaScript 提供了 class 关键字来定义类,这样的方案仍然是基于原型运行时系统的模拟

  JavaScript 的原型:如果所有对象都有私有字段 [[prototype]],就是对象的原型;读一个属性,如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找到为止。

  

  从 ES6 以来,JavaScript 提供了一系列内置函数,以便更为直接地访问操纵原型。三个方法分别为:

  • Object.create 根据指定的原型创建新对象,原型可以是null;
  • Object.getPrototypeOf 获得一个对象的原型。
  • Object.setPrototypeOf 设置一个对象的原型。

  

  在 ES3 和之前的版本中,“类”的定义是一个私有属性 [[class]],其访问方式是 Object.prototype.toString。

  在 ES5 开始,[[class]] 私有属性被 Symbol.toStringTag 代替,Object.prototype.toString 的意义从命名上不再跟 class 相关。

  

  new 操作在创建对象的时候具体做了哪些事情:

  1. 以构造器的 prototype 属性(注意与私有字段 [[prototype]] 的区分)为原型,创建新对象;
  2. 将 this 和调用参数传给构造器,执行;
  3. 如果构造器返回的是对象,则返回,否则返回第一步创建的对象。

  new 这样的行为,试图让函数对象在语法上跟类变得相似,但是,它客观上提供了两种方式,一是在构造器中添加属性,二是在构造器的 prototype 属性上添加属性。

  ES6 中引入了 class 关键字,并且在标准中删除了所有 [[class]] 相关的私有属性描述,类的概念正式从属性升级成语言的基础设施,从此,基于类的编程方式成为了 JavaScript 的官方编程范式。我们通过 get/set 关键字来创建 getter,通过括号和大括号来创建方法,数据型成员最好写在构造器里面。

猜你喜欢

转载自www.cnblogs.com/zjp-zxy/p/10861357.html