Tuesday, December 20, 2016

JavaScript Evolution ECMAScript 6 - Merging Object via Object.assign()

Copying all properties of one object to another one is a common operation in JavaScript. In this article, we gonna explore ES2015 new implementation of Object.assign().

Object.assign() syntax is Object.assign(target, sources, ...). The target object is the return value and the source is the object to be copied.

Example of merging an object:
let first = {first: "Sam"};
let last = {last: "Wong"};
let person = Object.assign(first, last);
console.log(person); // Return {first: "Sam", last: "Wong"}
console.log(first); // Return {first: "Sam", last: "Wong"} as the source also changed.
Example of merging an object without modifying the source (cloning)
let first = {first: "Sam"};
let last = {last: "Wong"};
let person = Object.assign({}, first, last);
console.log(person); // Return {first: "Sam", last: "Wong"}
console.log(first); // Return {first: "Sam"} as source's value preserve
Example of merge multi-source and value is overwritten when the key is equal.
let b = Object.assign({foo:0},{foo:1},{foo:2});
console.log(b); // Return {foo:2} as last object prevail.
In use-case, Object.assign() is practical to write flexible and usable function. In the coming example, we are going to write a buildUser function which accepts 2 parameters (first, last), and a custom Options (lettercase, and targetElement) will vary according to each call of the function. The function can be called in many ways.
buildUser("Sam", "Wong");
buildUser("Sam, "Wong", {lettercase: "upper"});
buildUser("Sam", "Wong", {lettercase: "upper", targetElement: ".username"})
For such function, it is okay to accept the object parameter instead using the name parameter.

Example of Name Parameter:
// Bad implementation as not easy to read when scale to more arguments.
function buildUser(first, last, {lettercase, targetElement} = {})
Example of Object Parameter:
// Good implement as easy to read when scale.
function buildUser(first, last, options = {})
Some options might not be specified by the caller, so we need to have default values. One way we can do it by using ||. This code worked, the issue here is the default value can be anywhere which is hard to read.
function buildUser (first, last, options = {}){
  let lettercase = options.lettercase || "uppercase";
  let targetElement = options.targetElement || ".username";
  ...
}
To solve this, we group default values in 1 place. The grouping default value is the common pattern in a large project. It can help us write more idiomatic JavaScript. The next step is to merge the default and options using the Object.assign() syntax. The important point is options value must overwrite default value and the result stores in setting variable.
function buildUser(first, last, options = {}) {
  let defaults = {
    lettercase = "upper",
    targetElement = ".username"
  }

  let setting = Object.assign({}, defaults, options);
  console.log(setting.lettercase);
  console.log(setting.targetElement);
}

No comments:

Post a Comment