Javascript truthy and falsy , Javascript logic operators || and &&
2013-03-12 16:04
579 查看
In JavaScript, logical operators are used for boolean logic where a boolean value may be returned depending on the outcome of an expression. With the
view plaincopy to clipboardprint?
var bar = false,
foobar = 5,
foo = bar ||foobar; // foo = 5
In this case,
This pattern might look familiar as if you've written jQuery plugins before or used
view plaincopy to clipboardprint?
function( options ) {
options = $.extend({}, defaults, options ||{});
}
Some developers also like using the
view plaincopy to clipboardprint?
var foo = bar ||null;
Commonly, you're unlikely to want
You may also see developers opting for this approach to default-namespacing, where rather than opting for a two-line statement consisting of
view plaincopy to clipboardprint?
var namespace = namespace ||{
utils:{},
core:{}
};
view plaincopy to clipboardprint?
console.log(null ||NaN ||undefined ||false ||0 ||10);
// outputs: 10
What's happening here isn't quite magic—the expression is simply being lazily evaluated. The interpreter checks the value of the first part of the statement,
If you're interesting in reading up more about the evaluation technique used in this example, check out short-circuit evaluation.
So, where is any of this useful? The OR operator can be applied to functions where we wish to provide a default value (as we've seen earlier) if falsy-ness is incurred as follows:
view plaincopy to clipboardprint?
function foo( a, b ){
a = a ||5;
b = b ||6;
console.log( 'Values:' + a + ',' +b );
}
Although, you're more likely to see a ternary to solve this problem in the wild, or perhaps something similar to this:
view plaincopy to clipboardprint?
if(a && a === 5){
// do something
}else{
// do something else
}
You may be wondering why. In my opinion it comes down to two things:
Readability: Some developers feel that if/else is easier to read and it can certainly save time when you don't have to evaluate the expression in your mind while looking through code. I would argue that we still have to do the same with if/else, but it comes down to a matter of preference at the end of the day.
Performance: The developers I've discussed the OR operator with have had a perception that if statements had to be more performant than ||, however I believed they had to be at least equivalent performance-wise.
Performance testing: OR vs IF
view plaincopy to clipboardprint?
var caseTrue = false;
function sum(){
return 100 + 10;
}
// test 1
caseTrue ||sum();
// test 2
if(!caseTrue){
sum();
}
view plaincopy to clipboardprint?
var bar = 5;
bar == 5 && console.log('bar equals 5');
// outputs: bar equals 5
bar == 8 ||console.log('bar does not equal 8');
// outputs: bar does not equal 8
And just for the curious:
view plaincopy to clipboardprint?
bar == 5 ||console.log('bar equals 5');
// evaluates to true
bar == 8 && console.log('bar does not equals 8');
// evaluates to false
The logical OR operator can also however be used in a number of other places:
view plaincopy to clipboardprint?
('foo' ||'bar'); // returns foo
Although a specific falsy value hasn't been assigned to either side above, the first object is considered truthy in this case, which is why
Extending the 'default value' concept slightly, it's possible to define functions that either execute specific methods defined within a namespace, or define those methods if they don't exist. This can be done a number of different ways (with optional type-checking), but a basic example could look like:
view plaincopy to clipboardprint?
function helloWorld( fn ){
(fn.method = fn.method ||function() {
console.log('foo');
})();
}
helloWorld({}); // outputs: foo
//passing in an object with a method
helloworld({
method:function(){
console.log('boo');
}
}); //outputs boo
The
Querying the DOM for an element if a reference we expect to be cached is falsy/undefined
Dynamically creating the element if the result of querying the DOM is that the element didn't exist and thus returned an empty result.
view plaincopy to clipboardprint?
// bar, either undefined or a cached selection of $('#bar')
// var bar = $('#bar');
var bar;
// if bar isn't undefined/falsey, use bar, otherwise query the
// DOM for the div 'bar' so we can cache it in 'foo' if
// bar has a valid length (i.e isn't an empty collection)
// if bar doesn't exist in the global scope and isn't currently
// in the DOM, we'll dynamically create a div and set it's ID to
// 'bar' instead.
var foo = bar = bar && bar.length && bar ||
(bar = $('#bar')).length ? bar :
$('<div />', { id: 'bar' });
console.log(foo, bar);
You can try out the above code sample here:http://jsfiddle.net/dY5W9/6/
The above approach to solving this problem should typically not be used in production environments and is only shown for demonstration purposes. There are far simpler (and more readable) ways this problem can be solved.
Finally, here are some further experiments using the OR operator, just in case you're interested in how truthy/falsy/other values are evaluated:
view plaincopy to clipboardprint?
true ||true // returns true
false ||true // returns true
true ||false // returns true
false ||(5 === 6) // returns false
"foo" ||"bar" // returns foo
false ||"bar" // returns bar
"foo" ||false // returns foo
(0 ||'bar'); // returns bar
(false ||true ||false ||false); // true
(false ||false ||true); // true
Nearly every website on the internet uses javascript in some form or fashion. Yet very few people, even those who write it and teach it, have a clear understanding of how javascript works!
Logical Operators are a core part of the language. We’re going to look at what logical operators are, what “truthy” and “falsy” mean, and how to use this to write cleaner, faster and more optimized javascript.
An empty string (
Gotchas to watch out for: the strings “0″ and “false” are both considered truthy. You can convert a string to a number with the
As one commenter mentioned, arrays are particularly weird. If you just test it for truthyness, an empty array is truthy. HOWEVER, if you compare an empty array to a boolean, it becomes falsy:
Another commenter pointed out an additional gotcha to watch out for: while javascript evaluates empty arrays as true, PHP evaluates them as false.
PHP also evaluates “0″ as falsy. (However the string “false” is evaluated as truthy by both PHP and javascript.)
Logical OR,
The logical OR operator,
Where would you ever use this? The OR operator allows you to easily specify default variables in a function.
Logical AND,
The logical AND operator,
The logical AND allows you to make one variable dependent on another.
Logical NOT,
Unlike
Another useful way to use the
see also :
http://addyosmani.com/blog/exploring-javascripts-logical-or-operator/ http://nfriedly.com/techblog/2009/07/advanced-javascript-operators-and-truthy-falsy/
||(OR) operator, since values don't need to be explicitly
trueor
false(they can be truthy or falsy), the operator can return non-boolean results when evaluated.
Introduction
To understand the||operator, let's first look at a fairly basic example. The logical OR operator may be used to provide a default value for a defined variable as follows:
view plaincopy to clipboardprint?
var bar = false,
foobar = 5,
foo = bar ||foobar; // foo = 5
In this case,
foowill only be assigned the value of
foobarif
baris considered falsy. A falsy value could be considered being equal to
0,
false,
undefined,
null,
NaNor empty (e.g
"").
This pattern might look familiar as if you've written jQuery plugins before or used
$.extend(), you'll see it implemented when checking for an options object to either be specified or set to an explicit default value:
view plaincopy to clipboardprint?
function( options ) {
options = $.extend({}, defaults, options ||{});
}
Some developers also like using the
||operator to set explicit
nullvalues when handling falsy values in an application. This helps ensure that values are intentionally nullified:
view plaincopy to clipboardprint?
var foo = bar ||null;
Commonly, you're unlikely to want
nullvalues but when you do, there's a certain comfort in not having to wonder if it's a desired value or if it indeed should be a nullified property or variable.
You may also see developers opting for this approach to default-namespacing, where rather than opting for a two-line statement consisting of
namespace = namespace ||{}and populating the object later, this is all done at once as follows:
view plaincopy to clipboardprint?
var namespace = namespace ||{
utils:{},
core:{}
};
Behind The Scenes
Now, JavaScript variables aren't typed, so a variable may be assigned a value (e.g. a number), despite being assigned through boolean operators:view plaincopy to clipboardprint?
console.log(null ||NaN ||undefined ||false ||0 ||10);
// outputs: 10
What's happening here isn't quite magic—the expression is simply being lazily evaluated. The interpreter checks the value of the first part of the statement,
null, establishes that it's falsy and continues moving forward until a falsy value isn't found (or if no truthy value is found, returning the last value). It's a neat trick that works in dynamic languages beyond just JavaScript, but won't work in static languages, where a type error will be thrown if you try the above.
If you're interesting in reading up more about the evaluation technique used in this example, check out short-circuit evaluation.
So, where is any of this useful? The OR operator can be applied to functions where we wish to provide a default value (as we've seen earlier) if falsy-ness is incurred as follows:
view plaincopy to clipboardprint?
function foo( a, b ){
a = a ||5;
b = b ||6;
console.log( 'Values:' + a + ',' +b );
}
Although, you're more likely to see a ternary to solve this problem in the wild, or perhaps something similar to this:
view plaincopy to clipboardprint?
if(a && a === 5){
// do something
}else{
// do something else
}
You may be wondering why. In my opinion it comes down to two things:
Readability: Some developers feel that if/else is easier to read and it can certainly save time when you don't have to evaluate the expression in your mind while looking through code. I would argue that we still have to do the same with if/else, but it comes down to a matter of preference at the end of the day.
Performance: The developers I've discussed the OR operator with have had a perception that if statements had to be more performant than ||, however I believed they had to be at least equivalent performance-wise.
Performance Testing
With the aid of jsPerf, we can test out one example of OR vs IF to find out how they compare:Performance testing: OR vs IF
view plaincopy to clipboardprint?
var caseTrue = false;
function sum(){
return 100 + 10;
}
// test 1
caseTrue ||sum();
// test 2
if(!caseTrue){
sum();
}
More Tricks
Now that we've looked at performance testing, there are a few other tricks that the logical operator can be used for. In the following example if the expression on the left evaluates totrue, a positive equality message is logged whilst evaluating to
falsehas the opposite effect.
view plaincopy to clipboardprint?
var bar = 5;
bar == 5 && console.log('bar equals 5');
// outputs: bar equals 5
bar == 8 ||console.log('bar does not equal 8');
// outputs: bar does not equal 8
And just for the curious:
view plaincopy to clipboardprint?
bar == 5 ||console.log('bar equals 5');
// evaluates to true
bar == 8 && console.log('bar does not equals 8');
// evaluates to false
The logical OR operator can also however be used in a number of other places:
view plaincopy to clipboardprint?
('foo' ||'bar'); // returns foo
Although a specific falsy value hasn't been assigned to either side above, the first object is considered truthy in this case, which is why
foois returned. The second object would be returned if the first was falsy.
Extending the 'default value' concept slightly, it's possible to define functions that either execute specific methods defined within a namespace, or define those methods if they don't exist. This can be done a number of different ways (with optional type-checking), but a basic example could look like:
view plaincopy to clipboardprint?
function helloWorld( fn ){
(fn.method = fn.method ||function() {
console.log('foo');
})();
}
helloWorld({}); // outputs: foo
//passing in an object with a method
helloworld({
method:function(){
console.log('boo');
}
}); //outputs boo
The
||operator could also be used in combination with a ternary to support:
Querying the DOM for an element if a reference we expect to be cached is falsy/undefined
Dynamically creating the element if the result of querying the DOM is that the element didn't exist and thus returned an empty result.
view plaincopy to clipboardprint?
// bar, either undefined or a cached selection of $('#bar')
// var bar = $('#bar');
var bar;
// if bar isn't undefined/falsey, use bar, otherwise query the
// DOM for the div 'bar' so we can cache it in 'foo' if
// bar has a valid length (i.e isn't an empty collection)
// if bar doesn't exist in the global scope and isn't currently
// in the DOM, we'll dynamically create a div and set it's ID to
// 'bar' instead.
var foo = bar = bar && bar.length && bar ||
(bar = $('#bar')).length ? bar :
$('<div />', { id: 'bar' });
console.log(foo, bar);
You can try out the above code sample here:http://jsfiddle.net/dY5W9/6/
The above approach to solving this problem should typically not be used in production environments and is only shown for demonstration purposes. There are far simpler (and more readable) ways this problem can be solved.
Finally, here are some further experiments using the OR operator, just in case you're interested in how truthy/falsy/other values are evaluated:
view plaincopy to clipboardprint?
true ||true // returns true
false ||true // returns true
true ||false // returns true
false ||(5 === 6) // returns false
"foo" ||"bar" // returns foo
false ||"bar" // returns bar
"foo" ||false // returns foo
(0 ||'bar'); // returns bar
(false ||true ||false ||false); // true
(false ||false ||true); // true
Wrapping Up
That's it! Whilst||has many potential uses, always remember to factor in readability of your code when opting to use it. If you have any other gotchas, corrections or comments to share, feel free to leave them below and we'll get back to you. Happy coding.
Nearly every website on the internet uses javascript in some form or fashion. Yet very few people, even those who write it and teach it, have a clear understanding of how javascript works!
Logical Operators are a core part of the language. We’re going to look at what logical operators are, what “truthy” and “falsy” mean, and how to use this to write cleaner, faster and more optimized javascript.
Javascript Logical Operators
In traditional programming, operators such as&&and
||returned a boolean value (
trueor
false). This is not the case in javascript. Here it returns the actual
object, not a
true/
false. To really explain this, I first have to explain what is truthy and what is falsy.
Truthy or Falsy
When javascript is expecting abooleanand it’s given something else, it decides whether the something else is “truthy” or “falsy”.
An empty string (
''), the number
0,
null,
NaN, a boolean
FALSE, and
undefinedvariables are all “falsy”. Everything else is “truthy”.
parseInt()and
parseFloat()functions, or by just multiplying it by 1.
PHP also evaluates “0″ as falsy. (However the string “false” is evaluated as truthy by both PHP and javascript.)
How Logical Operators Work
Logical OR, ||
The logical OR operator, ||, is very simple after you understand what it is doing. If the first object is truthy, that gets returned. Otherwise, the second object gets returned.
Logical AND, &&
The logical AND operator, &&, works similarly. If the first object is falsy, it returns that object. If it is truthy, it returns the second object.
Logical NOT, !
Unlike &&and
||, the
!operator DOES turn the value it receives into a boolean. If it receives a truthy value, it returns
false, and if it receives a falsy value, it returns
true.
!operator is to use two of them – this way you always get a
trueor a
falseno matter what was given to it.
http://addyosmani.com/blog/exploring-javascripts-logical-or-operator/ http://nfriedly.com/techblog/2009/07/advanced-javascript-operators-and-truthy-falsy/
相关文章推荐
- Truthy and Falsy Values in JavaScript
- Truthy and Falsy: When All is Not Equal in JavaScript
- Groovy truthy and falsy
- usage of >>>、>> and << operators
- <<High Performance JavaScript>>读书笔记-5.Strings and Regular Expressions
- JavaScript: DHTML API,Drag & Drop for Images and Layers
- AndAlso & OrElse Operators in C#短路运算符
- 全面解析JavaScript中或者(或 or ||)与并且(与 and &&)
- JavaScript Var 'Undefined' in Firefox; IE and Opera Work fine
- javascript || and &&
- Truth, Equality and JavaScript
- JavaScript Comparison and Logical Operators
- JavaScript_A Beginner's Guide - Conditional Statements and Loops - 09/23/2012
- LINQ LINQ Operators and Lambda Expression - Syntax & Examples
- JavaScript Comparison and Logical Operators
- Truthy Vs Falsy Values in JavaScript
- O'Reilly JavaScript and DHTML Cookbook
- Top JavaScript Frameworks, Libraries & Tools and When to Use Them
- About the difference of href='javascript:void(0)' and href=‘#’
- K&R C Bible Increment and Decrement Operators