Is there a “null coalescing” operator in JavaScript?
javascript中是否有空合并运算符?
例如,在C中,我可以这样做:
1 2 | String someString = null; var whatIWant = someString ??"Cookies!"; |
我能为javascript找到的最佳近似值是使用条件运算符:
1 2 | var someString = null; var whatIWant = someString ? someString : 'Cookies!'; |
有点恶心。我能做得更好吗?
与c空合并运算符(
1 | var whatIWant = someString ||"Cookies!"; |
有一些情况(在下面澄清)表明行为与C的行为不匹配,但这是在JavaScript中分配默认值/可选值的一般、简洁的方法。
澄清无论第一个操作数的类型如何,如果将其强制转换为
1 2 3 4 5 | alert(Boolean(null)); // false alert(Boolean(undefined)); // false alert(Boolean(0)); // false alert(Boolean("")); // false alert(Boolean("false")); // true -- gotcha! :) |
这意味着:
1 2 3 4 5 | var whatIWant = null || new ShinyObject(); // is a new shiny object var whatIWant = undefined ||"well defined"; // is"well defined" var whatIWant = 0 || 42; // is 42 var whatIWant ="" ||"a million bucks"; // is"a million bucks" var whatIWant ="false" ||"no way"; // is"false" |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function coalesce() { var len = arguments.length; for (var i=0; i<len; i++) { if (arguments[i] !== null && arguments[i] !== undefined) { return arguments[i]; } } return null; } var xyz = {}; xyz.val = coalesce(null, undefined, xyz.val, 5); // xyz.val now contains 5 |
此解决方案的工作方式与SQL合并函数类似,它接受任意数量的参数,如果这些参数都没有值,则返回空值。它的行为就像C??运算符,即"、false和0被视为不为空,因此计为实际值。如果你来自.NET背景,这将是最自然的感觉解决方案。
如果用
1 2 3 4 5 6 7 | function $N(value, ifnull) { if (value === null || value === undefined) return ifnull; return value; } var whatIWant = $N(someString, 'Cookies!'); |
是的,很快就要到了。请参阅此处的建议和此处的实施状态。
看起来是这样的:
1 | x ?? y |
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | const response = { settings: { nullValue: null, height: 400, animationDuration: 0, headerText: '', showSplashScreen: false } }; const undefinedValue = response.settings?.undefinedValue ?? 'some other default'; // result: 'some other default' const nullValue = response.settings?.nullValue ?? 'some other default'; // result: 'some other default' const headerText = response.settings?.headerText ?? 'Hello, world!'; // result: '' const animationDuration = response.settings?.animationDuration ?? 300; // result: 0 const showSplashScreen = response.settings?.showSplashScreen ?? true; // result: false |
这里没有人提到过
对于给定代码:
1 2 3 4 5 6 7 | var a, b = null, c = parseInt('Not a number'), d = 0, e = '', f = 1 ; |
如果要使用
1 | var result = a || b || c || d || e || f; // result === 1 |
如果您使用典型的合并方法,如本文所述,您将得到
1 | var result = coalesce(a,b,c,d,e,f); // result.toString() === 'NaN' |
我觉得这两个都不对。在我自己的合并逻辑的小世界里,可能不同于你的世界,我认为未定义、空和NaN都是"空的"。所以,我希望从coalesce方法中得到
如果任何人的大脑像我的一样工作,而你想排除
1 2 3 4 5 6 7 8 9 10 11 12 | function coalesce() { var i, undefined, arg; for( i=0; i < arguments.length; i++ ) { arg = arguments[i]; if( arg !== null && arg !== undefined && (typeof arg !== 'number' || arg.toString() !== 'NaN') ) { return arg; } } return null; } |
对于那些希望代码尽可能短,并且不介意有一点不清晰的人,您也可以按照@impinball的建议使用它。这充分利用了这样一个事实,即NaN永远不等于NaN。你可以在这里读到更多:为什么南不等于南?
1 2 3 4 5 6 7 8 9 10 11 | function coalesce() { var i, arg; for( i=0; i < arguments.length; i++ ) { arg = arguments[i]; if( arg != null && arg === arg ) { //arg === arg is false for NaN return arg; } } return null; } |
目前没有支持,但JS标准化过程正在进行中:https://github.com/tc39/proposal-optional-chaining
注意javascript特定的空定义。在javascript中有两个"无值"的定义。1。空:当变量为空时,意味着它不包含任何数据,但该变量已在代码中定义。这样地:
1 2 3 4 | var myEmptyValue = 1; myEmptyValue = null; if ( myEmptyValue === null ) { window.alert('it is null'); } // alerts |
在这种情况下,变量的类型实际上是对象。测试它。
1 | window.alert(typeof myEmptyValue); // prints Object |
未定义:如果代码中以前没有定义变量,如预期的那样,它不包含任何值。这样地:
1 2 | if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); } // alerts |
如果出现这种情况,则变量的类型为"未定义"。
请注意,如果使用类型转换比较运算符(==),javascript将对这两个空值执行相同的操作。要区分它们,请始终使用类型严格比较运算符(==)。
在阅读了您的说明之后,@ates goral的答案提供了如何在JavaScript的C中执行相同的操作。
@gumbo的答案提供了检查空值的最佳方法;但是,重要的是要注意在javascript中
这里有一篇关于这两个术语之间差别的好文章。基本上,要理解,如果使用