类定义了一些可以共享的属性和方法, 使得继承于这个类的子类, 或这个类的实例, 都拥有这些属性和方法, 能够实现相同的功能.

1. 原型:
JavaScript中, 类的实现基于原型机制. 所有的对象直接量都有同一个原型对象, 并通过 Object.prototype 获得对原型对象的引用. 通过 new + 构造函数创建的对象的原型就是构造函数 protype 属性的值, 所有的内置构造函数都具有一个继承自 Object.prototype 的原型. 下面代码的arr的原型是 Array.prototype, 它同时继承 Array.prototype 和 Object.prototype, 这就成了一条原型链. 对属性赋值先检查原型链, 它会在原始对象上创建属性, 或对已有的属性赋值, 而不会去修改原型链. var num = 1; var obj = new Object(); var arr = new Array(5);

2. 构造函数:
new + 构造函数可以直接创建一个新对象, 因此构造函数本身只需初始化这个对象的状态即可, 构造函数的 prototype 属性被用作新对象的原型. 当在花括号里重写预定义的 prototype, 这个新定义的原型对象就不含有 constructor属性了, 这时可以显示的添加一个构造函数, 也可以依次给prototype添加方法, 而不重写之. function Mesh( geometry, material ) {} var c = Mesh.prototype.constructor; console.log( c === Mesh ); // true Mesh.prototype = {}; var c2 = Mesh.prototype.constructor; console.log( c2 === Mesh ); // false Mesh.prototype = { constructor: Mesh; }; var c3 = Mesh.prototype.constructor; console.log( c3 === Mesh ); // true Mesh.prototype.funName = function(){}

3. 类的检测:
运用 instanceof 和 isPrototypeOf() 可以检测你要查找的对象是不是这个类, 从中也能检测到这些类都继承于 Object.prototype. 如要查询这个对象的类的构造函数, 使用 constructor. 但是, 用到 call() 来实现继承的, 不能检测到继承的父类. function Geometry() {} Geometry.prototype = { constructor: Geometry }; function BoxGeometry() { Geometry.call(this); } BoxGeometry.prototype.constructor = BoxGeometry; var g = new Geometry(), box = new BoxGeometry(); console.log( g instanceof Geometry ); // true console.log( box instanceof BoxGeometry ); // true console.log( box instanceof Geometry ); // false console.log( box instanceof Object ); // true console.log( Geometry.prototype.isPrototypeOf(g) ); // true console.log( BoxGeometry.prototype.isPrototypeOf(box) ); // true console.log( Geometry.prototype.isPrototypeOf(box) ); // false console.log( Object.prototype.isPrototypeOf(box) ); // true console.log( Object.getPrototypeOf(g) ); // Object { constructor: function Geometry() } console.log( Object.getPrototypeOf(box) ); // Object { constructor: function BoxGeometry() } console.log( g.constructor.name ); // Geometry console.log( box.constructor.name ); // BoxGeometry

4. 继承原型对象:
从上演示的代码可以检测到 box的 父类是 Object, 可却无法检测到 Geometry, 这不符合一般的逻辑呀. 为此, 必须确保子类的 prototype 也继承于父类的 prototype. 使用 Object.create() , 它是一个静态函数, 传入的第一个参数是原型对象. function Geometry() {} Geometry.prototype = { constructor: Geometry }; function BoxGeometry() {} BoxGeometry.prototype = Object.create( Geometry.prototype ); BoxGeometry.prototype.constructor = BoxGeometry; var g = new Geometry(), box = new BoxGeometry(); console.log( box instanceof Geometry ); // true console.log( Geometry.prototype.isPrototypeOf(box) ); // true

5. 继承属性和方法:
子类继承父类, 可以获取父类的属性和方法, 也可以对自身修改属性和重新方法, 而不会影响到父类. 子类 BoxGeometry 通过 Geometry.call(this)来获取父类 Geometry 中的 colors 属性, 通过 Object.create( Geometry.prototype ) 来获得调用父类中 center() 方法的权限. 如果没有实现对原型的继承, 执行 box.center() 会报错 —— TypeError: box.center is not a function. function Geometry() { this.colors = [ '0xfff000' ]; } Geometry.prototype = { constructor: Geometry, center: function(){ console.log('Put the geometry in the center.'); } }; function BoxGeometry() { Geometry.call(this); } BoxGeometry.prototype = Object.create( Geometry.prototype ); BoxGeometry.prototype.constructor = BoxGeometry; var g = new Geometry(), box = new BoxGeometry(); console.log( g.colors, box.colors ); // [ '0xfff000' ], [ '0xfff000' ] box.center(); // 'Put the geometry in the center.' box.colors = [ '0xfff000', '0x000fff' ]; console.log( g.colors, box.colors ); // [ '0xfff000' ], [ '0xfff000', '0x000fff' ]

6. 动态继承:
可随时对原型添加新方法来对类扩充功能. 下面的两个方法即是对 String 类的方法进行扩充, insert() 方法可实现在字符串的某个位置插入另一个字符串, splice() 方法则是模拟数组中的 splice() 方法, 在某处删除字符后又插入字符, 即对特定位置的字符进行替换. var str1 = '12345', str2 = 'abcd', s = ''; s = str1 + str2; console.log(s); // 12345abcd String.prototype.insert = function(start, str){ return this.substr(0, start) + str + this.substr(start); }; s = str1.insert(3, str2); console.log(s); // 123abcd45 String.prototype.splice = function(start, number, str){ return this.substr(0, start) + str + this.substr(start + number); }; s = str1.splice(1, 2, str2); console.log(s); // 1abcd45