2014-08-22 3 views
1

Я ищу что-то немного причудливое с функциями конструктора в Javascript, и я не совсем уверен, как это сделать.Динамически модифицирующие конструкторы в JavaScript?

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

function OriginalConstructor() { 
    // Do constructor things here 
    // Like defining methods and properties 
} 

NewConstructor = modifyConstructor(OriginalConstructor); 

И в результате «NewConstructor» должно быть функционально эквивалентно следующему:

function NewConstructor(id, data) { 
    this.id = id; 
    this.data = data; 
    // Do stuff from the original constructor here 
    // i.e. the same methods and properties defined in the original constructor 
} 

Кто-нибудь знает, как создать функцию «modifyConstructor»?

+0

Не уверен, что я понял, вы хотите вернуть новый конструктор с помощью тех же методов и прототипов или просто вернуть новый экземпляр переданного конструктора? – adeneo

+0

Звучит как классическое подклассирование с вызовом super(). Или они должны использовать один и тот же прототип? – Bergi

+0

см. Также [Можно ли переопределить метод класса JavaScript?] (Http://stackoverflow.com/a/21243884/1048572) – Bergi

ответ

3

Вы создаете функцию, которая задает свойства по вашему определению и вызывает исходный конструктор. Например:

function modifyConstructor(Constr) { 
    function NewConstructor(id, data) { 
     this.id = id; 
     this.data = data; 

     // Call original constructor 
     Constr.apply(this, Array.prototype.slice.call(arguments, 2)); 
    } 
    // Setting the constructor property might not be a good idea depending on 
    // the use case 
    NewConstructor.prototype = Object.create(Constr.prototype, { 
     constructor: {value: NewConstructor, writable: true, configurable: true} 
    }); 
    return NewConstructor; 
} 

Это в основном реализует NewConstructor как подкласс любой Constr есть.

+0

Это было именно то, что я искал, спасибо! –

0

Ваш пример выглядит плохой практикой.

Таким образом, гораздо легче поддерживать,

Я бы так:

function OriginalConstructor(id, number){ 

    this.id = id; 
    this.number = number; 

} 
var Obj = new OriginalConstructor(); 

function newConstructor(Obj){ 

    this.id = Obj.id; 
    this.number = Obj.number * 2; 

} 

newObject = new newConstructor(Obj); 

Что вы получаете от этого вл етс: Obj, который изначально был создан оригинальный конструктор, и это данные и состояние никогда не изменялись, а newObject был создан модифицированным конструктором, который модифицирует объект на основе нового конструктора.

+0

Кажется, это должен быть новый новый конструктор (Obj); '. Вы должны указать, что у 'newObject' нет ни одного другого свойства, которое может быть у Obj. Таким образом, это другой результат того, что ОП описал в своем вопросе. –

+0

Исправлено первое, о втором, что вы имеете в виду. NewObject не имеет ни одного из других свойств, которые может иметь Obj, он был создан на основе данных, которые Obj имеет. – Linial

+0

Если в 'OriginalConstructor.prototype' есть какие-либо свойства,' newObject' их не имеет. –

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