Pro Yearly is on sale from $80 to $50! »

The hidden and new parts of JS

55c3671e959e903a7880eaf0cf61f3e4?s=47 Ritesh Kumar
February 17, 2018

The hidden and new parts of JS

This talk involves array-like objects, dependency injection, how sort works, let/const, async/await and some ES2018 features.

55c3671e959e903a7880eaf0cf61f3e4?s=128

Ritesh Kumar

February 17, 2018
Tweet

Transcript

  1. !// The hidden and new parts of JS @ritz078

  2. let/const

  3. function varTest() { var x = 1; if (true) {

    var x = 2; !// same variable! console.log(x); !// 2 } console.log(x); !// 2 } function letTest() { let x = 1; if (true) { let x = 2; !// different variable console.log(x); !// 2 } console.log(x); !// 1 } Scope let var
  4. !// SyntaxError: Missing initializer in const declaration const a; const

    const b = [1, 2, 3]; !// Modification without changing reference allowed. b.push(4); !// b = [1, 2, 3, 4] !// throws an error. reassigning not allowed. b = [2, 3];
  5. console.log(a); !// undefined var a = 5; console.log(b); !// ReferenceError:

    b is not defined const b = 5; console.log(c); !// ReferenceError: c is not defined let c = 5; Hoisting https://stackoverflow.com/a/31222689/3366126
  6. { "plugins": [ ["transform-es2015-block-scoping", {"tdz": true}] ] }

  7. for (var i = 0; i < 10; i!++) {

    setTimeout(function() { console.log(i) }, 5) } var i; for (i = 0; i < 10; i!++) { setTimeout(function() { console.log(i) }, 5) } !// 10 is printed 10 times.
  8. for (let i = 0; i < 10; i!++) {

    setTimeout(function() { console.log(i) }, 5) } !// Prints number from 1 to 10 Why ?
  9. !// A closure is created. !// Now i is a

    value and not !// a reference. var _loop = function _loop(i) { setTimeout(function () { console.log(i); }, 5); }; for (var i = 0; i < 10; i!++) { _loop(i); } for (let i = 0; i < 10; i!++) { setTimeout(function() { console.log(i) }, 5) } !// Prints number from 1 to 10
  10. { "plugins": [ ["transform-es2015-block-scoping", { "throwIfClosureRequired": true }] ] }

  11. Array

  12. Array.isArray(Array.prototype); !// true

  13. .sort( ) const arr = [10, 3, 100] const sortedArray

    = arr.sort(); !// it doesn't correctly sort an array of numbers. console.log(sortedArray) !// [10, 100, 3] !// also sorting changes the original array console.log(arr) !// [10, 100, 3] The default sort order is according to string Unicode code points.
  14. const arr = [10, 3, 100] !// passing a comparator

    function const sortedArray = arr.sort((a, b) !=> a - b); console.log(sortedArray) !// [3, 10 100]
  15. ~N !!=== -(N + 1) Tilde (~) !// equivalent to

    someStr.indexOf("a") !>= 0 if (~someStr.indexOf("a")) { !// Found it } else { !// Not Found }
  16. .includes () const arr = [1, 2, 3, NaN]; arr.includes(3)

    !// true !// uses same value zero comparison !// just like map and set. arr.includes(NaN) !// true !// uses Strict Equality Comparison "!!===" arr.indexOf(NaN) !// -1
  17. Array-like objects

  18. !// !|> Indexed access to elements !// !|> Has length

    property !// !|> Does not have array methods such as push, !// forEach and indexOf const arrayLikeObject = { 0: "hello", 1: "world", length: 2 } console.log(arrayLikeObject[1]) !// hello !// throws error console.log(arrayLikeObject.indexOf("hello"))
  19. !// Arguments are array like objects function a () {

    console.log(Array.isArray(arguments)) !// false console.log(arguments[0]) !// 1 console.log(arguments.length) !// 3 } a(1, 2, 3)
  20. !// elements is a HTMLCollection !// They are array like

    objects const elements = document.getElementsByTagName("div") console.log(Array.isArray(elements)) !// false
  21. Converting array like objects to an array !// Can convert

    array like objects and string into !// an array. Array.from(arguments); !// Borrowing a method from Array Array.prototype.slice.call(arguments); !// Node treats arguments and array like objects differently. !// Anyways, you shouldn't be spreading arguments, it's going !// to cause an engine to deoptimize the entire function. !// https:!//github.com/petkaantonov/bluebird/wiki/Optimization- killers#3-managing-arguments [!!...arguments]
  22. Object

  23. length !// array-like-object const a = { 0: 1, 1:

    2, 2: 3, length: 3 } console.log(Object.keys(a)) !// ["0", "1", "2", "length"]
  24. function a () { arguments.length !// 3 Object.keys(arguments) !// ["0",

    "1", “2"] } a(1,2,3) no length
  25. .defineProperty() const a = { 0: 1, 1: 2, 2:

    3 } Object.defineProperty(a, "length", { enumerable: false, writable: true, !// can value be modified ? configurable: true, !// can property be deleted ? value: 3 }) console.log(a.length) !// 3 console.log(Object.keys(a)) !// ["0", "1", "2"]
  26. Function

  27. function sum (a, b, c) { !// the number of

    arguments actually passed. console.log(arguments.length) !// 2 return a + b + c; } sum(1, 2) !// the number of arguments that the function accepts. console.log(sum.length) !// 3 .length ()
  28. function sum (a, b, c=3) { return a + b

    + c; } sum(1, 2) !// the number of arguments that the function accepts. console.log(sum.length) !// ? Gotcha
  29. !// There is no c here. Now sum.length makes better

    sense. function sum(a, b) { var c = arguments.length > 2 !&& arguments[2] !!!== undefined ? arguments[2] : 3; return a + b + c; } sum(1, 2) console.log(sum.length) !// 2
  30. Dependency Injection var app = angular.module('myApp', []); !// works as

    expected app.controller('myCtrl', function($scope, $timeout) { $scope.firstName = "John"; $scope.lastName = "Doe"; }); !// works as expected app.controller('myCtrl', function($timeout, $scope) { $scope.firstName = "John"; $scope.lastName = "Doe"; }); In this case, position of argument doesn’t matter but name does.
  31. function a($scope, $timeout) { !// your code here } const

    code = a.toString() !// "function a($scope, $timeout) { !// !// your logic here !// }" const match = code .match(/^function\s{0,}[a-zA-Z\d_]{0,}\(([^\)]+)\)/)[1]; console.log(match.split(", ")) !// ["$scope", "$timeout"] .toString() If the argument name changes after minification, this fails.
  32. async/await

  33. async function () { let response = await fetch("https:!//random-api/v1"); let

    user = await response.json(); return user; } !// syntax error in top-level code let response = await fetch("https:!//random-api/v1"); let user = await response.json();
  34. class Thenable { constructor (num) { this.num = num; }

    then (resolve, reject) { setTimeout(() !=> resolve(this.num * 2), 1000); } } async function () { let result = await new Thenable(2) alert(result) } a()
  35. const data = [ fetch("/a"), fetch("/b"), fetch("/c") ] for await

    (const x of data) { console.log(x) } ES2018: async-for-of Async for-of statements are only allowed within async functions and async generator functions.
  36. new Map ()

  37. > const map = new Map(); > map.set('foo', 123); >

    map.get('foo') !// 123 > map.has('foo') !// true > map.delete('foo') !// true > map.has('foo') !// false > map.size !// 1 > map.clear() length is for data structures that are indexable – like arrays. size is for collections that are unordered like maps and sets.
  38. !// Any value can be a key. const KEY1 =

    {}; map.set(KEY1, 'hello'); console.log(map.get(KEY1)); !// hello const KEY2 = {}; map.set(KEY2, 'world'); console.log(map.get(KEY2)); !// world Object vs Map
  39. Object vs Map const map = new Map (); !//

    typeof keys is preserved map.set(1, "hello") console.log([!!...map.keys()]) !// [1] const obj = {} !// typeof keys is string obj[1] = "world" console.log(Object.keys(obj)) !// ["1"]
  40. Object vs Map !// Map const map = new Map

    (); !// Doesn't override prototype methods map.set("get", "world") console.log(map.get) !// function get() { [native code] } !// Object const obj = {} !// overrides prototype methods obj['toString'] = "override" console.log(obj.toString) !// "override"
  41. new Set ()

  42. Array vs Set const arr = [1, 2, "3", 3,

    3]; const set = new Set(arr); !// O(1) lookup set.has(3) !// only unique values are present. !// They are unique by both type !// and value. set.size !// 4 Array.from(set.values()) !// [1, 2, "3", 3] const arr = [1, 2, "3", 3, 3]; !// O(n) lookup arr.indexOf(3) !// all elements preserved arr.length !// 5
  43. ES2018

  44. Rest operator in object destructuring const obj = {foo: 1,

    bar: 2, baz: 3}; const {foo, !!...rest} = obj; !// Same as: !// const foo = 1; !// const rest = {bar: 2, baz: 3};
  45. RegExp capture groups const RE_DATE = /(?<year>[0-9]{4})-(?<month>[0-9] {2})-(?<day>[0-9]{2})/; const matchObj

    = RE_DATE.exec('1999-12-31'); const year = matchObj.groups.year; !// 1999 const month = matchObj.groups.month; !// 12 const day = matchObj.groups.day; !// 31
  46. promise .then(result !=> {···}) .catch(error !=> {···}) .finally(() !=> {···});

    Promise.prototype.finally()
  47. Thank You @ritz078