Cannot understand JavaScript instruction - javascript

I am interested in the Wasabi tool.
Please have a look on this piece of code.
I don't understand this instruction:
var W = window.Wasabi = window.Wasabi || {};
My final purpose is to adjust a CSS property, dynamically loaded by the JavaScript...
Thanks for the help.

Two things going on here.
Logical OR operator:
a||b will return a if a is truthy or b otherwise.
so window.Wasabi||{} mean return window.Wasabi if it is defined or otherwise return a new empty object.
Double assignment:
c=d=1 set d equal to 1 and c equal to d. i.e. set c and d to 1.
Putting these two things together:
if window.Wasabi is set already then just get a reference to it and store that in W. Otherwise create a new object, store a reference in window.Wasabi (to use next time) and call it W for use now.

If window.Wasabi doesn't exist, then window.Wasabi will be equal to {}. If it already exist, then don't change it. Finally, assign W to window.Wasabi. So, it would be like this code:
var W;
if (!window.Wasabi) {
window.Wasabi = {};
}
W = window.Wasabi;

There are 2 not-so-obvious things in this statement. There's the 2 consecutive equals, and the || at the end. They are not related so Ill tackle them one by one.
var W=window.Wasabi=window.Wasabi;
//Shorthand for
var window.Wasabi=window.Wasabi;
var W=window.Wasabi;
In english, that'd be: W equals window.Wasabi which equals window.Wasabi.
Now, the || is an OR in an operation, it states to take the left most value, if it's a truthy value, OR the one on the right.
var window.Wasabi=window.Wasabi||{};
//equates to
var window.Wasabi;
if(window.Wasabi){
window.Wasabi=window.Wasabi;
}else{
window.Wasabi={};
}
This pattern is very useful to give a default value to a variable. This will answer that Wasabi is at least an object...

There are two main javascript concepts to understand in this statement.
The first one is :
var x = y || {}
This is equivalent to :
if (y)
x = y
else {
x = {}
If y is truethy, then its value will be assigned to x. Else, x will be equal to {} (an empty object)
The second one is :
a = b = "something"
b will be assigned the value "something" and a will be assigned the value of b (which was just set to "something")
Both a and b will be assigned the value "something".
Application to your example :
var W=window.Wasabi=window.Wasabi||{};
If window.Wasabi is not defined (or is falsy), then it will be assigned to {}.
Then the W variable will be assigned the value of window.Wasabi.
Is window.Wasabi is defined, then it will be assigned to the value of itself (nothing will happen), and W will be assigned the value of window.Wasabi.
It's a pretty dirty way to set the initial value of an object if it doesn't exist, but... it works.

Related

Object definition in old Javascript

I came accross a following piece of code and i got confused and unable to understand the syntax used.
I would need help to break some hightlighted
let HT = HT || {}; //What is this syntax and what does it do ?
//Are we adding an Hexagon object to the object HT ?
HT.Hexagon = function(id, x, y) {
}
//Are we adding an object named Orientation to the object Hexagon ?
HT.Hexagon.Orientation = {
Normal: 0,
Rotated: 1
};
//Are we adding an object named Static to the object Hexagon ?
HT.Hexagon.Static = {
HEIGHT:91.14378277661477,
WIDTH:91.14378277661477,
SIDE:50.0,
ORIENTATION:HT.Hexagon.Orientation.Normal,
DRAWSTATS: false
};
How can one convert this piece of code to the modern ES6 classes ?
The first line code is using the or operator.
The operator checks first the expression on its left side - in this case the HT (it's probably an existing object.) If the expression is true e.g. holds a value like an object a number or a string etc, the expression will be assigned to the variable.
If HT does not hold any value which means it is false. Than it assign's the expression on its righte side - in this case an empty object.
The answer for your other three question is yes.
And it's not old JS at all.

Using logic in expressions [duplicate]

Given this snippet of 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
Can someone please explain to me what this technique is called (my best guess is in the title of this question!)? And how/why it works exactly?
My understanding is that variable f will be assigned the nearest value (from left to right) of the first variable that has a value that isn't either null or undefined, but I've not managed to find much reference material about this technique and have seen it used a lot.
Also, is this technique specific to JavaScript? I know doing something similar in PHP would result in f having a true boolean value, rather than the value of d itself.
See short-circuit evaluation for the explanation. It's a common way of implementing these operators; it is not unique to JavaScript.
This is made to assign a default value, in this case the value of y, if the x variable is falsy.
The boolean operators in JavaScript can return an operand, and not always a boolean result as in other languages.
The Logical OR operator (||) returns the value of its second operand, if the first one is falsy, otherwise the value of the first operand is returned.
For example:
"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"
Falsy values are those who coerce to false when used in boolean context, and they are 0, null, undefined, an empty string, NaN and of course false.
Javacript uses short-circuit evaluation for logical operators || and &&. However, it's different to other languages in that it returns the result of the last value that halted the execution, instead of a true, or false value.
The following values are considered falsy in JavaScript.
false
null
"" (empty string)
0
Nan
undefined
Ignoring the operator precedence rules, and keeping things simple, the following examples show which value halted the evaluation, and gets returned as a result.
false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"
The first 5 values upto NaN are falsy so they are all evaluated from left to right, until it meets the first truthy value - "Hello" which makes the entire expression true, so anything further up will not be evaluated, and "Hello" gets returned as a result of the expression. Similarly, in this case:
1 && [] && {} && true && "World" && null && 2010 // null
The first 5 values are all truthy and get evaluated until it meets the first falsy value (null) which makes the expression false, so 2010 isn't evaluated anymore, and null gets returned as a result of the expression.
The example you've given is making use of this property of JavaScript to perform an assignment. It can be used anywhere where you need to get the first truthy or falsy value among a set of values. This code below will assign the value "Hello" to b as it makes it easier to assign a default value, instead of doing if-else checks.
var a = false;
var b = a || "Hello";
You could call the below example an exploitation of this feature, and I believe it makes code harder to read.
var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);
Inside the alert, we check if messages is falsy, and if yes, then evaluate and return noNewMessagesText, otherwise evaluate and return newMessagesText. Since it's falsy in this example, we halt at noNewMessagesText and alert "Sorry, you have no new messages.".
Javascript variables are not typed, so f can be assigned an integer value even though it's been assigned through boolean operators.
f is assigned the nearest value that is not equivalent to false. So 0, false, null, undefined, are all passed over:
alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
There isn't any magic to it. Boolean expressions like a || b || c || d are lazily evaluated. Interpeter looks for the value of a, it's undefined so it's false so it moves on, then it sees b which is null, which still gives false result so it moves on, then it sees c - same story. Finally it sees d and says 'huh, it's not null, so I have my result' and it assigns it to the final variable.
This trick will work in all dynamic languages that do lazy short-circuit evaluation of boolean expressions. In static languages it won't compile (type error). In languages that are eager in evaluating boolean expressions, it'll return logical value (i.e. true in this case).
This question has already received several good answers.
In summary, this technique is taking advantage of a feature of how the language is compiled. That is, JavaScript "short-circuits" the evaluation of Boolean operators and will return the value associated with either the first non-false variable value or whatever the last variable contains. See Anurag's explanation of those values that will evaluate to false.
Using this technique is not good practice for several reasons; however.
Code Readability: This is using Boolean operators, and if the behavior of how this compiles is not understood, then the expected result would be a Boolean value.
Stability: This is using a feature of how the language is compiled that is inconsistent across multiple languages, and due to this it is something that could potentially be targeted for change in the future.
Documented Features: There is an existing alternative that meets this need and is consistent across more languages. This would be the ternary operator:
() ? value 1: Value 2.
Using the ternary operator does require a little more typing, but it clearly distinguishes between the Boolean expression being evaluated and the value being assigned. In addition it can be chained, so the types of default assignments being performed above could be recreated.
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
Return output first true value.
If all are false return last false value.
Example:-
null || undefined || false || 0 || 'apple' // Return apple
It's setting the new variable (z) to either the value of x if it's "truthy" (non-zero, a valid object/array/function/whatever it is) or y otherwise. It's a relatively common way of providing a default value in case x doesn't exist.
For example, if you have a function that takes an optional callback parameter, you could provide a default callback that doesn't do anything:
function doSomething(data, callback) {
callback = callback || function() {};
// do stuff with data
callback(); // callback will always exist
}
Its called Short circuit operator.
Short-circuit evaluation says, the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression. when the first argument of the OR (||) function evaluates to true, the overall value must be true.
It could also be used to set a default value for function argument.`
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`
It means that if x is set, the value for z will be x, otherwise if y is set then its value will be set as the z's value.
it's the same as
if(x)
z = x;
else
z = y;
It's possible because logical operators in JavaScript doesn't return boolean values but the value of the last element needed to complete the operation (in an OR sentence it would be the first non-false value, in an AND sentence it would be the last one). If the operation fails, then false is returned.
It will evaluate X and, if X is not null, the empty string, or 0 (logical false), then it will assign it to z. If X is null, the empty string, or 0 (logical false), then it will assign y to z.
var x = '';
var y = 'bob';
var z = x || y;
alert(z);
Will output 'bob';
According to the Bill Higgins' Blog post; the Javascript logical OR assignment idiom (Feb. 2007), this behavior is true as of v1.2 (at least)
He also suggests another use for it (quoted):
"lightweight normalization of cross-browser differences"
// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;

Trouble with beginner node.js concepts [duplicate]

Given this snippet of 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
Can someone please explain to me what this technique is called (my best guess is in the title of this question!)? And how/why it works exactly?
My understanding is that variable f will be assigned the nearest value (from left to right) of the first variable that has a value that isn't either null or undefined, but I've not managed to find much reference material about this technique and have seen it used a lot.
Also, is this technique specific to JavaScript? I know doing something similar in PHP would result in f having a true boolean value, rather than the value of d itself.
See short-circuit evaluation for the explanation. It's a common way of implementing these operators; it is not unique to JavaScript.
This is made to assign a default value, in this case the value of y, if the x variable is falsy.
The boolean operators in JavaScript can return an operand, and not always a boolean result as in other languages.
The Logical OR operator (||) returns the value of its second operand, if the first one is falsy, otherwise the value of the first operand is returned.
For example:
"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"
Falsy values are those who coerce to false when used in boolean context, and they are 0, null, undefined, an empty string, NaN and of course false.
Javacript uses short-circuit evaluation for logical operators || and &&. However, it's different to other languages in that it returns the result of the last value that halted the execution, instead of a true, or false value.
The following values are considered falsy in JavaScript.
false
null
"" (empty string)
0
Nan
undefined
Ignoring the operator precedence rules, and keeping things simple, the following examples show which value halted the evaluation, and gets returned as a result.
false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"
The first 5 values upto NaN are falsy so they are all evaluated from left to right, until it meets the first truthy value - "Hello" which makes the entire expression true, so anything further up will not be evaluated, and "Hello" gets returned as a result of the expression. Similarly, in this case:
1 && [] && {} && true && "World" && null && 2010 // null
The first 5 values are all truthy and get evaluated until it meets the first falsy value (null) which makes the expression false, so 2010 isn't evaluated anymore, and null gets returned as a result of the expression.
The example you've given is making use of this property of JavaScript to perform an assignment. It can be used anywhere where you need to get the first truthy or falsy value among a set of values. This code below will assign the value "Hello" to b as it makes it easier to assign a default value, instead of doing if-else checks.
var a = false;
var b = a || "Hello";
You could call the below example an exploitation of this feature, and I believe it makes code harder to read.
var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);
Inside the alert, we check if messages is falsy, and if yes, then evaluate and return noNewMessagesText, otherwise evaluate and return newMessagesText. Since it's falsy in this example, we halt at noNewMessagesText and alert "Sorry, you have no new messages.".
Javascript variables are not typed, so f can be assigned an integer value even though it's been assigned through boolean operators.
f is assigned the nearest value that is not equivalent to false. So 0, false, null, undefined, are all passed over:
alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
There isn't any magic to it. Boolean expressions like a || b || c || d are lazily evaluated. Interpeter looks for the value of a, it's undefined so it's false so it moves on, then it sees b which is null, which still gives false result so it moves on, then it sees c - same story. Finally it sees d and says 'huh, it's not null, so I have my result' and it assigns it to the final variable.
This trick will work in all dynamic languages that do lazy short-circuit evaluation of boolean expressions. In static languages it won't compile (type error). In languages that are eager in evaluating boolean expressions, it'll return logical value (i.e. true in this case).
This question has already received several good answers.
In summary, this technique is taking advantage of a feature of how the language is compiled. That is, JavaScript "short-circuits" the evaluation of Boolean operators and will return the value associated with either the first non-false variable value or whatever the last variable contains. See Anurag's explanation of those values that will evaluate to false.
Using this technique is not good practice for several reasons; however.
Code Readability: This is using Boolean operators, and if the behavior of how this compiles is not understood, then the expected result would be a Boolean value.
Stability: This is using a feature of how the language is compiled that is inconsistent across multiple languages, and due to this it is something that could potentially be targeted for change in the future.
Documented Features: There is an existing alternative that meets this need and is consistent across more languages. This would be the ternary operator:
() ? value 1: Value 2.
Using the ternary operator does require a little more typing, but it clearly distinguishes between the Boolean expression being evaluated and the value being assigned. In addition it can be chained, so the types of default assignments being performed above could be recreated.
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
Return output first true value.
If all are false return last false value.
Example:-
null || undefined || false || 0 || 'apple' // Return apple
It's setting the new variable (z) to either the value of x if it's "truthy" (non-zero, a valid object/array/function/whatever it is) or y otherwise. It's a relatively common way of providing a default value in case x doesn't exist.
For example, if you have a function that takes an optional callback parameter, you could provide a default callback that doesn't do anything:
function doSomething(data, callback) {
callback = callback || function() {};
// do stuff with data
callback(); // callback will always exist
}
Its called Short circuit operator.
Short-circuit evaluation says, the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression. when the first argument of the OR (||) function evaluates to true, the overall value must be true.
It could also be used to set a default value for function argument.`
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`
It means that if x is set, the value for z will be x, otherwise if y is set then its value will be set as the z's value.
it's the same as
if(x)
z = x;
else
z = y;
It's possible because logical operators in JavaScript doesn't return boolean values but the value of the last element needed to complete the operation (in an OR sentence it would be the first non-false value, in an AND sentence it would be the last one). If the operation fails, then false is returned.
It will evaluate X and, if X is not null, the empty string, or 0 (logical false), then it will assign it to z. If X is null, the empty string, or 0 (logical false), then it will assign y to z.
var x = '';
var y = 'bob';
var z = x || y;
alert(z);
Will output 'bob';
According to the Bill Higgins' Blog post; the Javascript logical OR assignment idiom (Feb. 2007), this behavior is true as of v1.2 (at least)
He also suggests another use for it (quoted):
"lightweight normalization of cross-browser differences"
// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;

JavaScript function arguments store by reference [duplicate]

This question already has answers here:
JavaScript by reference vs. by value [duplicate]
(4 answers)
Closed 9 years ago.
Not sure if this is the correct way to word my question. If I set up the following piece of JavaScript code:
var x = 5;
var y = function(z) {
z=7;
return z;
}
y(x);
x;
I get 7 returned from the function call but x stays its original value. I thought JavaScript variables call by reference so how come x's value isn't actually changed through the function?
The real problem here is that you're not mutating anything; you're just reassigning the variable z in the function. It wouldn't make a difference if you passed an object or array.
var x = ['test'];
var y = function(z) {
z=['foo'];
return z;
}
y(x);
x; // Still ['test']
Now, what others have said is also true. Primitives cannot be mutated. This is actually more interesting than it sounds, because the following code works:
> var x = 1;
> x.foo = 'bar';
"bar"
> x
1
> x.foo
undefined
Notice how the assignment to x.foo was seemingly successful, yet x.foo is nowhere to be found. That's because JavaScript readily coerces primitive types and object types (there are "object" versions of primitives, that are normal objects). In this case, the primitive 1 is being coerced into a new object (new Number(1)), whose foo attribute is getting set, and then it is promptly destroyed, so no lasting effects occur.
Thanks to #TeddHopp about this note:
Only the value is passed for all variables, not just primitives. You
cannot change a variable in the calling code by passing it to a
function. (Granted, you can change the object or array that may be
passed; however, the variable itself remains unchanged in the calling
code.)
If you want the value of x to change anyways you can do:
x = y(x);

Javascript: multiple variable declaration - when does the variable become available?

Let's say I'm declaring a list of variables in the following manner:
var a = "value_1"
, b = "value_2"
, c = b;
What is the expected value of c? In other words, is the scope of a variable immediately available after the comma, or not until the semicolon?
This is as opposed to the following code snippet, where it is very clear that the value of c will be "value_2":
var a = "value_1";
var b = "value_2";
var c = b;
I thought I'd ask rather than test in a browser and just assume that the behavior will be consistent.
See the comma operator:
The comma operator evaluates both of its operands (from left to right) and returns the value of the second operand
So b = "value_2" is evaluated before c = b
It's not really an answer to the question, but when faced with such a choice between two expressions of the same thing, always choose the one which is the less ambiguous.
In your second code snippet, it's clear to everybody what the final state is. With the first one, well, you had to ask a question here to know :) If you come back to the code in a month from now, or if somebody else does, then you'll have to go through the same process of finding out the actual meaning. I don't think it's worth the 6 characters you're saving.

Categories

Resources