// 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;
}
}
以上看起来非常冗长。使用默认参数处理参数选项有什么更好的方法?
答案 0 :(得分:67)
这使用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
修改:现在也在underscore
或lodash
!
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 );
}
答案 1 :(得分:26)
ES6 / ES2015有几种新方法。使用Object.assign
:
options = Object.assign({}, defaults, options);
使用解构赋值:
const { a = 1, b = 2 } = options;
您还可以使用解构函数参数:
const ƒ = ({a = 1, b = 2, c = 3} = {}) => {
console.log({ a, b, c });
};
没有依赖!
答案 2 :(得分: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.
};
虽然有点冗长,但我觉得它很容易阅读,添加/删除选项并添加默认值。当有很多选项时,更紧凑的版本是:
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.
};
答案 3 :(得分: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"}
答案 4 :(得分:2)
如果您需要在许多连续功能中执行此操作,那么标准化流程并加快其速度的方法是:
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);
}
这样,您只需在函数内定义一个选项对象,其中包含默认值。
如果您想对avoid prototype 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
(您可以查看兼容性表格here)
最后 ECMAScript 6 将为我们带来最好的方法:default parameters。
在此之前需要几个月的时间才能在浏览器中得到广泛支持。
答案 5 :(得分:2)
在不使用外部库的情况下使用ES6 Spread Operator
function Example(opts) {
let defaults = { foo: 1, bar: 2 }
opts = { ...defaults, ...(opts || {}) }
console.log(opts);
}
Example({ bar: 3, baz: 4 })
// { foo: 1, bar: 3, baz: 4 }
答案 6 :(得分:0)
虽然Object.assign是将选项与默认值合并的非常简单的方法,但它有一些缺点:
如果您想使用三元运算符设置条件选项 - 即使undefined
值也会覆盖默认值:
const options = {
logging: isProduction ? 'none' : undefined
};
const defaults = {
logging: 'verbose'
}
Object.assign({}, defaults, options); // {logging: undefined} !
如果您提供的选项名称不正确 - 您将不会收到警告:
const options = {
loging: 'none' // typo
};
const defaults = {
logging: 'verbose'
}
Object.assign({}, defaults, options); // {logging: 'verbose', loging: 'none'} !
为了涵盖这些情况,我创建了很小的flat-options包
它不会覆盖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."
希望这有帮助!
答案 7 :(得分:0)
如果您有权使用ES6 with a stage 4 proposal(例如Babel),则可以通过传播和解构分配来完成。
const defaultPrintOptions = {
fontName: "times",
fontStyle: "normal",
fontSize: 10,
align: "left"
};
// Setting the null default isn't necessary but
// makes it clear that the parameter is optional.
// Could use {} but would create a new object
// each time the function is called.
function print(text, options = null) {
let {
fontName,
fontStyle,
fontSize,
align
} = {
...defaultPrintOptions,
...options
};
console.log(text, fontName, fontStyle, fontSize, align);
}
print("All defaults:");
print("Override some:", {
fontStyle: "italic",
align: "center"
});
print("Override all:", {
fontName: "courier",
fontStyle: "italic",
fontSize: 24,
align: "right"
});
这也可以(但可能会创建更多对象):
function myFunction({
text = "",
line = 0,
truncate = 100
} = {}) {
console.log(text, line, truncate);
}
(David Walsh的另一个示例-@wprl的答案也提到了这一点)
答案 8 :(得分:0)
var mergeOptions = function mergeOptions(userOptions) {
// Default options
var options = {
height: "100px",
width: "100px" ,
color: "blue"
}
if (userOptions) {
Object.keys(userOptions).forEach(function (key) {
options[key] = userOptions[key]
})
}
return options;
}
答案 9 :(得分:0)
这是一种简单干净的方法,希望对您有所帮助:
function example(url, {title = false, check = false, wait = false} = {}){
console.log('url: ', URL);
console.log('title: ', title);
console.log('check: ', check);
console.log('wait: ', wait);
}
example('https://example.com', {wait: 20})
这是上面代码的输出:
url: https://example.com
title: false
check: false
wait: 20
答案 10 :(得分:0)
有一个新的 javascript 语法可以轻松设置默认值、逻辑赋值运算符:
// Super crazy this:
staticConfig.defaultPropsForFoo =
staticConfig.defaultPropsForFoo || {
myDefault: 'props'
}
// turns into:
staticConfig.defaultPropsForFoo ||= { myDefault: 'props' }
如果您更喜欢更严格的布尔语义,也可以使用空运算符:
staticConfig.defaultPropsForFoo ??= { myDefault: 'props' }
(可以说我们应该总是使用 ??=
版本,但它也很新)
此外,我一直使用默认参数,但此语法适用于任何解构赋值:
const {
defaultPropsForFoo = { myDefault: 'props' },
...restConfig
} = staticConfig
答案 11 :(得分:-1)
我认为你正在寻找类似的东西(对于迟到的回复感到抱歉):
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
答案 12 :(得分:-5)
现在我想起来了,我有点像这样:
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
}