I always have such an intuition that an expression inside code can be mentally substituted by its evaluation result. However, the following two code snippets have different execution results.

let obj = {};
({a: obj.b, b: obj.a} = {a: 1, b: 2}); //* This line
console.log(obj); // {b: 1, a: 2}

versus

let obj = {a: 1, b: 2};
({a: obj.b, b: obj.a} = obj); //* and this line
console.log(obj); // {a: 1, b: 1}

I think the two starred lines are same IN MY BRAIN, but they have different execution results.

Is this an intentional design?

2

There are 2 answers

1
Thomas On BEST ANSWER

Object destructuring is just syntactic sugar for this:

let obj = {};

// ({a: obj.b, b: obj.a} = {a: 1, b: 2});
const __temp_source = {a: 1, b: 2};
obj.b = __temp_source.a;
obj.a = __temp_source.b;

console.log(obj); // {b: 1, a: 2}

but here, source and target are the same object

let obj = {a: 1, b: 2};

// ({a: obj.b, b: obj.a} = obj);
obj.b = obj.a;
obj.a = obj.b;

console.log(obj); // {a: 1, b: 1}

what you could do is

let obj = {a: 1, b: 2};

[obj.a, obj.b] = [obj.b, obj.a];

// const __temp_source = [obj.a, obj.b];
// obj.b = __temp_source[0];
// obj.a = __temp_source[1];

console.log(obj); // {a: 2, b: 1}

0
derpirscher On

Your first snippet is semantically equivalent to

let obj = {}; let obj2 = {a: 1, b: 2}; 
obj.b = obj2.a;
obj.a = obj2.b
console.log(obj);

Whereas your second snippet is semantically equivalent to

let obj = {a: 1, b: 2};
obj.b = obj.a;
obj.a = obj.b;

console.log(obj); // {a: 1, b: 1}