鉴于这段JavaScript代码...
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = a || b || c || d || e;
alert(f); // 4
有人可以向我解释这种技术叫什么(我的最佳猜想是这个问题的标题!)?以及它如何/为什么确切起作用?
我的理解是,f
将为变量分配第一个变量的最接近的值(从左到右),该变量的值不为null或未定义,但是我没有设法找到有关此技术的大量参考资料,并且看到它用了很多。
另外,这项技术是否专门针对JavaScript?我知道在PHP中执行类似的操作会导致f
具有真正的布尔值,而不是其d
本身的值。
有关说明,请参阅短路评估。这是实现这些运算符的常用方法。它不是JavaScript所独有的。
如果变量是falsy,则可以指定一个默认值,在这种情况下为的值。y
x
JavaScript中的布尔运算符可以返回操作数,而不是像其他语言一样总是返回布尔结果。
||
如果第一个操作数为falsy,则逻辑OR运算符()返回其第二个操作数的值,否则返回第一个操作数的值。
例如:
"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"
Falsy值是谁要挟到false
布尔上下文中使用时,它们是0
,null
,undefined
,一个空字符串,NaN
当然false
。
Javacript对逻辑运算符和使用短路评估。但是,它与其他语言的不同之处在于,它返回停止执行的最后一个值的结果,而不是或值。||
&&
true
false
以下值在JavaScript中被认为是虚假的。
- 假
- 空值
""
(空字符串)- 0
- 楠
- 未定义
下面的示例忽略了运算符的优先级规则,并且保持简单,下面的示例显示哪个值停止了评估,并作为结果返回。
false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"
直到第一个5个值NaN
都是虚假的,因此它们都从左到右进行求值,直到遇到第一个真实值为止-"Hello"
这使整个表达式为true,因此将不对任何向上的值进行求值,并"Hello"
作为表达式的结果返回。同样,在这种情况下:
1 && [] && {} && true && "World" && null && 2010 // null
前5个值都是真实的,直到遇到第一个虚假值(null
)时才被求值,这会使表达式为假,因此2010
不再进行求值,并null
作为表达式的结果返回。
您所给出的示例就是利用JavaScript的此属性来执行分配。它可以在需要获取一组值中第一个真实或虚假值的地方使用。下面的代码将为该值分配值"Hello"
,b
因为它使分配默认值更容易,而不是进行if-else检查。
var a = false;
var b = a || "Hello";
您可以将下面的示例称为对该功能的利用,并且我相信它会使代码更难阅读。
var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);
在警报内部,我们检查是否messages
为虚假,如果是,则进行评估并返回noNewMessagesText
,否则进行评估并返回newMessagesText
。由于在此示例中是虚假的,因此我们停止了noNewMessagesText和alert "Sorry, you have no new messages."
。
Javascript变量未输入类型,因此即使通过布尔运算符分配了f,也可以为其分配一个整数值。
为f分配了不等于false的最近值。所以0,false,null,undefined都被传递了:
alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
没有任何魔术。像这样的布尔表达式a || b || c || d
会延迟计算。Interpeter寻找的值a
,它是未定义的,所以它是假的,因此继续前进,然后看到b
哪个为空,仍然给出错误的结果,因此继续前进,然后看到c
-相同的故事。最终,它看到d
并说“呵呵,它不是null,所以我得到了结果”,并将其分配给最终变量。
该技巧适用于所有对布尔表达式进行延迟短路评估的动态语言。在静态语言中,它将不会编译(类型错误)。在渴望评估布尔表达式的语言中,它将返回逻辑值(在这种情况下为true)。
这个问题已经收到了几个很好的答案。
总之,该技术利用了语言的编译功能。也就是说,JavaScript“短路”布尔运算符的求值,并将返回与第一个非false变量值或最后一个变量包含的值关联的值。请参阅Anurag对这些将评估为false的值的解释。
由于多种原因,使用此技术不是一种好的做法。然而。
-
代码可读性:这是使用布尔运算符,如果不了解其编译方式,则预期结果将是布尔值。
-
稳定性:这是一种使用语言编译功能的特性,该特性在多种语言之间是不一致的,因此,将来有可能将其作为目标进行更改。
-
记录的功能:有一个现有的替代方案可以满足此需求,并且在更多语言之间保持一致。这将是三元运算符:
()?值1:值2。
使用三元运算符确实需要更多类型的输入,但是它可以清楚地区分所评估的布尔表达式和所分配的值。另外,它可以被链接,因此可以重新创建上面执行的默认分配的类型。
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = ( a ) ? a :
( b ) ? b :
( c ) ? c :
( d ) ? d :
e;
alert(f); // 4
返回输出第一个真值。
如果全部为假,则返回最后一个假值。
例:-
null || undefined || false || 0 || 'apple' // Return apple
它将新变量(z
)设置为x
“真”(非零,有效对象/数组/函数/无论是什么)的值或y
其他值。这是在x
不存在的情况下提供默认值的一种相对常见的方法。
例如,如果您的函数具有可选的回调参数,则可以提供不执行任何操作的默认回调:
function doSomething(data, callback) {
callback = callback || function() {};
// do stuff with data
callback(); // callback will always exist
}
这意味着如果x
设置了,则for的值z
将为x
,否则,如果y
设置则其值将被设置为z
的值。
和...一样
if(x)
z = x;
else
z = y;
这可能是因为JavaScript中的逻辑运算符不会返回布尔值,而是完成操作所需的最后一个元素的值(在OR语句中,它将是第一个非false值;在AND语句中,它将是最后一个非false值。 )。如果操作失败,则false
返回。
它称为短路运算符。
短路评估表示,仅当第一个参数不足以确定表达式的值时,才执行或评估第二个参数。当OR(||)函数的第一个参数评估为true时,总值必须为true。
它也可以用来设置函数参数的默认值。
function theSameOldFoo(name){
name = name || 'Bar' ;
console.log("My best friend's name is " + name);
}
theSameOldFoo(); // My best friend's name is Bar
theSameOldFoo('Bhaskar'); // My best friend's name is Bhaskar`
它将计算X,如果X不为null,则为空字符串或0(逻辑假),然后将其分配给z。如果X为null,空字符串或0(逻辑假),则它将y分配给z。
var x = '';
var y = 'bob';
var z = x || y;
alert(z);
将输出'bob';
根据比尔·希金斯的博客文章;Java逻辑OR分配习惯用法(2007年2月),此行为自v1.2开始(至少)
他还提出了另一种用法(引用):“跨浏览器差异的轻量级标准化”
// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;
文章标签:javascript , or-operator , variable-assignment , variables
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!