Javascript 原型和继承(Prototypes and Inheritance)

  JavaScript 对象从一个原形对象(prototype object) 继承属性。所有对象都有原型;原型的所有属性看上去就像使用它作为原型的那些对象的属性一样。简单的说就是:所有对象都从他的原型继承属性

  (each object inherits properties from its prototype).

  对象的 prototype 通过它的 constructor function 来定义。JavaScript 里所有的 function 都有一个 prototype 属性。这个属性开始是空的,接下来你给他添加的任何属性都会被 constructor 创建的对象所拥有。

  prototype 对象和 constructor 相关联。这意味着 prototype 可以作为放置方法以及其他常量的理想场所。原型中的属性不会被复制到新创建的对象中去,他们的属性看上去就像对象的属性一样。这意味着,使用原型能够大幅度的减少多个同类对象占用的内存。

  每一个 class 都只有一个 prototype object, 附带一套属性。但我们在运行时可能会创建多个类的实例。那么如果发生对原型的属性的读写会发生什么情况?

  当你读一个属性的时候,JavaScript 首先尝试去查找对象本身是否有这个属性,如果没有,接着去查找原型里面是否有。有的话就返回结果。

  而当你写原型的属性的时候,因为多个对象共享原型,显然是不能直接在原型上进行写操作的。这个时候实际上 JavaScript 会在对象上创建一个同名的属性,然后把值写到里面。当你下次读这个属性的时候,JavaScript 一下子就在对象的属性里查找到了,那么就不需要去原型里查找了。这个时候,我们说“对象的属性掩盖或隐藏了原型的属性”。(shadows or hides) 。

  从上面讨论看出,其实我们在设计类的时候,只要掌握一个原则:在原型里仅定义一些方法(方法一般是不会变的),常数,常量等。做到这一点就不容易混淆了。

  例子:

Javascript 原型和继承(Prototypes and Inheritance)

  // Define a constructor method for our class.

Javascript 原型和继承(Prototypes and Inheritance)

  // Use it to initialize properties that will be different for

Javascript 原型和继承(Prototypes and Inheritance)

  // each individual Circle object.

Javascript 原型和继承(Prototypes and Inheritance)

  functionCircle(x, y, r)

Javascript 原型和继承(Prototypes and Inheritance)

  {

Javascript 原型和继承(Prototypes and Inheritance)

      this.x = x;  // The X-coordinate of the center of the circle

Javascript 原型和继承(Prototypes and Inheritance)

  this.y = y;  // The Y-coordinate of the center of the circle

Javascript 原型和继承(Prototypes and Inheritance)

  this.r = r;  // The radius of the circle

Javascript 原型和继承(Prototypes and Inheritance)

  }

Javascript 原型和继承(Prototypes and Inheritance)

Javascript 原型和继承(Prototypes and Inheritance)

Javascript 原型和继承(Prototypes and Inheritance)

  // Create and discard an initial Circle object.

Javascript 原型和继承(Prototypes and Inheritance)

  // This forces the prototype object to be created in JavaScript 1.1.

Javascript 原型和继承(Prototypes and Inheritance)

  new Circle(0,0,0);

Javascript 原型和继承(Prototypes and Inheritance)

Javascript 原型和继承(Prototypes and Inheritance)

Javascript 原型和继承(Prototypes and Inheritance)

  // Define a constant: a property that will be shared by

Javascript 原型和继承(Prototypes and Inheritance)

  // all circle objects. Actually, we could just use Math.PI,

Javascript 原型和继承(Prototypes and Inheritance)

  // but we do it this way for the sake of instruction.

Javascript 原型和继承(Prototypes and Inheritance)

  Circle.prototype.pi =

  3.14159;

Javascript 原型和继承(Prototypes and Inheritance)

Javascript 原型和继承(Prototypes and Inheritance)

Javascript 原型和继承(Prototypes and Inheritance)

  // Define a method to compute the circumference of the circle.

Javascript 原型和继承(Prototypes and Inheritance)

  // First declare a function, then assign it to a prototype property.

Javascript 原型和继承(Prototypes and Inheritance)

  // Note the use of the constant defined above.

Javascript 原型和继承(Prototypes and Inheritance)

  function Circle_circumference(  ) { return

  2

  *

  this.pi *

  this.r; }

Javascript 原型和继承(Prototypes and Inheritance)

  Circle.prototype.circumference =Circle_circumference;

Javascript 原型和继承(Prototypes and Inheritance)

Javascript 原型和继承(Prototypes and Inheritance)

Javascript 原型和继承(Prototypes and Inheritance)

  // Define another method. This time we use a function literal to define

Javascript 原型和继承(Prototypes and Inheritance)

  // the function and assign it to a prototype property all in one step.

Javascript 原型和继承(Prototypes and Inheritance)

  Circle.prototype.area =

  function(  ) { return

  this.pi *

  this.r *

  this.r; }

Javascript 原型和继承(Prototypes and Inheritance)

Javascript 原型和继承(Prototypes and Inheritance)

Javascript 原型和继承(Prototypes and Inheritance)

  // The Circle class is defined.

Javascript 原型和继承(Prototypes and Inheritance)

  // Now we can create an instance and invoke its methods.

Javascript 原型和继承(Prototypes and Inheritance)

  var c =

  new Circle(0.0, 0.0, 1.0);

Javascript 原型和继承(Prototypes and Inheritance)

  var a =c.area(  );

Javascript 原型和继承(Prototypes and Inheritance)

  var p = c.circumference(  );

  内置的类的 prototype.

  不光是用户自定义的类可以有 prototype. 系统内置的类比如 String, Date 也都有的。而且你可以向他们添加新的方法,属性等。

  下面这段代码就对所有的 String 对象添加了一个有用的函数:

Javascript 原型和继承(Prototypes and Inheritance)

  // Returns true if the last character is c

Javascript 原型和继承(Prototypes and Inheritance)

  String.prototype.endsWith =

  function(c) {

Javascript 原型和继承(Prototypes and Inheritance)

      return (c ==

  this.charAt(this.length-1))

Javascript 原型和继承(Prototypes and Inheritance)

  }

  然后我们就可以类似这样的来调用了:

Javascript 原型和继承(Prototypes and Inheritance)

  var message =

  "hello world";

Javascript 原型和继承(Prototypes and Inheritance)

  message.endsWith('h')  // Returns false

Javascript 原型和继承(Prototypes and Inheritance)

  message.endsWith('d')  // Returns true