Sometimes in the internet I see a syntax that is strange to me. Something like:
console.log = console.error = console.info = console.debug = console.warn = console.trace = function() {}
How does this "equal" sequence work?
Thanks.
An assignment operator assigns a value to its left operand based on the value of its right operand.
Consider:
a = b = c = d = 5;
The expression is resolved right to left so:
d = 5 and c = d (which is 5), b = c (5) and so on.
In your example those console methods are all being (re)defined as an empty function.
See: MDN: Assignment Operators for more info.
With assignments, the operations are resolved from right to left. So the right most value will be populated into all the preceding variables.
What you describe can be easily explained by analogy using a simpler example:
// Normal variable assignment
var a, b;
a = 15;
b = 15;
console.log("a: "+a+" , b: "+b);
// Assing the same value to two variables
var c, d;
c = d = 15;
console.log("c: "+c+" , d: "+d);
// Assign the same value to two variables and make it a function
var e, f;
e = f = function(){ console.log("Hi!"); };
// Call both of the variables' functions
e(); f();
Starting from variables a and b, you then go to c and d that are given the same value. The takeaway here is that you can assign the same value to two variables and the expression will be evaluated from right to left, so in effect it's like assigning the two variables' values separately. However, this does not mean that chaning one will change the other as well.
Finally, see what happens with e and f. These are assigned a function instead of a value, so you can then call them as if they were functions.
Short version: Expression gets resolved from right to left. The assignment is by value, not by reference, meaning that changing one of the variables' value will not affect the others. Finally, if you assign a function to your variables, you can then use their names to call the function that is their value.
Related
I know typeof(my_number) is a primitive number, which makes functions receive a copy of my_number instead of my_number itself, which does't make it's value change at all. This is working as expected (I also know var is deprecated, that's probably not my issue here whatever).
What i don't know is why my_object_number isn't changed. I know i could have returned number + 1 and associated it to my_object_number, but I'm intentionally trying to code something similar to what a void(int*)function would have done in C.
var my_number = 3;
var my_object_number = new Number(3);
var my_object ={
number: 3
}
function increments_number(numero){
numero = numero + 1;
}
function increments_object(number){
number.number++;
}
increments_number(my_number);
increments_number(my_object_number);
increments_object(my_object);
console.log("primitive number = 3, which increased by a function = " + my_number);
console.log("object Number = 3 , which increased by a function = " + my_object_number)
console.log("prop number of a hardcoded object = 3, which increased by a function = " + my_object.number)
the code above prints.
primitive number = 3, which increased by a function = 3
object Number = 3 , which increased by a function = 3
prop number of a hardcoded object = 3, which increased by a function = 4
I'm not sure why my_object_number isn't incremented
I know typeof(my_number) is a primitive number, which makes functions receive a copy of my_number instead of my_number itself, which does't make it's value change at all.
There is no difference between primitives and objects in JavaScript in this respect. Actually, you can forget there’s a difference at all, for the most part – in strict mode, they’ll either behave the same in every situation or throw an error. Function calls aren’t related either. Instead, the difference is between mutating a value and reassigning something that contains a value, like a variable or a property, to contain a different value.
var a = {};
var b = a;
b = {foo: 'bar'};
console.log(a); // didn’t change, because assignment to `b` changes the variable `b`,
// not the value `{}`
var d = 5;
var e = d;
e = 6;
console.log(d); // didn’t change, because assignment to `e` changes the variable `e`,
// not the value `5`
'use strict';
var a = {};
var b = a;
b.foo = 'bar';
console.log(a); // the value {} changed; all variables stayed the same
var d = 5;
var e = d;
e.foo = 'bar'; // throws an error; a primitive is indistinguishable from…
var f = Object.freeze({});
var g = f;
g.foo = 'bar'; // … an immutable object.
++, like all math operators in JavaScript, is an operation on something that contains a value – it doesn’t mutate a value. ++x acts like x = x + 1.
What I get from previous posts and articles is that the exports object is located on the global object. I came across this code which confused me:
let blue = 'blue'
let red = 'red'
var exports = module.exports = {
red,
blue
};
This code sets module.exports to a variable called exports which then gets set to an object which gets exported.
I am confused however by this syntax:
Example1:
var exports = module.exports = {}
How does this work exactly? Because normally in JS you can't assing a variable two times. For instance this gives an error:
Example2:
let foo = 5 = 4;
How does the code in example 1 give no error while the code in example 2 does?
let foo = 5 = 4;
Cause its parsed from right to left:
let foo = (5 = 4);
And 5 is not a variable, so you cant assign stuff to it. However it works with an identifier:
let bar;
let foo = bar = 5;
Your interpretation of what the line is doing is incorrect.
This code sets module.exports to a variable called exports which then gets set to an object which gets exported.
What is actually happening is that the value { red, blue } is being assigned to module.exports, and then that same value ({ red, blue }) is being assigned to exports.
In JavaScript and other languages with similar syntax (C, C++, C#, Java) someAssignableThing = someValue is treated as an expression, and you can use a = b as a sub-portion of other expressions and chain as many together as you want.
As an expression someAssignableThing = someValue equates to "assign someValue to someAssignableThing and evaluate to the value someValue".
So the statement:
a = b = c = d = e = 5;
would assign the value 5 to a, b, c, d, and e.
It is a syntax error to have something on the left side of the = that cannot be assigned a value and that's why you get an error in the second case (you cannot assign a value to 5).
Trying to set a background color to the body of the document, I am puzzled as for why the following code does not work (tested in Chrome):
var a = 'blue';
var b = document.getElementById('body').style.backgroundColor;
b = a; // Not working.
while this works fine:
var a = 'blue';
var b = document.getElementById('body').style;
b.backgroundColor = a; // works.
and this works too:
document.getElementById('body').style.backgroundColor = 'blue'; //works
Can someone explain why the first version does not work?
This is a classic pointer user error. I've made this mistake many many times.
var a = 'blue';
var b = document.getElementById('body').style.backgroundColor;
b = a; // Not working.
The above code doesn't work because the value of document.getElementById('body').style.backgroundColor is being copied to the identifier b. When you reassign b with the value of a you're not re-assigning the value of document.getElementById('body').style.backgroundColor.
That why thiis code works:
var a = 'blue';
var b = document.getElementById('body').style;
b.backgroundColor = a; // works.
because you're saving the value of style to the identifier b. b a complex type. Now when you reassign b.style you're also re-assigning document.getElementById('body').style because the identifier b holds the same reference as document.getElementById('body').style.
Let me try to break that down:
In javascript (and many other languages) when you assign a complex type (i.e. an object or an array) to an identifier, you're actually assigning a reference to "something" in memory. You can think of the identifier's value being an "address" instead of holding all the values of the complex type, and when you try to pull values out of the identifier using the obj.prop syntax, you're actually telling the program to go to the address and fetch the desired value.
Therefore, if any property in that "something" changes, the references (aka pointers) will also reflect that change:
const complexType = {
a: 'something'
}
const x = complexType;
const y = complexType;
console.log(`from x: ${x.a}`);
console.log(`from y: ${y.a}`);
complexType.a = 'something else';
// notice how they change
console.log(`from x again: ${x.a}`);
console.log(`from y again: ${y.a}`);
To contrast, simple/primitive types are always copied on assignment. This means that the identifier hold the full value instead of holding an address. That means whenever you assign an identifier to a simple/primitive value, that value will persist even when you change the original value.
// original value
let simpleType = 'something';
let a = simpleType;
let b = simpleType;
console.log(`from a: ${a}`);
console.log(`from b: ${b}`);
// re-assign
simpleType = 'something else';
// notice how they *don't* change
console.log(`from a again: ${a}`);
console.log(`from b again: ${b}`);
So to conclude, document.getElementById('body').style.backgroundColor returns a simple type. This simple type get copied on assignment. That's why you can't do this:
var a = 'blue';
var b = document.getElementById('body').style.backgroundColor;
b = a; // Not working.
Hope that helps!
var b = document.getElementById('body').style.backgroundColor;
Acts like a getter and returns the background color of the element with the ID of body. It doesn't hold a pointer to it the way you seem to be thinking. So b would contain a string like purple or whatever color you set.
Then you're doing b = a; which will just overwrite the value of b with a's value.
Looking at var a=b=1; , I already know that both a and b has the same value.
But my question is :
Does the a gets its value from 1 or from b ?
I made a small test :
/*1*/ (function (){
/*2*/ var j = window.j = function (){ alert('3');};
/*3*/ window.j2 = j;
/*4*/ })();
/*5*/
/*6*/ window.j(); //3
/*7*/ window.j=null;
/*8*/ window.j2();//3
As you can see line #8 yields 3 so I persume that a is not having the value of b but the value of 1.
Am I right ?
visualize :
(function (){
var j = window.j = function (){ alert('3');};
|
| ^ ^
| | | //which one ?
+----------+--------+
})();
Assignment in javascript works from right to left. So you are getting your value from window.j. Re-setting window.j will not affect the result because Javascript variables always passes by value, exception is array or object.
Example of passing value by ref in JS object:
var obj = { x: 2 };
var anotherObj = obj;
anotherObj.x++;
alert(obj.x); //3
You can find more information here.
More useful examples available in this answer.
The "=" operator associates to the right so "a=b=1" is equivalent to "a=(b=1)". So 1 is assigned to b first with a result of 1, which is then assigned to a.
Assigment in JavaScript is right associative, so you are correct.
In
a = b = c;
a takes the value of b at time of assignment, so if b is later assigned to something else, a retains its value (which happens to be the same as c)
You are right technically but are confused with reference / value assignment i think. Technically a does get it's value from b but there is no reference to b therefore if your were to do b = null it would have no affect to a, which is what you're seeing in your example.
a inherits the value of b without relying on b still existing or having that same value later on when you refer back to a. The assignment happens right to left so actually reads a = ( b = 1)
I'm reading some code and I see a comparison that's laid out like this:
a = b = c
Seeing as how searching Javascript about equal or comparison yields remedial results, anyone care to explain what's going on?
EDIT: These are all objects or object properties that we're talking about here, should have specified.
DOUBLE EDIT: This is inside of an Object.defineProperties() block.
= is an operator. It takes two arguments: a variable reference and an expression. It assigns the value of the expression to the variable, and returns the assigned value.
As a result, you can chain them and it equates to this:
a = (b = c)
In other words, assign b to the value of c, then assign that value to a also.
a = b = c is just shorthand expression for:
b = c;
a = b;
if(a = b) will always return true because it is assigning, instead of comparing. To compare, the statement should read: if(a == b).
The = operator associates right-to-left and evaluates to the value that was assigned.
So this:
a = b = c;
Means this*:
b = c;
a = c;
* Unless you're dealing with properties.
That is not a comparison. It is an assignment of the value of c to the b and a variables.
Assignment works right to left, so it is an assignment of c to b first. Then the return value of that operation is assigned to a.
The return value of an assignment operation is the value that was assigned, so a will get the same value assigned to b.
It equates this;
b = c; a = b;