What is "x && foo()"? - javascript

I saw somewhere else said,
x && foo();
 is equal to
if(x){
foo();
}
I tested it and they really did the same thing.
But why? What exactly is x && foo()?

Both AND and OR operators can shortcut.
So && only tries the second expression if the first is true (truth-like, more specifically). The fact that the second operation does stuff (whatever the contents of foo() does) doesn't matter because it's not executed unless that first expression evaluates to something truthy. If it is truthy, it then will be executed in order to try the second test.
Conversely, if the first expression in an || statement is true, the second doesn't get touched. This is done because the whole statement can already be evaluated, the statement will result in true regardless of the outcome of the second expression, so it will be ignored and remain unexecuted.
The cases to watch out for when using shortcuts like this, of course, are the cases with operators where defined variables still evaluate to falsy values (e.g. 0), and truthy ones (e.g. 'zero').

This is known as short-circuit evaluation.
In this case, if x is False, then foo() doesn't need to be evaluated (the result of && will always be False); if x is True, it does need to be evaluated (even if the result is thrown away).

It's not exactly equivalent. The first one is an expression with a return value you can use; the second one is a statement.
If you are not interested in the return value (that is, the information whether both x and foo() evaluate to a truthy value), they are equivalent, but normally, you should use the boolean-logic version only if you want to use it as a boolean expression, e.g.:
if (x && foo()) {
do_stuff();
}
If you are only interested in running foo() conditionally (when x is truthy), the second form is to be preferred, since it conveys the intention more clearly.
A reason people might prefer the boolean-logic version might be that javascript is subject to an unusual restriction: source code size (more verbose source code means more bandwidth used); since the boolean-logic version uses less characters, it is more bandwidth-efficient. I'd still prefer the more verbose version most of the time, unless the script in question is used a lot - for a library like jQuery, using optimizations like this is perfectly justifyable, but in most other cases it's not.

In javascript, the && operator evaluates left to right and returns the value of the rightmost operation. If the first condition evaluates to false, it doesn't evaluate the second. So its a shorthand of saying "if something is not null or undefined, do something"

It is short circuiting.
The && operator works like this: It does the logical or of the two operands on both side. If the left hand side has a non zero value then the right hand side is evaluated to determine the truth value. If the left hand side is zero then whatever the right hand side be, the expression will evaluate to 0, therefore the right hand side is not evaluated. So in effect, if x is non-zero then only foo is called, and if x is 0 then foo is not called, and thus, it works like if - else in this case.

Related

Why | and || are similar to a semicolon in Javascript?

I was testing some stuff on Console on Chrome and then I ran that piece of code:
alert() | window.confirm();
alert() || window.confirm();
My problem was to run both alert and confirm methods in a single line without using semicolon. It turns out that both | and || worked and I can't imagine why it worked, firstly because || means an OR operator which should run one of them not both and secondly | I don't know what it is. Can someone explain what happened and what else should work instead of ;?
A semicolon indicates the end of a statement.
If you aren't already aware, an expression is something which evaluates to a value. For example, 5, 'foobar', and myFn() are all expressions, because they evaluate to values.
Statements can be composed of multiple expressions. For example, const result = fn('foo') passes the 'foo' expression into the function call, and the function call returns a value which is assigned to result.
In your code, both lines are composed of two expressions, but each line happens to be a single statement. With this line:
alert() || window.confirm()
will first evaluate alert. Since alert returns undefined, the || operator then evaluates the expression on the right, which is window.confirm().
You can put multiple expressions together on the same by using operators like |, ||, or =. You can also evaluate multiple expressions by putting each as a separate statement, like
alert();
window.confirm();
Both will result in an alert box and a confirm dialog coming up.
alert() returns undefined, which is false-y. Therefore, window.confirm() will still run, for your example of ||.
As for a single pipe character |, that's a bitwise-OR, which you can read about here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise
The || is an operator, like + or /; it calculates something. In the case of ||, it calculates whether one OR the other value is true.
Normally, you'd use that in something like an if statement: if (i===0 || j===0) {...} but it's not restricted to that; for instance, you could put the result in a variable, then use it in an if statement later: have_zero = i===0 || j===0; ...; if (have_zero) {...}
The || (and &&) operators do have one special thing: if the left side determines the answer, they don't bother calculating the right side (called "short-circuit evaluation").
Here, you're calculating alert() || window.confirm(), so it calls alert(); as others have noted, this returns undefined which doesn't determine the answer to the ||, so Javascript then calls window.confirm(). The answer is then thrown away, because you're not putting it in a variable or otherwise using it, but that's OK - you wanted to call the methods, you weren't interested in the answer.

Weird Code - Dynamic properties in primitive and reference variables in javascript (JS)

I'm working through Learning Javascript Properly and am reading Chapter 4 of Professional Javascript for Web Developers. On p. 86 they say
Primitive values can’t have properties added to them even though
attempting to do so won’t cause an error. Here’s an example:
var name = “Nicholas”;
name.age = 27;
alert(name.age); //undefined
They also say that JavaScript does not treat strings as objects, like other languages do. I wanted to see if I could get it to print out name.age.
I tried
var name = "Nicholas";
name.age = 27, alert(name.age);
And got undefined.
Trying
var name = "Nicholas";
name.age = 27 & alert(name.age);
Also gave undefined.
But,
var name = "Nicholas";
alert(name.age = 27);
gives 27!
With regards to the text's original example, the author says
"Here a property called age is defined on the string name and assigned
a value of 27. On the very next line, however, the property is gone.
Only reference values can have properties defined dynamically for
later use."
What is going on with the comma separated assignment and function call - I knew you could use commas to separate variable assignments, but you can also do function calls? What are the limits to the comma in javascript?
How does the & operator work for chaining together code snippets? What is that operator and what should it be used for?
Why did my last example work when the other ones wouldn't? Does this have to do with scope?
Edit: Thanks JLRishe and SirReal. I didn't really understand JLRishe's answer until reading SirReal's, but I recommend reading both!
Really, the answer to all three of your questions has to do with how the ,, & and = operators are defined, and has nothing to do with properties on primitive values.
What is going on with the comma separated assignment and function call
Your second example is an example of the comma operator, and this is different from the comma used in variable declarations. It evaluates each of its operands one at a time from left to right, and the ultimate value of the expression is the value of the last operand.
How does the & operator work for chaining together code snippets?
The & operator evaluates its two operands from left to right and produces the result of applying a bitwise AND to them. Your alert() is executing as a side effect of this. The expression 27 & alert(name.age) evaluates to 0, and this is what is assigned to name.age (but this doesn't really do anything). You can see similar behavior with:
name.age = 27 * alert(name.age);
or
name.age = 27 - alert(name.age);
or several other operators.
Why did my last example work when the other ones wouldn't?
What you observed in your last example is the well-defined behavior of the = operator. It performs an assignment and produces the value of the right-hand side. The assignment doesn't actually happen in this case, for the reasons you quoted, but it evaluates to the value of the right-hand nonetheless, and that is what is passed to the alert() function.
& is bitwise AND, a comparison operator. It's used to compare values at the bit level. You should probably not be using this for chaining code together.
, (comma) is the comma operator.
The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.
There don't appear to be any limits to that, but there are not a lot of good reasons to abuse this. MDN suggests that this is mostly for working with multiple values in for loops.
=, the simple assignment operator allows chaining. That means x = y = 2 is valid and will result in x == 2 and y == 2. I haven't found explicit documentation to support this, but I think it's safe to infer that the result of the assignment is returned when using =, which is the strange behavoir you're seeing. While you can't actually set a property on a string, the value you try to set is returned in case you wanted to chain it or otherwise use it.
You can't think like this in javascript. Variable assignment will work in this context if the variable can be assigned but has no bearing on the value passed to the function, that is, in this case 27, not name.age.
var name = "Nicholas";
alert(name.age = 27);
This will always alert an integer of 27. This is because you are not just assigning the name.age property a value, you are also passing the value to the alert function regardless of the property you attempted to assign the value to.
Comma operators string together operands and evaluate them in the order that you define them. As they are evaluated separately name.age has no value when it is evaluated as the second operand in your example.
The & operator is a bitwise operator that converts both sides to integers and evaluates both sides as their 32 bit binary representations. As other comments and answers have pointed out if either the left or right side is NaN it is treated as 0.
Irrelevant detail added in original answer below
&& evaluates left to right, similar to comma operators, however if the left side evaluates to false, the right side is never evaluated. This allows you to chain a check and an evaluation together without errors. This is called short circuiting.
callback instanceof Function && callback();
The above example checks if callback is a function, only if it is TRUE will the right hand side be evaluated.
The reason alert(name.age = 27) works is because of how primitive wrapper types operate. Primitive values like booleans, numbers, and strings in javascript are treated as objects in certain special cases, permitting the use of methods (like substring()).
Normally, a primitive value would not be able to call a method since it is considered a primitive, not an object (reference type). However, there are primitive wrapper types that enable this to work behind the scenes.
The three primitive wrapper types are Number, Boolean, and String and correspond to their respective primitive values. When you execute a method on a primitive value what is actually happening is the following:
The primitive value is cast as an instance of the primitive wrapper type
The method is executed on the primitive wrapper instance (an object)
The primitive wrapper instance is destroyed (your value goes back to being a regular primitive value).
The variable name in the code example is a string primitive value. When the property .age is added to it, it must first be cast as an instance of the primitive wrapper type String. However, that instance is immediately destroyed after that call executes, which is why the only call that does not return undefined is the one that alerts the property at the same time it is assigned.
The major difference between reference types and primitive wrapper types is the lifetime of the object. When you instantiate a reference
type using the new operator, it stays in memory until it goes out of
scope, whereas automatically created primitive wrapper objects exist
for only one line of code before they are destroyed. This means that
properties and methods cannot be added at runtime. Take this for
example:
var s1 = “some text”;
s1.color = “red”;
alert(s1.color);//undefined
Here, the second line attempts to add a color property to
the string s1. However, when s1 is accessed on the third line, the
color property is gone. This happens because the String object that
was created in the second line is destroyed by the time the third line
is executed. The third line creates its own String object, which
doesn’t have the color property. (Zakas, 147)
This is also why the following code would have worked:
var name = new String("Nicholas");
name.age = 27;
alert(name.age); //27
Here we have an explicit construction of an instance of the String primitive wrapper type, so it survives as an actual object.
Source: Zakas, Professional Javascript for Web Developers, p. 147 3rd ed.

Mozilla states expressions are also statements. Why?

Looking at these articles from Mozilla's JavaScript guide:
Expressions
Statements
expressions are also considered assignment statements. In fact, in the second article one can read "any expression is also a statement". Being acquainted with other programming languages, I thought that expressions are always values, but they never cause side effects like statements would do. In other words, 7, 7 + 8, "string", etc., are expressions, because they don't change the state, but a = 7 is a statement, since a variable has now been defined (i.e. a state has changed).
Why would Mozilla not differentiate between the two in JS?
I believe you are taking the terms "expression" and "statement" too literally. "Expressions not changing any state" is a very tough requirement for a programming language.
A thought experiment: In 7 + 8 substitute 8 with a function call to
var globalVar = 0;
function my8() {
globalVar = globalVar + 1;
return 8;
}
Is 7 + my8() a statement or an expression? There is no obvious state change happing here, but still my8 performs a state change. Using the "no side-effects" definition it would be impossible to decide if 7 + my8() is a statement or an expression without analyzing the code of the my8 function. Of course it would be possible to simply prohibit any state change as part of a function call, but that is not the way of JavaScript.
In my experience most languages define "everything which returns a value" as an expression and a statement, everything else as just a statement.
To answer your question "Why would Mozilla not differentiate between the two in JS?":
I think they do, but not in the manner you expected. To consider "everything which returns a value" an expression seems to be the most practical approach.
Also there is no contradiction between a chunk of code being a statement and an expression at the same time. That is simply how Javascript and many other languages work. Of course it is always possible to draw a more strict line between those two.
Examples:
Assignments return values, so this is possible:
a = b = c = 1;
It can be written in the more obvious form:
a = (b = (c = 1));
Because of that an assignment is considered an expression (and also a statement).
On the other hand:
if (true) { };
does not return a value (in Javascript!) and therefore is no expression (but still a statement).
An expression is a code fragment that returns some value, Expression (Computer Science):
3; // 3
{}; // Object
func(); // whatever func returns, or undefined if not specified
You can combine expressions into one compound expression:
3 + 7; // 10
{}, []; // Array. Comma operator always returns result of right-most expression
A statement is the smallest valid code fragment that can be compiled or interpreted, Statement (Computer Science):
5; // valid js
You can also combine statements into compound statements:
check || func(); // valid js
{
4 + 9;
"block statement";
}
In the Mozilla documentation, a statement refers to any (compound) statement that is explicitly or implicitly terminated by semi-colon (;).
[,,[],[,[,,],,]]; // Array declaration whose reference is returned (and ignored)
// Multi-dimensional array with empty (undefined) elements
In some programming languages the above example doesn't compile or doesn't get interpreted. Other languages might not allow for the result of an expression not to be catched.
Javascript is very expressive, which is why every expression counts as a valid statement. Some statements are not expressions, like break, return, while, etc. They don't return any value, but they control the program execution flow.
Mozilla does differentiate between the two, or rather the Javascript syntax does.
The only slightly "special" about Javascript is the following:
"any expression is also a statement",
which means that at places where a statement is required in the syntax, an expression can be used directly (but not the other way around). E.g. the following is valid Javascript but invalid in many other similar languages:
if (true) "asfd"
or
foo = function(){
if (5) {
"some text here that won't do anything";
return true;
42; // always good to have that one here!
}
}
whereas statements cannot be used as expressions:
a = (if (true) 5) // does not work "unexpected token 'if'"
They used that "feature" for the strict mode specification without introducing a new keyword or syntax - if you add the expression "use strict" as the first statement in a function body, Javascript is executed in strict mode in supporting browsers.
While expressions evaluate to a value, usually, statements do not. Most statements alter control flow, expressions usually don't (although one could argue that an expression that results in an exception being thrown alters control flow, too).
In Javascript expressions form a subset of all statements.

Difference between statement and function

It's almost midnight and I just got a question in my head is "for loop" a statement or a function.
I always thought it is a statement, but I did a google search on it being a function and there are indeed results for that. So what is it? And in that case what is the difference between function and statement?
A for loop is a not usually a function, it is a special kind of statement called a flow control structure.
A statement is a command. It does something. In most languages, statements do not return values. Example:
print "Hello World"
A function is a subroutine that can be called elsewhere in the program. Functions often (but not necessarily) return values. Example:
function(a) { return a * 2 }
A control structure, also known as a compound statement, is a statement that is used to direct the flow of execution. Examples:
if (condition) then { branch_1 } else { branch_2 }
for (i = 0; i < 10; i += 1) { ... }
Also worth noting is that an expression is a piece of code that evaluates to a value. Example:
2 + 2
All examples are in pseudocode, not tied to any particular language. Also note that these are not exclusive categories, they can overlap.
Out of the three language tags you've chosen, I'm only very familliar with Python, but I believe many other languages have a similar view of these concepts. All the example code here is Python.
A statement is a thing that is executed; an "instruction to do something" that the language implementation understands. e.g.
print "Hello World"
pass
def foo(n):
return n + 1
if condition:
print 'yay'
else:
print 'doh'
The above block contains a print statement, a pass statement, a function definition statement, and an if/else statement. Note that the function definition and the if/else statement are compound statements; they contain other statements (possibly many of them, and possibly other compound statements).
An expression is something that can be evaluated to produce a value. e.g.
1
"foo"
2 * 6
function(argument)
None
The above contains a numeric literal expression, a string literal expression, an expression involving numeric operators, a function call expression, and the literal None expression. Other than literals and variables, expressions are made up of other expressions. In function(argument), function and argument are also both expressions.
The key difference is that statements are instructions that tell the language implementation to "go do something". Expressions are evaluated to a value (which possibly requires to language implementation to "go do something" on the way).
A consequence of this is that anywhere you see a value (including an expression), you could substitute any other expression and you would still get something that makes some sort of sense. It may fail to compile, or throw exceptions at runtime, or whatever, but on at least some level you can understand what's going on.
A statement can never appear inside an expression (I believe this is not true in Ruby and Javascript in some sense, as they allow literal code blocks and functions which are then used as a value as a whole, and functions and code blocks contain statements; but that's kind of different from what I'm talking about). An expression must have a value (even if it's an uninteresting one like None). A statement is a command; it doesn't make sense for it to appear as part of an expression, because it has no value.
Many languages also allow expressions to be used as statements. The usual meaning of this is "evaluate this expression to get a value, then throw it away". In Python, functions that always return None are usually used this way:
write_to_disk(result)
It's used as a "command", so it looks like a statement, but technically it's an expression, we just don't use the value it evaluates to for anything. You can argue that a "bare expression" is one of the possible statements in a language (and they're often parsed that way).
Some languages though distinguish between functions that must be used like statements with no return value (often called procedures) and functions that are used like an expression, and give you errors or warnings for using a function like a statement, and definitely give you an error for using a procedure as an expression.
So, if foo is an expression, I can write 1 + foo and while it may be result in a type error, it at least makes that much sense. If foo is a statement, then 1 + foo is usually a parse error; the language implementation won't even be able to understand what you're trying to say.
A function on the other hand, is a thing you can call. It's not really either an expression or a statement in itself. In Python, you use a def statement to create a function, and a function call is an expression. The name bound to the function after you create it is also an expression. But the function itself is a value, which isn't exactly an expression when you get technical, but certainly isn't a statement.
So, for loops. This is a for loop in Python:
for thing in collection:
do_stuff(thing)
Looks like a statement (a compound statement, like an if statement). And to prove it, this is utterly meaningless (and a parse error):
1 + for thing in collection:
do_stuff(thing)
In some languages though, the equivalent of a for loop is an expression, and has a value, to which you can attempt to add 1. In some it's even a function, not special syntax baked into the language.
This answer is relevant to Python 2.7.2. Taken from the python tutorial:
"4. More Control Flow Tools
4.2. for Statements:
The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence."

Will `if(x=y)` Ever Return false, or fail In JavaScript?

This is a theoretical question, as I can't imagine any practical uses.
I made a bold statement today saying that in JavaScript, the following will always return true:
if (x=y){
//code
}
And the //code, whatever it is, will always be executed.
This is the classic typo of not entering == or even ===.
This feature can also be demonstrated in C/C++, but being more strongly-typed languages than JavaScript, it is not hard to think instances where this assignment will fail.
However, in JavaScript, given two variables x and y, I was struggling to think of an occation where this would fail, or the proceding conditional code block would not execute.
Anyone?
It (x=y) would evaluate to false if y=0, y=null, y=undefined or y=false.
Edit: Also if y=NaN
Edit: Also if y=""
The conditional block "x=y" will always execute. But in javascript "false", undefined, null, and 0 evaluate to false. So whenever y is one of those values, the "//code" will not be executed.
js
js> if(x=y){
print('hello');
}
typein:1: ReferenceError: y is not defined
js>

Categories

Resources