如何为传递给构造函数的对象设置默认属性?

时间:2016-09-07 12:48:17

标签: javascript constructor wrapper factory javascript-objects

我试图在一个位置进行更改,以影响传递到对象的所有实例化的配置对象。该对象在全球范围内可用,如下所示:

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的javascript构造函数。

我缺少什么?

2 个答案:

答案 0 :(得分: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
  }
}

答案 1 :(得分: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);