GithubHelp home page GithubHelp logo

no-mutation-cheatsheet's Introduction

No Mutation Cheatsheet

A quick reference for alternatives to mutable methods for Javascript collections.

Arrays

Arrays have lots of methods that will introduce side effects into your functions. It's possible to avoid the following mutating methods, with a mixture of slice, concat, map, reduce and filter.

pop/shift

pop and shift remove the last and first element from an array, respectively.

// remove the first element
return arr.slice(1);

// remove the last element
return arr.slice(0, -1);

push/unshift

push and unshift add an element to the end and start of an array, respectively.

// add element at the end
return arr.concat([element]);

// add element at the start
return [element].concat(arr);

reverse

reverse reverses the ordering of an array in-place.

return arr.reduce(function(reversed, item) {
  return [item].concat(reversed);
}, []);

sort

It's possible to re-implement sort in a side effect free way --- as shown with reverse --- but it requires a lot more code.

A simpler alternative is to copy the array, then use the mutable sort method on the new copy.

function copy(arr) {
  return arr.map(function(item) {
    return item;
  });
}

return copy(arr).sort();

splice

splice is a multipurpose method for removing and inserting items into an array.

// to remove `count` items at `index`
var before = arr.slice(0, index),
    after  = arr.slice(index + count);

return before.concat(after);

// insert items at `index`
var before = arr.slice(0, index),
    after  = arr.slice(index);

before
  .concat(items)
  .concat(after);

forEach

forEach is the odd-one-out here, as the method itself creates no side effects. However, it does encourage them, in the same way for, for-in and while loops do.

Here are some common patterns that use these looping constructs with side effects.

// transform each element in an array
arr.forEach(function(item, index) {
  arr[index] = item * 2;
});
return arr;

// without side effects
return arr.map(function(item) {
  return item * 2;
});
// remove some items from an array
var kept = [];
arr.forEach(function(item) {
  if(item < 5) {
    kept.push(item);
  }
});
return kept;

// without side effects
return arr.filter(function(item) {
  return item < 5;
});
// sum an array of numbers
var total = 0;
nums.forEach(function(num) {
  total += num;
});

// without side effects
var total = nums.reduce(function(total, num) {
  return total + num;
}, 0);

Objects

Unlike arrays, the interface for objects is minimal and most of our interactions with them are syntactic. Unfortunately, this makes it much harder to work with them in an immutable way.

Rather than looking at alternatives to existing methods we'll look at some strategies for creating new objects rather than mutating them. The essential quality here is that we have to make sure that the updated version is not a reference to the original object.

The simplest way is to create new objects with the appropriate properties changed.

const counter = { count: 0 };
return { count: counter.count + 1 };

This can work well for simple cases, but the more properties in your object, the more code you'll have to write each time you want to change it. Instead we can create a new object with the properties we care about and let Object.assign handle the rest.

const counter = { count: 0 };
return Object.assign({}, counter, { count: counter.count + 1 });

A new syntax proposal for ES7 makes use of the spread syntax (...) which can help us translate this example into much more readable code.

return { ...counter, count: counter.count + 1 };

This syntax is available for use in Babel.

no-mutation-cheatsheet's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

cuth

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.