处理JavaScript中未定义参数和空参数之间的区别
我非常清楚null和undefined在JavaScript中是不同的。然而,当我自己的函数被作为参数传递时,我似乎无法决定是否使用这个事实 或者,以不同的方式表示,处理JavaScript中未定义参数和空参数之间的区别,javascript,Javascript,我非常清楚null和undefined在JavaScript中是不同的。然而,当我自己的函数被作为参数传递时,我似乎无法决定是否使用这个事实 或者,以不同的方式表示,myFoo(未定义)是否应返回与myFoo(null)相同的内容 或者,在另一种情况下,既然myBar(1,2,3)与myBar(1,2,3,未定义,未定义)是(几乎)相同的东西,那么myBar(1,2,3,null,null)应该返回与myBar(1,2,3)相同的东西吗 我觉得在这两种情况下都有可能出现混淆,并且库在处理null
myFoo(未定义)
是否应返回与myFoo(null)
相同的内容
或者,在另一种情况下,既然myBar(1,2,3)
与myBar(1,2,3,未定义,未定义)
是(几乎)相同的东西,那么myBar(1,2,3,null,null)
应该返回与myBar(1,2,3)
相同的东西吗
我觉得在这两种情况下都有可能出现混淆,并且库在处理null/undefined时应该遵循约定
我并不是在征求个人意见(所以请把这些意见表达成评论而不是回答)。我想问的是,是否有人知道,在处理这一区别时,是否有一种最佳实践应该坚持。非常欢迎参考外部资源 如何处理传递给函数的参数完全取决于您,因此取决于您。 如果要检查参数是否为
null
,请使用
if (myVar === null) {
如果要检查参数是否未定义
,请使用
if (typeof myVar === "undefined") {
如果预期参数不是0、null或未定义,则可以使用
if (myVar) {
因此,您的myFoo(null)
的行为是否应该与myFoo(未定义)
相同,完全取决于您在内部如何处理它们
当涉及到额外的参数时,除了
参数
集合比预期的要大之外,这没有任何影响。我想说,虽然在大多数情况下,区分这两个参数没有什么价值,但有价值的情况往往非常有趣
以一个函数为例,它可以被赋予一个回调函数undefined
可能表示应该使用一些默认回调(就好像没有指定参数一样),但是null
可能表示根本不应该进行回调:
function asyncWorker(data, callback, timeout) {
if (typeof callback === "undefined") {
callback = function() { $("#log").append("<p>Done!</p>"); };
}
// ...
if (callback) callback();
}
asyncWorker([1, 2, 3]); // default callback, no timeout
asyncWorker([4, 5, 6], null); // no callback, no timeout
asyncWorker([7, 8, 9], undefined, 10000); // default callback, 10s timeout
函数asyncWorker(数据、回调、超时){
如果(回调类型==“未定义”){
callback=function(){$(“#log”).append(“Done!”);};
}
// ...
if(callback)callback();
}
asyncWorker([1,2,3]);//默认回调,无超时
asyncWorker([4,5,6],null);//没有回调,没有超时
asyncWorker([7,8,9],未定义,10000);//默认回调,10秒超时
当然,这里可以使用
false
或0
代替null
,但在更复杂的示例中可能不是这样。您的代码是否能从额外的参数复杂性中获益完全取决于您。:-) 处理参数的最佳实践
- 定义预期参数、它们的用途以及这些参数的类型
- 决定如何通过正式参数或通过
集合访问它们参数
- 定义超出预期范围的值是否应产生默认值
- 在处理之前,请验证参数是否在范围内
- 对于布尔值,决定它们必须是真布尔值,还是仅为truthy/falsy
这是您需要根据方法的功能以及处理变量量的策略来选择的 以此为例,
function foo() {
var args = arguments.length == 1 ?
[document.body].concat([arguments[0]]) :
Array.prototype.slice.call(arguments);
args[0].style.backgroundColor = args[1];
}
foo(document.body, "red");
foo("blue");
真布尔值或真布尔值/falsy如何测试值在很大程度上取决于代码的设置方式
function foo(elem, color) {
if (!color) { // the correct test here should be 'typeof color == "undefined"'
color = "green";
}
elem.style.backgroundColor = color;
}
foo(document.body, "red"); //set the background color to red
foo(document.body); //set the background color to the default green
foo(document.body, ""); //remove the background color !This will fail!
最后一条语句将错误地使用默认值而不是提供的值,即使提供的值在预期范围内
在处理
undefined
值时,记住foo(undefined)没有区别代码>和foo()
除了参数
集合的长度不同之外。如何处理(如果需要的话)取决于您访问参数的方式。myBar(1,2,3)
与myBar(1,2,3,未定义,未定义)
:第一种情况下参数的长度为3,第二种情况下为5。啊,这一点很好。那么,如果我显式地接收到五个参数并在忽略参数
对象的情况下使用它们,那么我认为这是唯一一件相同的事情。我怀疑与null
的比较比与string“undefined”
@Marcel的比较要(稍微)快,你的观点是?把一个苹果和一个苹果进行比较比把一个桔子和一个桔子进行比较要快?或者这种类型的通话需要更长的时间?这有什么重要性?@Jakob:同样,这完全取决于你自己,很大程度上取决于你所期望的论点类型。如果您的代码不关心arg1
是否为0
、未定义
或null
,则将其强制转换为布尔值,如果不是,则检查精确值。简单的回答是:最佳实践是使用正确的方法。您是使用-
添加两个数字还是使用*
进行除法?也许不是,那么你怎么能要求一个关于“我应该用哪个操作符做数学?”的最佳实践呢?@Theo,但我做了,我的答案仍然是正确的。如果不知道最佳实践的用途,就无法推广最佳实践,因此我选择指出,它完全取决于手头的代码和开发人员的选择。@Theo,说真的,你认为OP寻求的答案确实存在吗?我回答的前提是,如果OP了解他在做什么,那么就不需要最佳实践(即使可以为其提供一个最佳实践)