類的設計模式:實例化、繼承和(相對)多態。設計模式
JavaScript經過原型鏈,在兩個對象之間建立一個關聯。這樣,一個對象就能夠經過委託訪問另外一個對象的屬性和函數,從而達到「繼承」的實現。app
下面來看一個例子:函數
function Foo(name) { this.name = name; } Foo.prototype.myName = function () { return this.name; }; function Bar(name, label) { Foo.call(this, name); this.label = label; } Bar.prototype = new Foo(); //實現prototype的關聯 Bar.prototype.myLabel = function () { return this.label; }; var a = new Bar("a", "obj a"); a.myName(); // "a" a.myLabel(); // "obj a"
每一個函數都有一個prototype屬性,函數的prototype屬性指向了一個對象,這個對象正是調用該構造函數而建立的實例的原型。例子中Bar.prototype就是實例a的原型。this
這是每個JavaScript對象(除了 null )都具備的一個屬性,叫__proto__,這個屬性會指向該對象的原型。spa
a.__proto__ === Bar.prototype //true Bar.prototype.__proto__ === Foo.prototype //true
constructor,每一個原型都有一個 constructor 屬性指向關聯的構造函數。prototype
Foo === Foo.prototype.constructor
function objectFactory() { var obj = new Object(),Constructor = [].shift.call(arguments); obj.__proto__ = Constructor.prototype; var ret = Constructor.apply(obj, arguments); return typeof ret === 'object' ? ret : obj; };
下面介紹,另外兩種寫法:設計
var Foo = { init: function(name){ this.name = name; }, myName: function(){ return this.name; } }; var Bar = Object.create(Foo); Bar.setup = function(name, label){ // 委託調用 this.init(name); this.label = label; }; Bar.myLabel = function(){ return this.label; }; var a = Object.create( Bar ); a.setup("a", "obj a"); a.myName(); // "a" a.myLabel(); // "obj a"
Object.create = function (o) { var F = function () {}; F.prototype = o; return new F(); };
class Foo { constructor(name) { this.name = name; } myName() { return this.name; } } class Bar extends Foo { constructor(props, label) { super(props); this.label = label; } myLabel() { return this.label; } } var a = new Bar("a", "obj a"); a.myName(); // "a" a.myLabel(); // "obj a"