Saturday, September 23, 2017

What lends the spread operator in TypeScript to immutability per se?

Well, consider this:

let yin = [13, 42];
let yang = [69, 86];
let yinyang = [...yin, ...yang];
console.log(yinyang);

 
 

It spits this up to the console in Google Chrome Development Tools:

  1. Array(4)
    • 13
    • 42
    • 69
    • 86

 
 

If we expand the code to this:

let yin = [13, 42];
let yang = [69, 86];
let yinyang = [...yin, ...yang];
console.log(yinyang);
yinyang[2] = 0;
console.log(yinyang);
console.log(yang);

 
 

We get this:

  1. Array(4)
    • 13
    • 42
    • 0
    • 86
  2. Array(4)
    • 13
    • 42
    • 0
    • 86
  3. Array(2)
    • 69
    • 86

 
 

And furthermore this:

let yin = [13, 42];
let yang = [69, 86];
let yinyang = [...yin, ...yang];
console.log(yinyang);
yinyang[2] = 0;
console.log(yinyang);
console.log(yang);
yang[0] = 13;
console.log(yinyang);
console.log(yang);

 
 

Gives:

  1. Array(4)
    • 13
    • 42
    • 0
    • 86
  2. Array(4)
    • 13
    • 42
    • 0
    • 86
  3. Array(2)
    • 13
    • 86
  4. Array(4)
    • 13
    • 42
    • 0
    • 86
  5. Array(2)
    • 13
    • 86

 
 

Neato! A change to the arrays' numbers does not affect the values in the other arrays. Now let's try the same trick with some objects:

let yin = {
   foo: 13,
   bar: 42
};
let yang = {
   bar: 69,
   baz: {
      qux: true
   }
};
let yinyang = {
   ...yin,
   ...yang
};
console.log(yinyang);

 
 

What is immediately above gives us:

  1. Object
    • bar: 69
    • baz:
      • qux: true
    • foo: 13

 
 

Alright, so far so good. Now consider this:

let yin = {
   foo: 13,
   bar: 42
};
let yang = {
   bar: 69,
   baz: {
      qux: true
   }
};
let yinyang = {
   ...yin,
   ...yang
};
console.log(yinyang);
yinyang.bar = 86;
yinyang.baz.qux = false;
console.log(yinyang);
console.log(yang);

 
 

Well that yields:

  1. Object
    • bar: 86
    • baz:
      • qux: false
    • foo: 13
  2. Object
    • bar: 86
    • baz:
      • qux: false
    • foo: 13
  3. Object
    • bar: 69
    • baz:
      • qux: false

 
 

Oh no! Trouble in paradise! This kinda works, but the objects that are copied are not deep copied leading to some unexpected behavior. Notice that all qux settings end up as false. What is more...

let yin = {
   foo: 13,
   bar: 42
};
let yang = {
   bar: 69,
   baz: {
      qux: true
   }
};
let yinyang = {
   ...yin,
   ...yang
};
console.log(yinyang);
yinyang.bar = 86;
yinyang.baz.qux = false;
console.log(yinyang);
console.log(yang);
yang.bar = 0;
yang.baz.qux = null;
console.log(yinyang);
console.log(yang);

 
 

Gives us:

  1. Object
    • bar: 86
    • baz:
      • qux: null
    • foo: 13
  2. Object
    • bar: 86
    • baz:
      • qux: null
    • foo: 13
  3. Object
    • bar: 0
    • baz:
      • qux: null
  4. Object
    • bar: 86
    • baz:
      • qux: null
    • foo: 13
  5. Object
    • bar: 0
    • baz:
      • qux: null

No comments:

Post a Comment