如何根據類名和參數建立對象

來源:互聯網
上載者:User

開發時遇到這樣的需求,希望通過一個類似factory的機制來建立對象,這個機制接收兩個參數,一個是對象所屬的類,另一個是參數數組,例如:

function getObject(cls, args){<br /> //....<br />}

 

這裡cls是一個類(即javascript函數),args是一個參數數組,例如[arg1, arg2, ....],希望這個函數返回的對象等同於下面代碼的效果:

new cls(arg1, arg2...);

 

容易想到,我們應該用apply方法,因為javascript中構建對象的過程就是執行建構函式的過程。而建構函式與普通函數性質完全一樣,只是它會被new關鍵字自動調用而已。apply方法接收2個對象,第一個是函數啟動並執行內容物件,即this對象。在這裡對象尚未構建,因此我們使用一個Null 物件:

 

function getObject(cls, args){<br /> var obj = {};<br /> cls.apply({}, args);<br /> return obj;<br />}

 

為驗證可行性,我們建立1個類:

function employee(name, age){<br /> this.name = name;<br /> this.age = age;<br />}

 

下面用getObject建立一個employee對象並確認其屬性:

var emp = getObject(employee, ['Jack', 26]);<br />alert(emp.name + ': ' + emp.age);

 

可以看到,正如我們所希望的,對象被正確建立。

 

但事情到此並沒有完。問題出在apply函數的第一個參數上:我們用了一個Null 物件。實際上起始物件不一定為空白。當empoyee的prototype也被定義時,就不為空白了,例如,我們通過prototype為employee增加一個方法:

 

empoyee.prototype.show = function(){<br /> alert(this.name + ': ' + emp.age);<br />}

 

再建立對象,並調用show方法:

var emp = getObject(employee, ['Jack', 26]);<br />emp.show();

 

會出錯,說show方法不存在,其原因就是我們只用到了emp的建構函式,卻沒用到其prototype。

 

實際上,根據javascript規範,new一個對象時,首先是以函數的prototype對象作為原型,在這個基礎上去調用建立新對象。因此我們需要修改getObject方法,讓apply以prototype為基礎。

 

但同時,不能直接以employee.prototype作為apply的第一個參數,因為那是直接修改了empoyee的原型。我們需要建立一份prototype的拷貝。如果用過dojo.delegate方法,我們應該知道複製對象最高效的做法,用其思路,來重寫getObject方法:

 

 

function getObject(cls, args){<br /> function _cls(){};<br /> _cls.prototype = cls.prototype;<br /> var obj = new _cls();<br /> cls.apply(obj, args);<br /> return obj;<br />}<br />//再執行如下代碼:<br />var emp = getObject(employee, ['Jack', 26]);<br />emp.show();

 

 

可以看到,show方法也被正確構建。這說明得到了正確的getObject方法。完整的例子可參見:

http://jsfiddle.net/V94Z2/

 

雖然這個需求的實現看似簡單,實際上它要求熟知javascript new關鍵字的工作原理,知其原理,我們就能成功的把對象的構建分成2個部分,一部分是prototype的複製,另一部分是建構函式的執行。用自己的代碼去實現這兩部分,就能實現我們需要的功能了。

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.