Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the result of this JavaScript code snippet, and why?

Tags:

javascript

I'm a newby of JavaScript and just met this question. Can't figure it out by googling and searching on stackoverflow. Code snippet is as following:

var a = { n : 1};    
var b = a;    
a.x = a = {n:  2};    
console.log(a.x);
console.log(b.x);

According to my current knowledge, a.x = a = {n:2}; equals to :

a = {n : 2};
a.x = a;

Which eventually make a equals to {n:2, x:{n:2}}. So a.x should equal to {n:2}, and because b = a, so b.x = {n:2}. But the result I run in browser is : alert(a.x) is undefined and alert(b.x) is [object object].

Can someone explain why? thanks a lot.

like image 966
Lisa Avatar asked Feb 27 '18 03:02

Lisa


People also ask

What is the purpose of this JS snippet?

Snippets are scripts that you author in the Sources panel. They have access to the page's JavaScript context, and you can run them on any page. Snippets are an alternative to bookmarklets.

What is a JavaScript code snippet?

The JavaScript snippet collection contains a wide variety of ES6 helper functions. It includes helpers for dealing with primitives, arrays and objects, as well as algorithms, DOM manipulation functions and Node.

What is the output of code snippet?

A code snippet is a boilerplate code that can be used without changing it. This code helps such candidates who are not familiar with the online coding environment to focus more on the algorithm that is required to solve the question rather than understanding the STD INPUT and OUTPUT syntaxes.

What does the code snippet show?

A code Snippet is a programming term that refers to a small portion of re-usable source code, machine code, or text. Snippets help programmers reduce the time it takes to type in repetitive information while coding. Code Snippets are a feature on most text editors, code editors, and IDEs.


1 Answers

This is a matter of operator precedence, and the matter is that there are three operators involved here: =, =, and ..

. has higher operator precedence than =, which means that a.x is evaluated before the assignments take place. After that, reassigning a mid-statement cannot affect the value of a in the expression a.x because it has already been evaluated.

We can observe this with the following code:

var _a;
var logging = false;
Object.defineProperty(window, 'a', { 
    get: function () {
        if (logging) {
            console.log('getting a'); 
        }
        return _a; 
    }, 
    set: function (val) { 
        if (logging) {
            console.log('setting a');
        }
        _a = val; 
    }
});

a = { n : 1};    
var b = a;

logging = true;
a.x = a = {n:  2};
logging = false;

console.log(a.x);
console.log(b.x);

What we can see here is that a's getter is being accessed before its setter in the process of the statement we're talking about, and it's only being accessed once. This tells us that a.x is being evaluated before a.x = .....

Where you're going wrong is that that statement actually evaluates like this:

a = {n:  2}
[the value that a referred to before the statement started executing].x = {n : 2};

In other words, the identifier a is "bound" before the statement begins executing and property references will refer to that bound value for the duration of the statement.

In this case, [the value that a referred to before the statement started executing] is equivalent to b, but it's not equivalent to the new value of a. That's why b.x has a value and a.x does not.

You could say that the process works out to be something like this:

var a = { n : 1};    
var b = a;

var temp = a;
var newVal = {n: 2};
a = newVal;
temp.x = newVal;

console.log(a.x);
console.log(b.x);

and this produces the same outcome as your original code.

The ECMAScript Spec lays out the procedure for evaluating an AssignmentExpression of the form LeftHandSideExpression = AssignmentExpression. The first two steps are:

  1. Let lref be the result of evaluating LeftHandSideExpression.
  2. Let rref be the result of evaluating AssignmentExpression.

This clearly shows that the left hand side of an assignment is evaluated before the right hand side is evaluated.

like image 135
JLRishe Avatar answered Nov 15 '22 13:11

JLRishe