JavaScript Prototypes原型


JavaScript是一种基于原型的语言,因此理解原型对象是JavaScript从业者需要知道的最重要的概念之一。本文将通过各种示例简要概述Prototype对象。在阅读本文之前,您需要对JavaScriptthis引用有一个基本的了解。

原型对象

为清楚起见,我们来看一下以下示例:

function Point2D(x, y) {
  this.x = x;
  this.y = y;
 }

当声明Point2D函数时,将为它创建一个名为prototype的默认属性(请注意,在JavaScript中,函数也是一个对象)。 prototype属性是一个包含constructor属性的对象,其值为Point2D函数: Point2D.prototype.constructor = Point2D 。当您使用new关键字调用Point2D时, 新创建的对象将继承 Point2D.prototype 所有属性 。要检查这一点,您可以将名为move的方法添加到Point2D.prototype ,如下所示:

Point2D.prototype.move = function(dx, dy) {
  this.x += dx;
  this.y += dy;
 }

 var p1 = new Point2D(1, 2);
 p1.move(3, 4);
 console.log(p1.x); // 4
 console.log(p1.y); // 6

Point2D.prototype被称为原型对象p1对象的原型 ,以及用new Point2D(...)语法创建的任何其他对象。您可以根据需要向Point2D.prototype对象添加更多属性。常见的模式是Point2D.prototype声明方法,其他属性将在构造函数中声明。

JavaScript中的内置对象以类似的方式构造。例如:

  • 使用new Object(){}语法创建的对象的原型是Object.prototype
  • 使用new Array()[]语法创建的数组的原型是Array.prototype
  • 等等其他内置对象,如DateRegExp

Object.prototype由所有对象继承,并且没有原型(其原型为null )。

原型链

原型链机制很简单:当您访问对象obj上的属性p时,JavaScript引擎将在obj对象中搜索此属性。如果引擎无法搜索,它会继续搜索obj对象的原型,依此类推,直到达到Object.prototype 。如果在搜索完成后,没有找到任何结果,则结果将是undefined 。 例如:

var obj1 = {
  a: 1,
  b: 2
 };

 var obj2 = Object.create(obj1);
 obj2.a = 2;

 console.log(obj2.a); // 2
 console.log(obj2.b); // 2
 console.log(obj2.c); // undefined

在上面的代码片段中,语句var obj2 = Object.create(obj1)将使用原型obj1对象创建obj2对象。换句话说,默认情况下, obj1成为obj2的原型而不是Object.prototype 。如您所见, b不是obj2的属性,您仍然可以通过原型链访问它。但是,对于c属性,您将获得undefined值,因为它无法在obj1Object.prototype找到。

在ES2016中,我们现在可以使用Class关键字以及上面提到的方法来操作prototype 。 JavaScript Class吸引了来自OOP背景的开发人员,但它基本上与上面做了同样的事情。

class Rectangle {
  constructor(height, width) {
    this.height = height
    this.width = width
  }

  get area() {
    return this.calcArea()
  }

  calcArea() {
    return this.height * this.width
  }
 }

 const square = new Rectangle(10, 10)

 console.log(square.area) // 100

这基本上与以下相同:

function Rectangle(height, width) {
  this.height = height
  this.width = width
 }

 Rectangle.prototype.calcArea = function calcArea() {
  return this.height * this.width
 }

类中的gettersetter方法将Object属性绑定到将在查找该属性时调用的函数。这只是语法糖,有助于更容易_查找_或_设置_属性。

更多JavaScript教程

学习更多JavaScript教程