Клонировать или применять: что лучше?

Я хочу создать серию объектов, которые наследуют или копируют свойства экземпляра из базового объекта. Это привело меня к решению о том, какой шаблон использовать, и я хотел спросить ваше мнение о том, какой метод "лучше".

//APPLY:
// ---------------------------------------------------------
//base object template
var base = function(){
   this.x = { foo: 'bar'};
   this.do = function(){return this.x;}
}

//instance constructor
var instConstructor = function (a,b,c){
   base.apply(this);//coerces context on base
   this.aa = a;
   this.bb = b;
   this.cc = c;
}

instConstructor.prototype = new base();

var inst = function(a,b,c){
    return new instConstructor(a,b,c);
}

//CLONE   
// --------------------------------------------------------- 
function clone(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    var copy = obj.constructor();
    for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
    }
    return copy;
}    

var x = {foo: 'bar'};

function instC(a,b,c){
     this.aa = a;
     this.bb = b;
     this.cc = c;
     this.x = clone(x);
};

instC.prototype.do = function(){
    return this.x;
}

оба они достигают одного и того же, а именно уникальных свойств экземпляра, основанных на общем шаблоне - вопрос в том, какой из них более "элегантный"

2 ответа

Решение

Хорошо, так что я подумал об этом - и ответ проистекает из варианта использования. Если клон копирует свойства в заданную область, применяется изменение области, окружающей свойство. Первое лучше для миксинов, второе для наследования.

Судя по вашим вопросам, похоже, вы ищете что-то похожее на Object.create. Эта функция может быть использована для создания нового объекта, который имеет выбранный вами объект в качестве прототипа.

//for old browsers without Object.create:
var objCreate = function(proto){
    function F(){};
    F.prototype = proto;
    return new F();

Что касается сравнения с методом клонирования, они делают разные вещи, поэтому вы должны выбрать, что является более подходящим.

Использование прототипов будет отражать изменения родительского объекта в дочерних объектах.

a = {x:1};
b = Object.create(a);
a.x = 2;
//b.x is now 2 as well

Вы также должны быть осторожны при использовании методов, которые имеют this, В зависимости от того, что вы делаете, вы можете иметь нежелательные последствия, если используете слишком много прототипного наследования.

a ={
   x: 1,
   foo: function(){ this.x += 1 }
}
b = Object.create(a);
b.foo();
//a.x does not change

С другой стороны, клонирование требует клонирования, так что вы можете быть уверены, что объекты не будут мешать друг другу. Иногда это то, что вы хотите.

Другие вопросы по тегам