Как правильно расширить объект JS? - PullRequest
4 голосов
/ 12 мая 2011

Допустим, у меня есть что-то вроде этого в файле с именем main.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 ]

6 голосов
/ 12 мая 2011

Другой вариант без 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
5 голосов
/ 12 мая 2011

Это потому что в строке

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

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

var a = {};

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

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

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

НТН

Иво Стойков

4 голосов
/ 12 мая 2011

Во-первых, вы заменяете прототип новым (перезаписываете то, что было раньше). Вторым способом вы добавляете новый элемент в прототип (расширяя его).

Есть еще один метод: библиотека, которая имеет метод extend или аналогичный (который в основном оборачивает то, что вы делаете во второй форме, в красивую оболочку). Например, в jQuery :

$.extend(obj_name.prototype, {
    newfoo : function() { alert('hi #3'); }
}
1 голос
/ 16 апреля 2014

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

Примеры исходного кода, предоставленные в файле readme настраница github, а также следующие ссылки:

Эта библиотека в основном позволяет определять «классы»в таком виде:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...