2011-05-12 135 views
4

比方說,我有這樣的事情在一個名爲main.js文件:如何正確擴展JS對象?

function obj_name() {} 

obj_name.prototype = { 
    foo : function() { alert('hi!'); }, 
    foo2 : function() { alert('hi again!'); } 
} 

現在我試圖展開對象在另一個文件中extend.js這樣:

obj_name.prototype = { 
    newfoo : function() { alert('hi #3'); } 
} 

...但問題是,它會工作,如果我這樣編碼:

obj_name.prototype.newfoo = function() { alert('hi #3'); } 

我想這可能是一個菜鳥問題。我甚至不知道這是否是擴展對象的正確方法,但我在這裏驚訝地想知道爲什麼會發生這種情況。

謝謝你們提前。

回答

4

第一種方法是用新的原型替換原型(覆蓋之前的原型)。第二種方法是,您在原型中添加一個新成員(從而擴展它)。還有另一種方法:一個庫有一個extend方法或類似的方法(它基本上將你在第二個窗體中做的事情封裝在一個漂亮的包裝中)。例如,在jQuery

$.extend(obj_name.prototype, { 
    newfoo : function() { alert('hi #3'); } 
} 
+0

感謝您的回答! – novato 2011-05-12 08:47:56

4

這是因爲該行

obj_name.prototype = { 
    newfoo : function() { alert('hi #3'); } 
} 

您創建一個新的原型對象,刪除privous內容。這是因爲如果你說

var a = {}; 

當你喜歡

obj_name.prototype.newfoo = function() { alert('hi #3'); } 

擴展對象,它只是增加一個新的屬性(newfoo)對象樹保持現有內容不變。這就是爲什麼它的工作原理

HTH

伊沃Stoykov

+0

謝謝。我想這是公平的,我把Amadan的答案設定爲我接受的答案。 – novato 2011-05-12 08:56:01

+0

+1對於不需要JQuery的人來做簡單的事情。 – Jonathan 2013-07-24 16:00:14

+0

感謝喬納森:-) – i100 2013-08-13 12:53:16

5

另一種選擇沒有jQuery的:

var extend = function(destination, source) 
{ 
    for (var property in source) 
    { 
     if (destination[property] && (typeof(destination[property]) == 'object') 
       && (destination[property].toString() == '[object Object]') && source[property]) 
      extend(destination[property], source[property]); 
     else 
      destination[property] = source[property]; 
    } 
    return destination; 
} 

var a = {a: 'test'};        // original 
var b = {newFoo: function() { alert('hi #3'); }}; // the addition 
extend(a, b);         // extend it 
a.newFoo();         // call the added property 
+0

我想這是一個錯字,對吧?代碼中的YG是什麼? – novato 2011-05-12 09:01:24

+0

我的不好,是的;)希望有幫助, – tradyblix 2011-05-12 09:04:03

+0

它呢,謝謝! – novato 2011-05-12 09:04:19

1

如果你正在尋找,讓你正是這個簡單的輕量級庫:OOP「在JavaScript中完成「,看看這個:https://github.com/haroldiedema/joii

在github頁面自述文件中提供的源代碼示例,以及這些鏈接S:

這個庫基本上可以讓你定義 「類」 爲這樣的:

var Person = Class(function() { 
    this.firstname = "John" 
    this.surname = "Smith" 
    this.role= "Developer" 

    this.getInfo = function() { 
     return this.firstname + ' ' + this.surname + ' is ' + this.role; 
    }; 
}); 

var AnotherPerson = Class({ extends: Person }, function() { 
    this.firstname = "Bob"; 
}); 

var p = new AnotherPerson(); 
console.log(p.getInfo()); 
// Bob Smith is Developer 

編輯

爲了把你的代碼作爲例如,但轉換成JOII兼容的代碼,它會看起來正是這樣:

var obj_name = Class(function() { 
    this.foo = function() { alert('hi!'); }; 
    this.foo2 = function() { alert('hi again!'); }; 
}; 

var obj_name2 = Class({ extends: obj_name }, function() { 
    this.newfoo = function() { alert('hi #3'); }; 
}); 

var o = new obj_name2(); 
o.foo(); // hi! 
o.newfoo(); // hi #3 

或將其作爲一個mix-in:

var o = new obj_name(); 
o.mixin(obj_name2); 

o.newfoo(); // hi #3 

或者反過來,用 「特質」。

// the "uses" option basically copies content from the given object to the scope of your "class", solving the horizontal code-reuse problem. 
var obj_name = Class({ uses: [obj_name2], function() { 
    this.foo = function() { alert('hi!'); }; 
    this.foo2 = function() { alert('hi again!'); }; 
}); 

var o = new obj_name(); 
o.newfoo(); // hi #3