2016-09-07 12 views
1

Я пытаюсь внести изменения в одно место, чтобы повлиять на объект конфигурации, переданный во все экземпляры объекта. Объект доступен по всему миру следующим образом:Как установить свойство по умолчанию для объекта, который передается в конструктор?

function Crayons(){ 
    return { 
    foo: ThirdPartyFoo 
    } 
} 

объект инициализируется в моем проекте с var myFoo = new Crayons().foo({color: "red"});

Я хотел бы сделать {color: "blue"} по умолчанию, так что если кто-то не проходит в цвет, синий.

Я пытался делать

function Crayons(){ 
    var fooWithDefaults = function(){ 
    this = new ThirdPartyFoo(arguments); //this is invalid 
    this.color = "blue"; //and this would overwrite color if it was set 
    } 

    return { 
    foo: fooWithDefaults 
    } 
} 

Но new ключевым слова бросает меня, так как я не знаю, как создать яваскрипт конструктора, который по существу говорит this = new 3rdPartyFoo.

Что мне не хватает?

+3

'this.color = дано || "синий" ' – Li357

+0

@AndrewL. что будет работать для цвета, но я до сих пор не знаю, как построить объект. – adamdport

+0

Во-первых, 'Crayons' не реализуется как истинный конструктор, а как фабрика. Таким образом, нет необходимости ссылаться на него с помощью оператора 'new'. Во-вторых, 'Crayons' не содержит метода' foo'. Если он вызван, он возвращает объект с атрибутом 'foo', который ссылается на' ThirdPartyFoo', который может быть конструктором. Пожалуйста, исправьте свой пример тем, что является хотя бы допустимым кодом или может быть запущено без ошибок при бросании (я имею в виду 'var myFoo = new Crayons.foo ({color:" red "});') –

ответ

2

Вы можете украсить конструктор:

function Crayons(){ 
    function fooWithDefaults() { 
    3rdPartyFoo.apply(this, arguments); // this is what you're looking for 
    if (!this.color) // or whatever to detect "not set" 
     this.color = "blue"; 
    } 
    fooWithDefaults.prototype = 3rdPartyFoo.prototype; // to make `new` work 

    return { 
    foo: fooWithDefaults 
    } 
} 

Или вы просто сделать это завод, который возвращает экземпляр:

function Crayons(){ 
    function fooWithDefaults(arg) { 
    var that = new 3rdPartyFoo(arg); // you should know how many arguments it takes 
    if (!that.color) // or whatever to detect "not set" 
     that.color = "blue"; 
    return that; 
    } 

    return { 
    foo: fooWithDefaults 
    } 
} 

Здесь вы также можете роняйте new при вызове var myFoo = Crayons.foo({color: "red"});

Альтернативой модификации экземпляра после его создания было бы украшение опций, которые передаются в, что в целом лучшее решение:

function Crayons(){ 
    function fooWithDefaults(arg) { 
    if (!arg.color) // or whatever to detect "not set" 
     arg.color = "blue"; 
    return new 3rdPartyFoo(arg); 
    } 

    return { 
    foo: fooWithDefaults 
    } 
} 
+0

Я не хочу «бросать« новый », поскольку я пытаюсь избежать рефакторинга. Ваше первое решение - это то, что я искал. Благодаря! – adamdport

+0

Я имел в виду, что вы * можете * отбросить 'new' в вызове' fooWithDefaults', а не то, что вам нужно сделать. Я бы рассмотрел третье решение, самое чистое. – Bergi

0

function ThirdPartyCrayon(config) {   // constructor :: possible original Crayon implementation 
 

 
    Object.assign(this, config); 
 
    this.type = "thirdpartycrayon"; 
 
} 
 

 

 
function createCrayonSetting(defaultConfig) { // factory (creates a closure) 
 

 
    function CrayonWithDefaults() {   // constructor :: customized Crayon wrapper 
 

 
     Object.assign(this, defaultConfig); 
 
     ThirdPartyCrayon.apply(this, arguments); 
 
    } 
 

 
    return { 
 
     Crayon: CrayonWithDefaults 
 
    } 
 
} 
 

 

 
var 
 
    setting = createCrayonSetting({color: "blue", strokeWidth: "thin"}), 
 

 
    crayon1 = new setting.Crayon({color: "red", strokeWidth: "bold"}), 
 
    crayon2 = new setting.Crayon({color: "green"}); 
 
    crayon3 = new setting.Crayon(); 
 

 

 
console.log("crayon1 : ", crayon1); 
 
console.log("crayon2 : ", crayon2); 
 
console.log("crayon3 : ", crayon3);

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

  • Нет связанных вопросов^_^