具有默认值的选项的javascript设计模式?

rip*_*234 66 javascript design-patterns optional-parameters option

// opt_options is optional
function foo(a, b, opt_options) {
  // opt_c, opt_d, and opt_e are read from 'opt_options', only c and d have defaults
  var opt_c = 'default_for_c';
  var opt_d = 'default_for_d';
  var opt_e; // e has no default

  if (opt_options) {
    opt_c = opt_options.c || opt_c;
    opt_d = opt_options.d || opt_d;
    opt_e = opt_options.e;
  }
}
Run Code Online (Sandbox Code Playgroud)

以上看起来非常冗长.使用默认参数处理参数选项的更好方法是什么?

max*_*max 72

这使用jQuery.extend但可以与您选择的库中的对象合并或ES6中的Object.assign互换.

function Module(options){
    var defaults = {
        color: 'red'
    };
    var actual = $.extend({}, defaults, options || {});
    console.info( actual.color );
}

var a = new Module();
// Red
var b = new Module( { color: 'blue' } );
// Blue
Run Code Online (Sandbox Code Playgroud)

编辑:现在也在underscorelodash!

function Module(options){
    var actual = _.defaults(options || {}, {
         color: 'red'
    });
    console.info( actual.color );
}

var a = new Module();
// Red
var b = new Module( { color: 'blue' } );
// Blue
Run Code Online (Sandbox Code Playgroud)

在Javascript ES6中,您可以使用Object.assign:

function Module(options = {}){
    let defaults = {
        color: 'red'
    };
    let actual = Object.assign({}, defaults, options);
    console.info( actual.color );
}
Run Code Online (Sandbox Code Playgroud)

  • 迟到了,但 object.assign 的问题是它会从“options”复制整个对象。因此,如果您有深层嵌套结构,它不会合并这些选项,而是会覆盖它们。 (2认同)

wpr*_*prl 34

ES6/ES2015有几种新方法.使用Object.assign:

options = Object.assign({}, defaults, options);
Run Code Online (Sandbox Code Playgroud)

使用解构赋值:

const { a = 1, b = 2 } = options;
Run Code Online (Sandbox Code Playgroud)

您还可以使用解构函数参数:

const ƒ = ({a = 1, b = 2, c = 3} = {}) => {
   console.log({ a, b, c });
};
Run Code Online (Sandbox Code Playgroud)

没有依赖!

  • 这种模式很棒,节省了很多房地产.虽然应该指出的是,任务很浅,而不是很深 (4认同)
  • 当心!如果您的“选项”输入有一个映射到“未定义”的已知键(例如“a”),您将不会从“默认值”中获取该属性的值 (4认同)
  • 如果未定义“选项”,它甚至可以工作! (2认同)

Ric*_*ard 20

要获得没有其他依赖项的默认选项,我使用以下模式:

var my_function = function (arg1, arg2, options) {
    options = options || {};
    options.opt_a = options.hasOwnProperty('opt_a') ? options.opt_a : 'default_opt_a';
    options.opt_b = options.hasOwnProperty('opt_b') ? options.opt_b : 'default_opt_b';
    options.opt_c = options.hasOwnProperty('opt_c') ? options.opt_c : 'default_opt_b';


    // perform operation using options.opt_a, options.opt_b, etc.
};
Run Code Online (Sandbox Code Playgroud)

虽然有点冗长,但我发现它易于阅读,添加/删除选项并添加默认值.当有很多选项时,稍微紧凑的版本是:

var my_function = function (arg1, arg2, options) {
    var default_options = {
        opt_a: 'default_opt_a',
        opt_b: 'default_opt_b',
        opt_c: 'default_opt_c'};

    options = options || {};
    for (var opt in default_options)
        if (default_options.hasOwnProperty(opt) && !options.hasOwnProperty(opt))
            options[opt] = default_options[opt];

    // perform operation using options.opt_a, options.opt_b, etc.
};
Run Code Online (Sandbox Code Playgroud)

  • 此外,我想指出,截至10月22日,ripper234接受的答案无效.在代码示例中,opt_c和opt_d始终具有default_for_c和default_for_d,即使options对象中存在其他值也是如此.将参数的顺序更改为逻辑OR可以修复此问题(a || b vs b || a). (3认同)

imb*_*olc 11

更紧凑的jQuery版本:

function func(opts) {
    opts = $.extend({
        a: 1,
        b: 2
    }, opts);

    console.log(opts);
}

func();            // Object {a: 1, b: 2} 
func({b: 'new'});  // Object {a: 1, b: "new"} 
Run Code Online (Sandbox Code Playgroud)


rip*_*234 -6

现在想起来,我有点喜欢这样:

function foo(a, b, opt_options) {
  // Force opt_options to be an object
  opt_options = opt_options || {};

  // opt_c, opt_d, and opt_e are read from 'opt_options', only c and d have defaults
  var opt_c = 'default_for_c' || opt_options.c;
  var opt_d = 'default_for_d' || opt_options.d;
  var opt_e = opt_options.e; // e has no default
}
Run Code Online (Sandbox Code Playgroud)

  • 不应该是 `var opt_c = opt_options.c || 'default_for_c';` 似乎永远不会达到 `opt_options.c`,因为 `'default_for_c'` 将评估为 true。 (4认同)
  • @Sukima另一个问题是,如果 opt_options.c 设置为 false,那么它会被更改回 true,这不是有意的。在这种情况下,最好显式检查未定义的情况。 (2认同)