2011-05-12 3 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

4

Это происходит потому, что в строке

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

создать новый объект-прототип, удаление privous содержимого. Это как если бы вы сказали

var a = {}; 

когда вы расширяете объект как

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

это просто добавить новое свойство (newfoo) в дереве объектов, сохраняя существующее содержимое нетронутым.Вот почему он работает

HTH

Иво Стойки

+0

Спасибо. Я думаю, справедливо, что я поставил ответ Амадана в качестве моего принятого ответа. – novato

+0

+1 для тех, кому не нужен JQuery, чтобы сделать что-то простое. – Jonathan

+0

спасибо Jonathan :-) – i100

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

+0

мой плохой, да;) надеюсь, что это поможет, тоже – tradyblix

+0

он делает, спасибо !! – novato

1

Если вы ищете простые легкие библиотеки, которая дает вам именно это: ООП " done right "в javascript, посмотрите на это: https://github.com/haroldiedema/joii

Примеры исходного кода, приведенные в readme на странице 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 

Или использовать его как смесь-в:

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 
Смежные вопросы