我正在重构一个我从开源项目中获取的大型javascript文档。许多函数使用不一致的return语句。这是我的意思的一个简单例子:
var func = function(param) {
if (!param) {
return;
}
// do stuff
return true;
}
有时函数返回布尔值,有时返回字符串或其他东西。通常它们与条件内的简单return;
语句不一致。
问题是代码很复杂。它是一个解析器,它使用大量独特的RegEx匹配,动态创建和销毁DOM节点等。初步测试表明,在上面的示例中,我可以将return;
语句更改为{{1}但是我担心我可能没有意识到它会对脚本产生负面影响(即某些功能停止工作),直到很久以后。
所以我的问题:使用空白退货声明是否有好处?这可能是故意用这种方式编码还是只是懒惰?我可以将它们全部更改为return false;
或return false;
,还是我需要深入了解每个电话,并了解他们对这些功能的结果做了什么?
答案 0 :(得分:43)
使用不带值的return
将返回值undefined
。
如果将值计算为布尔值,undefined
将作为false
使用,但如果将值与false
进行比较,则会得到不同的行为:
var x; // x is undefined
alert(x); // shows "undefined"
alert(!x); // shows "true"
alert(x==false); // shows "false"
因此,虽然代码应逻辑上返回true
或false
,而不是true
或undefined
,但您不能只将return;
更改为{{ 1}}不检查返回值的使用方式。
答案 1 :(得分:18)
“空白返回”语句可用于将控制转移回调用函数(或由于某种原因停止执行函数 - 例如:验证等)。在大多数情况下,我使用空白返回语句是在我做某种验证的时候。但是,我指出了为什么停止执行函数的一些指标。例如,使用错误消息在DIV元素上设置“innerText”属性。
在上面的代码中,它看起来像是一个验证。如果一切顺利,该函数返回“true”。看起来调用函数解析返回值,如果它是“true”,则执行语句的下一步(在调用函数中)。
在上面的示例中,返回“false”而不是空白返回是一个好习惯。这样你就可以使它变得统一,让其他程序员的生活更轻松。
你可以解决这些不一致的问题;但是,请确保彻底测试所有更改。测试您对代码所做的每一项更改都是一种很好的做法,无论它多么小。
答案 2 :(得分:8)
这里可能丢失的东西(不是直接用你的例子)是你可以有一个三态对象:
var myfunc = function(testparam) {
if (typeof testparam === 'undefined') return;
if (testparam) {
return true;
}
else {
return false;
}
};
var thefirst = myfunc(true)
var thesecond = myfunc(false);
var thelast = myfunc();
alert("type:" + typeof thefirst+" value:"+thefirst);
alert("type:" + typeof thesecond+" value:"+thesecond);
alert("type:" + typeof thelast+" value:"+thelast);
这些回报:
> type:boolean:true
> type:boolean:false
> type:undefined:undefined
注意:在此示例中,null将返回false myfunc(null);
答案 3 :(得分:6)
更改函数实际上会改变代码,因为return;
和return false;
会输出不同的数据类型。
var test = function (x) {
if (!x) {
return;
}
else {
return false;
}
};
var a = test(true), b = test(false);
console.log(typeof b); // boolean
console.log(typeof a); // undefined
答案 4 :(得分:3)
return;
和return undefined;
之间没有任何区别。调用这两个函数的结果是接收值undefined
。
(在以return
终止的函数主体与刚从代码结尾掉下来的函数主体之间,存在一个 规范级的区别,但是在代码中无法检测到任何东西。¹调用一个在代码末尾执行失败的函数也会导致值undefined
。)
"use strict";
// Implicit return of `undefined`
function x() {
return;
}
// Explicit return of `undefined`
function y() {
return undefined;
}
// Execution falls off the end
function z() {
}
console.log(typeof x() === "undefined"); // true
console.log(typeof y() === "undefined"); // true
console.log(typeof z() === "undefined"); // true
除非,当然,undefined
蒙上了一层阴影。遗憾的是,这仍然是可能的(尽管在全球范围内,这不是很高兴)。在非常前卫边缘情况下,存在区别:
"use strict";
(function() {
const undefined = 42;
// ^^^^^^^^^^^^^^^---- shadowing `undefined`
// Implicit return of `undefined`
function x() {
return;
}
// Explicit return of `undefined`
function y() {
return undefined;
}
// Execution falls off the end
function z() {
}
console.log(typeof x() === "undefined"); // true, `x` returns the canonical `undefined`
console.log(typeof y() === "undefined"); // false, `y` returns 42
console.log(typeof z() === "undefined"); // true, `z` (effectively) returns the canonical `undefined`
})();
¹使用return
是突然完成,[[Call]]转换为具有值的正常完成。代码的结尾是正常完成(spec)([[Call]]确保为值提供undefined
)。但这又是规范级别的差异,不是代码中可以观察到的。