[設計模式] JavaScript 之 原型模式 : Object.create 與 prototype
1. Object.create 1>. 定義: 建立一個可指定原型對象的並可以包含可選自訂屬性的對象; 2> Object.create(proto [, properties]); 可選,用於配置新對象的屬性; 複製代碼1. proto: 要建立新對象的 原型,必須,可為 null; 這個 proto 要是已經建立的[new過],或 對象.prototype 才有價值;2. properties: 可選,結構為:{ propField: { value: 'val'|{}|function(){}, writable: true|false, enumerable: true|false, configurable: true|false, get:function(){return 10}, set:function(value){} }}自定的屬性有以下的四種本置屬性:value: 自訂屬性值;writable: 該項值是否可編輯,預設為 false, 當為 true 時,obj.prodField 可賦值;否則唯讀;enumerable: 可枚舉; confirurable: 可配置; 還可以包含 set, get 訪問器方法; 其中,[set, get] 與 value 和 writable 不能同時出現;複製代碼1. 建立原型對象類: function ProtoClass(){ this.a = 'ProtoClass'; this.c = {}; this.b = function() { }}建立原型方法: ProtoClass.prototype.aMethod = function() { //this.a; //this.b(); return this.a;}使用方法 1. 以 ProtoClass.prototype 建立一個對象; var obj1 = Object.create(ProtoClass.prototype, { foo:{value: 'obj1', writable: true}})obj1 就具有 ProtoClass 原型方法 aMethod 的方法; obj1.aMethod();//就會輸出 undefined 方法可訪問,ProtoClass 成員無法訪問但是這種方法執行不到 ProtoClass 下 a, b, c 的成員屬性: 2. 採用 執行個體化的 ProtoClass 做原型: var proto = new ProtoClass(); var obj2 = Object.create(proto, { foo:{value:'obj2'}});這樣建立的 obj2 就具有 ProtoClass 的所有的成員屬性 a, b, c 以及 aMethod 原型方法; 並添加了一個 foo 唯讀 資料屬性; obj2.a; //ProtoClassobj2.c: //[Object]obj2.b(); // obj2.aMethod(); //ProtoClassobj2.foo; //obj23. 子類繼承: 複製代碼function SubClass() { }SubClass.prototype = Object.create(ProtoClass.prototype ,{ foo:{value: 'subclass'}}); SubClass.prototype.subMethod = function() { return this.a || this.foo;}複製代碼這種方法可以繼承 到 ProtoClass 的 aMethod 方法,執行; var func = new SubClass();func.aMethod() ;//undefined,讀不到 ProtoClass 的成員屬性,a,b,cfunc.subMethod();//subclass要讓 SubClass 能讀取到 ProtoClass 的成員屬性,SubClass 要改下: function SubClass(){ ProtoClass.call(this);} //其他代碼;這種方法就可以擷取 ProtoClass 的成員屬性及原型方法;: var func = new SubClass();func.aMethod() ;//ProtoClassfunc.subMethod();//ProtoClass還有一種方法,就是使用 執行個體化的 ProtoClass 對象,做為 SubClass 的原型; 複製代碼var proto = new ProtoClass(); function SubClass() {} SubClass.prototype = Object.create(proto, { foo:{value: 'subclass'}});複製代碼這樣 SubClass 執行個體化後,就可以擷取到 ProtoClass 所有的屬性及原型方法,以及建立一個唯讀資料屬性 foo; var func = new SubClass();func.foo; //subclassfunc.a; //ProtoClassfunc.b(); //func.c; //[Object]func.aMethod(); //ProtoClass4. 另外的建立繼承方法,跟 Object.create 使用 執行個體化的ProtoClass 做原型 效果一樣: function SubClass() { this.foo = 'subclass'; //不過這邊可讀寫} SubClass.prototype = new ProtoClass();Object.create 相關說明 Object.create 用於建立一個新的對象,當為 Object 時 prototype 為 null, 作用與 new Object(); 或 {} 一致; 當為 function 時,作用與 new FunctionName 一樣; 複製代碼//1 Objectvar o = {}//等同於var o2 = Object.create({});//兩者 constructor 一樣; //-----------------------------------------function func() { this.a = 'func';}func.prototype.method = function() { return this.a;} var newfunc = new func();//等同於[效果一樣]var newfunc2 = Object.create(Object.prototype/*Function.prototype||function(){}*/, { a: {value:'func', writable:true}, method: {value: function() {return this.a;} }});複製代碼但是 newfunc 與 newfunc2 在建立它們的對象的函數引用是不一樣的. newfunc 為 function func() {...},newfunc2 為 function Function { Native } Object.create(proto[, propertiesField]): proto 說明,該值為必須,可以為 null, 如果沒設定,將會拋出異常; proto 為非 null, 即為已 執行個體化的值,即已經 new 過的值;javaScript 中的 對象大多有 constructor 屬性,這個屬性說明 此對象是通過哪個函數執行個體化後的對象; propertiesField 為可選項,設定新建立對象可能需要的成員屬性或方法;