Skip to content
导航

类和原型

JavaScript没有类,但是可以通过原型,以及ES6的语法糖class模拟类的实现。

原型

原型是 JavaScript 对象相互继承特性的机制。

指向原型对象的属性是__proto__,访问对象原型的标准方法是getPrototypeOf()

js
Object.getPrototypeOf(obj) === Object.prototype
obj.__proto__ === Object.prototype

区别与联系:

  • prototype是构造函数上的属性
  • __proto__是对象上的非标准属性
  • 它俩指向同一个原型对象

原型对象本身是一个对象,故原型对象也会有它自己的原型,逐渐构成了原型链null是原型链的末尾。

继承

在传统的面向对象编程中,类是继承的基础。
JavaScript 中没有类,也就没有类的继承。
但可以基于原型链实现继承,是通过让一个对象继承另一个对象的属性和方法来实现的。

构造函数

对象类型 = 类 = 用于创建对象的模板。创建“对象类型”的方法是使用对象构造函数。

在上一节示例代码中,Objectobj的构造函数.

定义一个构造函数:

js
function Box(value){ //首字母大写是一种约定实践,不是必须
  this.value = value
}

在构造函数中,this指代被创建的新对象实例。

js
Object.prototype.constructor === Object === obj.constructor

上述等式不能推导出 obj === Object.prototype,仅仅是不同对象有个 constructor 属性指向相同构造函数 Object

new运算符

创建一个具有构造函数的对象类型的实例。

js
new Constructor[([arguments])]

(arguments)是可选的,new Object等价于new Object()

new运算符做了以下事情:

js
var obj = {}
Object.setPrototypeOf(obj, Constructor.prototype)
var result = Constructor.apply( obj, arguments ) || obj
result.constructor = Constructor
return result

在实现继承这个概念上,JavaScript是鸭式辨型的。
换句话说,只要能达成和继承一样的效果,不管用的什么方法,都是实现了“继承”。

鸭式辨型:如果看起来像、走起路来像、叫起声来像鸭子,那么它就是鸭子

js
class Box {
  constructor(value) {
    this.value = value;
  }

  // 在 Box.prototype 上创建方法
  getValue() {
    return this.value;
  }
}

类是构造函数的语法糖,这意味着你仍然可以修改 Box.prototype 来改变所有实例的行为。

参考资料