具有默认值的选项的JavaScriptdevise模式?

// 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; } } 

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

这使用jQuery.extend,但可以与您select的库中的对象合并或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 

编辑 :现在也在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 

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

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

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

 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. }; 

虽然有点冗长,但我觉得很容易阅读,添加/删除选项和添加默认值。 当有很多select时,稍微更紧凑的版本是:

 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. }; 

而更紧凑的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"} 

在ES6 / ES2015中有几个新的方法。 使用Object.assign

 options = Object.assign({}, defaults, options); 

使用解构赋值:

 const { a = 1, b = 2 } = options; 

没有依赖!

如果你需要在许多连续的function中做到这一点,一个标准化过程并加快速度的方法是:

 function setOpts (standard, user) { if (typeof user === 'object' { for (var key in user) { standard[key] = user[key]; } } } 

那么你可以简单地定义你的函数就像这样:

 var example = function (options) { var opts = { a: 1, b: 2, c:3 }; setOpts(opts, options); } 

这样你只能在函数中定义一个选项对象,其中包含默认值。

如果你想要额外的检查以避免原型inheritance ,第一个函数可以是:

 function setOpts (standard, user) { if (typeof user === 'object') { Object.keys(user).forEach(function (key) { standard[key] = user[key]; }); } } 

后一种情况不支持:IE <9,Chrome <5,Firefox <4,Safari <5

(你可以在这里查看兼容性表)


最后, ECMAScript 6将为我们带来最好的方式: 默认参数

虽然在跨浏览器广泛支持之前需要几个月的时间。

尽pipeObject.assign是将选项与默认值合并的非常直接的方式,但它有一些缺点:

  1. 如果你想用三元运算符设置条件选项 – 即使对于undefined值,它也会覆盖默认值:

     const options = { logging: isProduction ? 'none' : undefined }; const defaults = { logging: 'verbose' } Object.assign({}, defaults, options); // {logging: undefined} ! 
  2. 如果您提供了不正确的选项名称 – 您将不会被警告:

     const options = { loging: 'none' // typo }; const defaults = { logging: 'verbose' } Object.assign({}, defaults, options); // {logging: 'verbose', loging: 'none'} ! 

为了涵盖这些情况,我创build了一个小平面选项包。
它不会覆盖undefined值的默认值:

 const options = { logging: isProduction ? 'none' : undefined }; const defaults = { logging: 'verbose' } flatOptions(options, defaults); // {logging: 'verbose'} 

并警告错误的选项名称:

 const options = { loging: 'none' // typo }; const defaults = { logging: 'verbose' } flatOptions(options, defaults); // throws "Unknown option: loging." 

希望这可以帮助!

我想你正在寻找这样的东西(对于迟到的回复抱歉):

 function foo(a, b, options) { this.defaults = { x: 48, y: 72, z: 35 }; for (var i in this.defaults) { if (options[i] != "undefined") { this.defaults[i] = options[i]; } } // more code... } 

编辑:道歉,从一些旧的代码抓住这个…你应该确保使用hasOwnProperty()方法,以确保你不遍历function.prototype

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty

现在我想到了,我喜欢这样:

 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 }