2013-04-15 2 views
0

Мне интересно, есть ли какая-то лучшая практика для того, чтобы дать поведение объекту, полученному извне (db, сеть и т. Д.) В javascript (nodejs).Как увеличить объект с помощью настраиваемого метода в javascript?

Например, предположим, что у меня есть функция getById(<Id>), которая извлекает правильный объект из db, как бы вы добавили метод save на объект, возвращаемый этой функцией?

Вот что я хотел бы иметь:

var getById = function (id) { 
    var obj = callSomeExternalCode(id); 
    return obj; 
}; 
var myObj = getById('1234'); 
myObj.aProperty = 'a_new_value'; 
myObj.save(); 

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

Edit: Я забыл упомянуть, это было бы очень хорошо, чтобы эти методы, определенные в отдельном «родительский» объект (даже если, как я полагаю, прото-наследование не является ответом)

Благодаря

ответ

1

это было бы очень хорошо, чтобы эти методы, определенные в отдельном «родительский» объект

Тогда просто сделать так:

var parent = { 
    save: function() {…} 
}; 
function getById(id) { 
    // There's a shortcut function called "extend" for this in many libs: 
    // return extend(callSomeExternalCode(id), parent); 
    // which does 
    var obj = callSomeExternalCode(id); 
    for (var p in parent) 
     obj[p] = parent[p]; // copy 
    return obj; 
} 

Я полагаю, прото-наследование не ответ

Это может быть, особенно если есть больше объектов на parent, чем на новых obj. Тогда вы могли бы сделать (даже без какого-либо псевдо-классического кода):

function getById(id) { 
    // return extend(Object.create(parent), callSomeExternalCode(id)); 
    // long: 
    var obj = callSomeExternalCode(id), 
     res = Object.create(parent); 
    for (var p in obj) 
     res[p] = obj[p]; // copy 
    return res; 
} 
+0

Я знаю, что это может показаться «грязным», но, как указано [здесь] Http: // StackOverflow.com/questions/5777641/storageing-and-retrieving-javascript-objects-in-from-mongodb), можно поменять объект «prototype» в v8 .... это выглядит слишком грязным для вас? – ArtoAle

+0

Да, я думаю, что [нестандартное свойство '__proto__'] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/proto) довольно грязное - оно не будет работать в IE. Разумеется, иногда может быть полезно «Object.setPrototypeOf», но я боюсь, что стандартного способа нет ... – Bergi

+0

О, это не проблема, это проект только для узлов :) В любом случае, я согласен. Поскольку он не полностью стандартизован, мне это неудобно: D – ArtoAle

0

Что-то вроде этого?

var getById = function (id) { 
    var obj = callSomeExternalCode(id); 

    obj.save = function() { 
     // do something 
    } 

    return obj; 
}; 
+1

Я редактировал вопрос, чтобы объяснить, почему я предпочитаю, чтобы избежать этого решения :) (во всяком случае, это не дублируя функцию сохранения для каждого объекта?) – ArtoAle

+0

Да, он создает несколько 'save' функций – Bergi

1

Почему бы не передать myObj другому объекту фабрики/украшения раньше?

т.е.

myAugmentedObj = User.augment(myObj); 
myAugmentedObj.save(); 

редактировать:

Более конкретно:

var UserModule = { 
    save: function (...) { ... }, 
    anotherFunction: function (...) { ... } 
}; 

var User = { 
    augment: function (user) { 
    return $.extend(user, UserModule); 
    } 
}; 

Кстати,

Я бы на самом деле сделать пользователя класс, и есть UserModule как часть а не отдельный объект, а затем создавать новые объекты в качестве экземпляров пользователя. Но вы явно упомянули об избежании классического наследования.

+0

Да, это то, о чем я думал. Проблема заключается в том, как реализовать функцию User.Augment (я имею в виду, скопировать из шаблона? Какой-нибудь другой метод?) – ArtoAle

+1

отредактирован, чтобы включить реализацию – Max

Смежные вопросы