我希望JavaScript函数具有我设置了默认值的可选参数,如果未定义值,则使用该参数(如果传递值,则将其忽略)。在Ruby中,您可以这样操作:
def read_file(file, delete_after = false)
# code
end
这在JavaScript中有效吗?
function read_file(file, delete_after = false) {
// Code
}
从ES6 / ES2015开始,默认参数位于语言规范中。
function read_file(file, delete_after = false) {
// Code
}
正常工作。
参考:默认参数-MDN
如果未传递任何值或未定义,则默认函数参数允许使用默认值初始化形式参数。
// the `= {}` below lets you call the function without any parameters
function myFor({ start = 5, end = 1, step = -1 } = {}) { // (A)
// Use the variables `start`, `end` and `step` here
···
}
预ES2015,
有很多方法,但这是我的首选方法-它使您可以传入任何您想要的内容,包括false或null。(typeof null == "object"
)
function foo(a, b) {
a = typeof a !== 'undefined' ? a : 42;
b = typeof b !== 'undefined' ? b : 'default_b';
...
}
function read_file(file, delete_after) {
delete_after = delete_after || "my default here";
//rest of code
}
这就赋予delete_after
的价值delete_after
,如果它不是一个falsey值,否则将字符串"my default here"
。有关更多详细信息,请查看Doug Crockford对语言的调查,并查看关于“运算符”的部分。
如果你想在一个通过这种方法行不通falsey值即false
,null
,undefined
,0
或""
。如果您需要传递假值,则需要使用Tom Ritter的answer中的方法。
当处理一个函数的许多参数时,让使用者在一个对象中传递参数实参,然后将这些值与一个包含该函数默认值的对象合并通常是有用的。
function read_file(values) {
values = merge({
delete_after : "my default here"
}, values || {});
// rest of code
}
// simple implementation based on $.extend() from jQuery
function merge() {
var obj, name, copy,
target = arguments[0] || {},
i = 1,
length = arguments.length;
for (; i < length; i++) {
if ((obj = arguments[i]) != null) {
for (name in obj) {
copy = obj[name];
if (target === copy) {
continue;
}
else if (copy !== undefined) {
target[name] = copy;
}
}
}
}
return target;
};
使用
// will use the default delete_after value
read_file({ file: "my file" });
// will override default delete_after value
read_file({ file: "my file", delete_after: "my value" });
我发现类似这样的简单内容对于个人而言更加简洁和易读。
function pick(arg, def) {
return (typeof arg == 'undefined' ? def : arg);
}
function myFunc(x) {
x = pick(x, 'my default');
}
在ECMAScript 6中,您实际上将能够准确地写出您拥有的东西:
function read_file(file, delete_after = false) {
// Code
}
如果不存在或,它将设置delete_after
为。您现在可以将诸如Babel这样的编译器与ES6功能一起使用。false
undefined
默认参数值
使用ES6,您可能会JavaScript
涉及到最常见的习惯用法之一,即为功能参数设置默认值。多年来我们这样做的方式应该看起来很熟悉:
function foo(x,y) {
x = x || 11;
y = y || 31;
console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 5 ); // 36
foo( null, 6 ); // 17
这种模式最常用,但是当我们传递诸如
foo(0, 42)
foo( 0, 42 ); // 53 <-- Oops, not 42
为什么?因为0 is falsy
,所以x || 11 results in 11
,而不是直接传入0。要解决此问题,有些人会改为更详细地写支票,如下所示:
function foo(x,y) {
x = (x !== undefined) ? x : 11;
y = (y !== undefined) ? y : 31;
console.log( x + y );
}
foo( 0, 42 ); // 42
foo( undefined, 6 ); // 17
现在,我们可以检查一种自上而下有用的语法,ES6
以简化默认值对缺失参数的分配:
function foo(x = 11, y = 31) {
console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 0, 42 ); // 42
foo( 5 ); // 36
foo( 5, undefined ); // 36 <-- `undefined` is missing
foo( 5, null ); // 5 <-- null coerces to `0`
foo( undefined, 6 ); // 17 <-- `undefined` is missing
foo( null, 6 ); // 6 <-- null coerces to `0`
x = 11
在函数声明中,它x !== undefined ? x : 11
比更常见的惯用法更像x || 11
默认值表达式
Function
默认值不仅可以是简单值,例如31;它们可以是任何有效的表达式,甚至可以是function call
:
function bar(val) {
console.log( "bar called!" );
return y + val;
}
function foo(x = y + 3, z = bar( x )) {
console.log( x, z );
}
var y = 5;
foo(); // "bar called"
// 8 13
foo( 10 ); // "bar called"
// 10 15
y = 6;
foo( undefined, 10 ); // 9 10
如您所见,默认值表达式是延迟计算的,这意味着它们仅在需要时以及在需要时才运行,也就是说,当参数的自变量被省略或未定义时。
默认值表达式甚至可以是内联函数表达式调用-通常称为立即调用函数表达式(IIFE)
:
function foo( x =
(function(v){ return v + 11; })( 31 )
) {
console.log( x );
}
foo(); // 42
该解决方案对我来说适用于js:
function read_file(file, delete_after) {
delete_after = delete_after || false;
// Code
}
只需使用未定义的显式比较即可。
function read_file(file, delete_after)
{
if(delete_after === undefined) { delete_after = false; }
}
我强烈建议在javascript中使用默认参数值时要格外小心。与高阶函数等结合使用时,它常常会造成错误forEach
,map
和reduce
。例如,考虑以下代码行:
['1', '2', '3'].map(parseInt); // [1, NaN, NaN]
parseInt具有可选的第二个参数function parseInt(s, [
基数,=10])
但parseInt
具有三个参数的map调用:(element,index和array)。
我建议您将必需的参数与可选/默认值的参数分开。如果您的函数采用1,2或3个必需参数(默认值没有意义),请将它们设为函数的位置参数,则所有可选参数都应作为单个对象的命名属性。如果您的函数需要4个或更多,则通过单个对象参数的属性提供所有参数可能更有意义。
在你的情况我建议你写你的DELETEFILE功能是这样的:(每个编辑 instead
的评论)...
// unsafe
function read_file(fileName, deleteAfter=false) {
if (deleteAfter) {
console.log(`Reading and then deleting ${fileName}`);
} else {
console.log(`Just reading ${fileName}`);
}
}
// better
function readFile(fileName, options) {
const deleteAfter = !!(options && options.deleteAfter === true);
read_file(fileName, deleteAfter);
}
console.log('unsafe...');
['log1.txt', 'log2.txt', 'log3.txt'].map(read_file);
console.log('better...');
['log1.txt', 'log2.txt', 'log3.txt'].map(readFile);
运行上面的代码片段说明了未使用参数的默认参数值潜伏的危险。
作为更新...使用ECMAScript 6,您可以像下面这样在函数参数声明中最终设置默认值:
function f (x, y = 7, z = 42) {
return x + y + z
}
f(1) === 50
如参考-http://es6-features.org/#DefaultParameterValues
作为一位长期的C ++开发人员(Rookie到Web开发的新手:)),当我第一次遇到这种情况时,我在函数定义中进行了参数分配,如下所述。
function myfunc(a,b=10)
但要注意,它在浏览器之间无法始终如一地工作。对我来说,它可以在台式机上使用chrome,但不能在android上使用chrome。如上文所述,更安全的选择是-
function myfunc(a,b)
{
if (typeof(b)==='undefined') b = 10;
......
}
这个答案的目的不是要重复其他人已经提到的相同解决方案,而是要告知函数定义中的参数分配在某些浏览器上可能有效,但不要依赖它。
对于有兴趣在Microsoft Edge中进行代码工作的任何人,请勿在函数参数中使用默认值。
function read_file(file, delete_after = false) {
#code
}
在该示例中,Edge将引发错误“ Expecting')'”
为了避开这种用途
function read_file(file, delete_after) {
if(delete_after == undefined)
{
delete_after = false;
}
#code
}
截至2016年8月8日,这仍然是一个问题
按照语法
function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
statements
}
您可以定义形式参数的默认值。并使用typeof函数检查未定义的值。
function helloWorld(name, symbol = '!!!') {
name = name || 'worlds';
console.log('hello ' + name + symbol);
}
helloWorld(); // hello worlds!!!
helloWorld('john'); // hello john!!!
helloWorld('john', '(>.<)'); // hello john(>.<)
helloWorld('john', undefined); // hello john!!!
helloWorld(undefined, undefined); // hello worlds!!!
如果要使用最新ECMA6
语法,请使用此命令:
function myFunction(someValue = "This is DEFAULT!") {
console.log("someValue --> ", someValue);
}
myFunction("Not A default value") // calling the function without default value
myFunction() // calling the function with default value
它被称为default function parameters
。如果未传递值或未定义,则允许使用默认值初始化形式参数。
注意:它不适用于Internet Explorer或更旧的浏览器。
为了获得最大的兼容性,请使用以下命令:
function myFunction(someValue) {
someValue = (someValue === undefined) ? "This is DEFAULT!" : someValue;
console.log("someValue --> ", someValue);
}
myFunction("Not A default value") // calling the function without default value
myFunction() // calling the function with default value
这两个函数的行为完全相同,因为每个示例都依赖于这样的事实:undefined
如果在调用该函数时未传递任何参数值,则参数变量将为。
如果您正在使用ES6+
,则可以通过以下方式设置默认参数:
function test (foo = 1, bar = 2) {
console.log(foo, bar);
}
test(5); // foo gets overwritten, bar remains default parameter
如果需要ES5
语法,可以按照以下方式进行:
function test(foo, bar) {
foo = foo || 2;
bar = bar || 0;
console.log(foo, bar);
}
test(5); // foo gets overwritten, bar remains default parameter
在以上语法中,OR
使用了运算符。OR
如果可以将其转换为第一个值,操作员将始终返回第一个值,true
否则将返回右侧值。当没有相应参数的情况下调用该函数时,JS引擎会将参数变量(bar
在我们的示例中)设置为undefined
。undefined
然后将其转换为false,从而使OR
操作员返回值0。
ES6:正如大多数答案中已经提到的那样,在ES6中,您可以简单地将参数和值一起初始化。
ES5:给定的答案大多是配不上我,因为在若干情况下我可能要通过falsey值,如0
,null
和undefined
一个函数。要确定参数是否未定义,因为这是我传递的值,而不是因为根本没有定义,所以我未定义:
function foo (param1, param2) {
param1 = arguments.length >= 1 ? param1 : "default1";
param2 = arguments.length >= 2 ? param2 : "default2";
}
function throwIfNoValue() {
throw new Error('Missing argument');
}
function foo(argValue = throwIfNoValue()) {
return argValue ;
}
此处的foo()是一个函数,其参数名为argValue。如果我们在此处的函数调用中未传递任何内容,则将调用函数throwIfNoValue(),并将返回的结果分配给唯一的参数argValue。这就是将函数调用用作默认参数的方式。这使得代码更加简化和可读。
是的,ES6完全支持使用默认参数:
function read_file(file, delete_after = false) {
// Code
}
要么
const read_file = (file, delete_after = false) => {
// Code
}
但是在ES5之前,您可以轻松地做到这一点:
function read_file(file, delete_after) {
var df = delete_after || false;
// Code
}
这意味着如果存在该值,请使用该值,否则,请使用||
执行相同操作后的第二个值...
注意:如果您将值传递给ES6一个值,即使该值是虚假的,也将有很大的不同,它将被替换为新值,例如null
或""
...,但仅当传递值时,才会替换ES5一个是真的,那是因为||
工作方式...
如果由于某种原因您未使用ES6并在lodash
此处使用,则可以通过以下_.defaultTo
方法通过简洁的方法来默认使用函数参数:
var fn = function(a, b) {
a = _.defaultTo(a, 'Hi')
b = _.defaultTo(b, 'Mom!')
console.log(a, b)
}
fn() // Hi Mom!
fn(undefined, null) // Hi Mom!
fn(NaN, NaN) // Hi Mom!
fn(1) // 1 "Mom!"
fn(null, 2) // Hi 2
fn(false, false) // false false
fn(0, 2) // 0 2
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
如果当前值为NaN,null或undefined,它将设置默认值
未来之声
将来,您将能够将一个对象“传播”到另一个对象(当前,截至2019年,Edge不支持!)-演示如何使用该对象作为漂亮的默认选项,而与顺序无关:
function test(options) {
var options = {
// defaults
url: 'defaultURL',
some: 'somethingDefault',
// override with input options
...options
};
var body = document.getElementsByTagName('body')[0];
body.innerHTML += '<br>' + options.url + ' : ' + options.some;
}
test();
test({});
test({url:'myURL'});
test({some:'somethingOfMine'});
test({url:'overrideURL', some:'andSomething'});
test({url:'overrideURL', some:'andSomething', extra:'noProblem'});
MDN参考:https : //developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax
...同时Edge DOES支持的对象是Object.assign()(IE不支持,但我真的希望我们可以将IE留在后面:))
同样,你可以做
function test(options) {
var options = Object.assign({
// defaults
url: 'defaultURL',
some: 'somethingDefault',
}, options); // override with input options
var body = document.getElementsByTagName('body')[0];
body.innerHTML += '<br>' + options.url + ' : ' + options.some;
}
test();
test({});
test({url:'myURL'});
test({some:'somethingOfMine'});
test({url:'overrideURL', some:'andSomething'});
test({url:'overrideURL', some:'andSomething', extra:'noProblem'});
编辑:由于对const
选项的注释-在函数的其余部分使用常量选项的问题实际上并不是您不能做到这一点,只是您不能在其自己的声明中使用常量变量-您将拥有将输入命名调整为类似
function test(input_options){
const options = {
// defaults
someKey: 'someDefaultValue',
anotherKey: 'anotherDefaultValue',
// merge-in input options
...input_options
};
// from now on use options with no problem
}
只是为了展示我的技能(大声笑),即使没有命名参数,也可以编写以上函数:
ES5及以上
function foo() {
a = typeof arguments[0] !== 'undefined' ? a : 42;
b = typeof arguments[1] !== 'undefined' ? b : 'default_b';
...
}
ES6及以上
function foo(...rest) {
a = typeof rest[0] !== 'undefined' ? a : 42;
b = typeof rest[1] !== 'undefined' ? b : 'default_b';
...
}
def read_file(file, delete_after = false)
# code
end
在这种情况下,以下代码可能适用,包括ECMAScript 6(ES6)以及早期版本。
function read_file(file, delete_after) {
if(delete_after == undefined)
delete_after = false;//default value
console.log('delete_after =',delete_after);
}
read_file('text1.txt',true);
read_file('text2.txt');
因为在调用时跳过函数的参数值时,语言的默认值有效,因此在JavaScript中将其分配给undefined。这种方法在程序上看起来并不吸引人,但具有向后兼容性。
是的,这被称为默认参数
如果未传递任何值或未定义,则默认函数参数允许使用默认值初始化形式参数。
句法:
function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
statements
}
描述:
函数的参数默认为undefined但是,在某些情况下,设置其他默认值可能会很有用。这是默认参数可以提供帮助的地方。
过去,设置默认值的一般策略是在函数的主体中测试参数值,如果未定义,则分配一个值。如果调用中未提供任何值,则其值将不确定。您必须设置条件检查以确保参数未定义
如果使用ES2015中的默认参数,则不再需要在功能主体中进行检查。现在,您只需在函数头中输入一个默认值即可。
差异示例:
// OLD METHOD
function multiply(a, b) {
b = (typeof b !== 'undefined') ? b : 1;
return a * b;
}
multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5); // 5
// NEW METHOD
function multiply(a, b = 1) {
return a * b;
}
multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5); // 5
不同的语法示例:
填充未定义与其他虚假值:
即使在调用时显式设置了该值,num参数的值也是默认值。
function test(num = 1) {
console.log(typeof num);
}
test(); // 'number' (num is set to 1)
test(undefined); // 'number' (num is set to 1 too)
// test with other falsy values:
test(''); // 'string' (num is set to '')
test(null); // 'object' (num is set to null)
通话时评估:
默认参数在调用时进行求值,因此与某些其他语言不同,每次调用该函数时都会创建一个新对象。
function append(value, array = []) {
array.push(value);
return array;
}
append(1); //[1]
append(2); //[2], not [1, 2]
// This even applies to functions and variables
function callSomething(thing = something()) {
return thing;
}
function something() {
return 'sth';
}
callSomething(); //sth
默认参数可用于以后的默认参数:
已经遇到的参数可用于以后的默认参数
function singularAutoPlural(singular, plural = singular + 's',
rallyingCry = plural + ' ATTACK!!!') {
return [singular, plural, rallyingCry];
}
//["Gecko","Geckos", "Geckos ATTACK!!!"]
singularAutoPlural('Gecko');
//["Fox","Foxes", "Foxes ATTACK!!!"]
singularAutoPlural('Fox', 'Foxes');
//["Deer", "Deer", "Deer ... change."]
singularAutoPlural('Deer', 'Deer', 'Deer peaceably and respectfully \ petition the government for positive change.')
在函数体内定义的函数:
在Gecko 33(Firefox 33 / Thunderbird 33 / SeaMonkey 2.30)中引入。在函数主体中声明的函数不能在默认参数内引用,并引发ReferenceError(当前在SpiderMonkey中为TypeError,请参见bug 1022967)。始终首先执行默认参数,然后评估函数体内的函数声明。
// Doesn't work! Throws ReferenceError.
function f(a = go()) {
function go() { return ':P'; }
}
默认参数之后没有默认值的参数:
在Gecko 26(Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2)之前,以下代码导致SyntaxError。此问题已在错误777060中修复,并在以后的版本中按预期工作。仍然从左到右设置参数,即使以后的参数没有默认值,它们也会覆盖默认参数。
function f(x = 1, y) {
return [x, y];
}
f(); // [1, undefined]
f(2); // [2, undefined]
具有默认值分配的解构参数:
您可以将默认值分配与解构分配符号一起使用
function f([x, y] = [1, 2], {z: z} = {z: 3}) {
return x + y + z;
}
f(); // 6
设置默认参数的另一种方法是使用参数的对象映射,而不是直接使用参数。例如,
const defaultConfig = {
category: 'Animals',
legs: 4
};
function checkOrganism(props) {
const category = props.category || defaultConfig.category;
const legs = props.legs || defaultConfig.legs;
}
这样,很容易扩展参数,而不必担心参数长度不匹配。
是-证明:
答案是肯定的。实际上,有许多语言支持默认参数。Python是其中之一:
def(a, enter="Hello"):
print(a+enter)
尽管由于括号这是Python 3代码,但函数中的默认参数也可以在JS中使用。
例如,在您的情况下:
function read_file(file, deleteAfter=false){
console.log(deleteAfter);
}
read_file("test.txt");
但是有时您实际上并不需要默认参数。
您可以在函数启动后立即定义变量,如下所示:
function read_file(file){
var deleteAfter = false;
console.log(deleteAfter);
}
read_file("test.txt");
在我的两个示例中,它都返回相同的内容。但是有时它们实际上可能是有用的,例如在非常高级的项目中。
因此,总而言之,可以在JS中使用默认参数值。但这几乎与在函数启动后立即定义变量相同。但是,有时它们仍然非常有用。您可能已经注意到,默认参数值比在函数启动后立即定义参数的标准方式少花费一行代码。
编辑:这是非常重要的!这会不会在IE浏览器。请参阅文档。因此,对于IE,您必须使用“在函数顶部定义变量”方法。默认参数在IE中不起作用。
是的,这可以使用Javascript。您也可以这样做:
function func(a=10,b=20)
{
alert (a+' and '+b);
}
func(); // Result: 10 and 20
func(12); // Result: 12 and 20
func(22,25); // Result: 22 and 25
文章标签:arguments , default-parameters , function , javascript , parameters
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!