Skip to content

Instantly share code, notes, and snippets.

@cerebrl
Last active March 14, 2019 13:07
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cerebrl/8fe8ffe04bace984882e to your computer and use it in GitHub Desktop.
Save cerebrl/8fe8ffe04bace984882e to your computer and use it in GitHub Desktop.
Interesting ES6 features

Interesting ES6 Features

The purpose of this is not to be an exhaustive list or a reference for ES6 features. This is intended to share the interesting ideas that are coming down the pipeline and to explore their intentions.

Table of contents

  1. String methods
  2. Variable type declarations
  3. Object features
  4. Function features
  5. Classes
  6. Working Interatively
  7. Promises
  8. Modules
  9. Other neat new features
  10. References

New string methods

String.includes() // Anywhere within string
String.startsWith() // does it start with ...
String.endsWith() // does it end with ...

New variable type declarations

var versus let: let is not the new var. This has been said by many of the leading engineers within our community. let was not intended to replace var, but to complement it when block scope is important.

let

/**********************
 * Old way: IIFE were needed to "snapshot" values at time of iteration
 */
for (var i = 0; i < arr.length; i++) {
	(asyncFunction(arr[i], function callback(error, data) {
		arr[i] = data.value;
	}(i)); // This is necessary to capture the value of i at iteration
}


/**********************
 * ES6 way
 *
 * With let, the value at iteration is preserved since 
 * a new i is created for each cycle
 */
for (let i = 0; i < arr.length; i++) {
	asyncFunction(arr[i], function callback(error, data) {
		arr[i] = data.value;
	};
}
// Be aware: access a let before it's initialized errs out
if (true) {
	console.log(name); // ReferenceError!
	let name = 'Justin';
} else {
	let name = 'James';
}

const

/**********************
 * Old way
 */
var PI = 3.14;
PI = 7; // altered


/**********************
 * ES6 way
 */
const PI = 3.14;
PI = 7; // throws error

New object features

Object property shorthand

function (greeting, name) {
	// properties and method are placed without keys
	var obj = {
		greeting,
		name,
		sayHello () {
			console.log(greeting + ', ' + name + '!');
		}
	}
	return obj;
};

Object destructuring

Destructuring works in parameters as well as vars and lets. Parameters are the most interesting to me

/**********************
 * Old way
 */
function func(obj) {
	// Manually destructure object into vars
	var color: obj.color,
		size: obj.size;
		
	console.log(color); // "red"
	console.log(size); // "large"
}
func({
	color: "red",
	size: "large",
	quantity: 5
});


/**********************
 * ES6 way
 */
function func({color, size}) {
	console.log(color); // "red"
	console.log(size); // "large"
}
func({
	color: "red",
	size: "large",
	quantity: 5
});

New function features

Default parameters

/**********************
 * Old way
 */
function func(type, color, size) {
	var type = type || "t-shirt",
		color = color || "black",
		size = size || "large";
		
	console.log(type); // "hoodie"
	console.log(color); // "red"
	console.log(size); // "large"
}
func("hoodie", null); // for any falsey value, the default will be assigned 


/**********************
 * ES6 way
 */
function func(type = "t-shirt", color = "black", size = "large") {
	console.log(type); // "hoodie"
	console.log(color); // null <-- surprised?
	console.log(size); // large
}
func("hoodie", null); // only the absence of a value will set a default

Rest parameters

/**********************
 * Old way
 */
function func(user) {
	var i = 1; // skip zeroth
	// Have to access the arguments function to grab the unknown items
	// Have to skip zeroth index to not iterate over the user parameter
	for (i; i < arguments.length; i++) {
		console.log(arguments[i]); // "SD9G876S98FG", "S9DF7SD98F7", "SDS0G87H8977H"
	}
}
func("jlowery", "SD9G876S98FG", "S9DF7SD98F7", "SDS0G87H8977H");


/**********************
 * ES6 way
 */
function func(user, ...items) {
	for (let i = 0; i < items.length; i++) {
		console.log(items[i]); // "SD9G876S98FG", "S9DF7SD98F7", "SDS0G87H8977H"
	}
}
func("jlowery", "SD9G876S98FG", "S9DF7SD98F7", "SDS0G87H8977H");

Arrow functions

var addTwo = (a, b) => a + b;
addTwo(2, 4); // 6

/**********************
 * What's interesting is ...
 */
var api = {
	el: document.getElementById('listItem'),
	bindListener: () => {
		this.el.addEventListener('click', () => {
			this.clickAction(el); // `this` is api
		});
	},
	clickAction: (el) => {
		// logic
	}
};
/**********************
 * ... replaces ...
 */
var api = {
	el: document.getElementById('listItem'),
	bindListener: function () {
		var that = this;
		this.el.addEventListener('click', function () {
			that.clickAction(el); // `that` is api because `this` would be global
		});
	},
	clickAction: function (el) {
		// logic
	}
};
// There's more to arrow functions than what's above, so go explore.

Classes

Class

/**********************
 * Realy old way: the constructor/prototype pattern
 */
function Mammal () {
	this.gestation = 'placental';
	this.food_source = 'mammaries';
}
Mammal.prototype.gestation = function () {
	console.log('Gestation is ' + this.gestation);
}
Mammal.prototype.feed = function () {
	console.log('Feeding happens through the ' + this.food_source);
}
var cat = new Mammal('placental', 'mammaries');


/**********************
 * Better new'ish way: Object.create() and behavior delegation
 */
var actions = {
		init: function (gestation, food_source) {
			this.gestation = gestation;
			this.food_source = food_source;
		},
		gestation: function () {
			console.log('Gestation is ' + this.gestation);
		},
		feed: function () {
			console.log('Feeding happens through the ' + this.food_source);
		}
	};
var Cat = Object.create(actions);
Cat.init('placental', 'mammaries');


/**********************
 * ES6 way: Classes (somewhat contraversial)
 */
class Mammal {
	constuctor(gestation, food_source) {
		this.gestation = gestation;
		this.food_source = food_source;
	}
	gestation() {
		console.log('Gestation is ' + this.gestation);
	}
	feed() {
		console.log('Feeding happens through the ' + this.food_source);
	}
}
var cat = new Mammal('placental', 'mammaries');

Subclass

// Using the Mammel class above
class Dog extends Mammal {
  vocalize() {
    console.log('bark');
  }
}

Working iteratively

For-of

// Create iterator
var iteratorMachine = function (arr) {
	var i = 0;
	return {
		callNext: function () {
			return {
				value: arr[i++],
				done: i >= arr.length ? true : false;
			}
		}
	}
};


/**********************
 * Old way
 */
var oldIterate = iteratorMachine([1, 2, 3]);
oldIterate.callNext(); // { value: 1, done: false }
oldIterate.callNext(); // { value: 2, done: false }
oldIterate.callNext(); // { value: 3, done: false }
oldIterate.callNext(); // { value: undefined, done: true }
oldIterate.callNext(); // will keep going and going


/**********************
 * ES6 way
 */
var es6Iterate = iteratorMachine([1, 2, 3]);
for (let item of es6Iterate) {
	console.log(item);
}
// for-in will print out the value property of the returned object
$ 1
$ 2
$ 3
// for-in stops when the done property is true

Generators

function *myGenerator(arr) {
	for (let i = 0; i < arr.length; i++) {
		yeild arr[i];
	}
}
var iterator = myGenerator([1, 2, 3]);
for (let item in iterator) {
	console.log(item);
}
$ 1
$ 2
$ 3

Promises

function asyncRequest(url, verb) {
	return new Promise(
		function (resolve, reject) {
			request(verb, url, function (error, response, body) {
				if (request.statusCode === 200) {
					// Success
					resolve(response);
				} else {
					// error
					reject(new Error(response));
				}
			}   
	});
}
asyncRequest('http://paypal.com/users/profile', 'GET').
	then(
		// Success method
		function (response) {
			console.log(response);
		},
		// Error method
		function (response) {
			console.log(response);
		}
	);

Modules

/**********************
 * Old way: AMD
 */
require('myComponent', function (myComponent) {
	myComonent.init();
});


/**********************
 * ES6 way: Modules
 */
import myComponent from 'lib/myComponent';
myComponent.init();

Other neat features (not exhaustive)

  • Map, set, weakmap, weakset
  • Module loaders
  • Proxies
  • Template strings
  • Super

References:

@xjamundx
Copy link

Object.assign is also awesome. (essentially _.extend)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment