└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # ECMAScript 6 equivalents in ES5 2 | 3 | *Please note this document is very much a work in progress. Contributions are welcome.* 4 | 5 | **Table of contents:** 6 | 7 | 1. [Arrow Functions](#arrow-functions) 8 | 1. [Block Scoping Functions](#block-scoping-functions) 9 | 1. [Template Literals](#template-literals) 10 | 1. [Computed Property Names](#computed-property-names) 11 | 1. [Destructuring Assignment](#destructuring-assignment) 12 | 1. [Default Parameters](#default-parameters) 13 | 1. [Iterators and For-Of](#iterators-and-for-of) 14 | 1. [Classes](#classes) 15 | 1. [Modules](#modules) 16 | 1. [Numeric Literals](#numeric-literals) 17 | 1. [Property Method Assignment](#property-method-assignment) 18 | 1. [Object Initializer Shorthand](#object-initializer-shorthand) 19 | 1. [Rest Parameters](#rest-parameters) 20 | 1. [Spread Operator](#spread-operator) 21 | 1. [Proxying a function object](#proxying-a-function-object) 22 | 1. [Array-like object to array](#array-like-object-to-array) 23 | 1. [About](#about) 24 | 1. [License](#license) 25 | 26 | ## Arrow Functions 27 | 28 | An arrow function expression (also known as fat arrow function) has a shorter syntax compared to function expressions and lexically binds the this value. Arrow functions are always anonymous. 29 | 30 | 31 | ES6: 32 | 33 | ```js 34 | [1, 2, 3].map(n => n * 2); 35 | // -> [ 2, 4, 6 ] 36 | ``` 37 | 38 | ES5 equivalent: 39 | 40 | ```js 41 | [1, 2, 3].map(function(n) { return n * 2; }, this); 42 | // -> [ 2, 4, 6 ] 43 | ``` 44 | 45 | ES6: 46 | 47 | ```js 48 | var evens = [2, 4, 6, 8, 10]; 49 | 50 | // Expression bodies 51 | var odds = evens.map(v => v + 1); 52 | var nums = evens.map((v, i) => v + i); 53 | 54 | console.log(odds); 55 | // -> [3, 5, 7, 9, 11] 56 | 57 | console.log(nums); 58 | // -> [2, 5, 8, 11, 14] 59 | 60 | // Statement bodies 61 | var fives = []; 62 | nums = [1, 2, 5, 15, 25, 32]; 63 | nums.forEach(v => { 64 | if (v % 5 === 0) 65 | fives.push(v); 66 | }); 67 | 68 | console.log(fives); 69 | // -> [5, 15, 25] 70 | 71 | // Lexical this 72 | var bob = { 73 | _name: 'Bob', 74 | _friends: [], 75 | printFriends() { 76 | this._friends.forEach(f => 77 | console.log(this._name + ' knows ' + f)); 78 | } 79 | } 80 | ``` 81 | 82 | ES5: 83 | 84 | ```js 85 | 'use strict'; 86 | 87 | var evens = [2, 4, 6, 8, 10]; 88 | 89 | // Expression bodies 90 | var odds = evens.map(function (v) { 91 | return v + 1; 92 | }, this); 93 | var nums = evens.map(function (v, i) { 94 | return v + i; 95 | }, this); 96 | 97 | console.log(odds); 98 | // -> [3, 5, 7, 9, 11] 99 | 100 | console.log(nums); 101 | // -> [2, 5, 8, 11, 14] 102 | 103 | var fives = []; 104 | nums = [1, 2, 5, 15, 25, 32]; 105 | 106 | // Statement bodies 107 | nums.forEach(function (v) { 108 | if (v % 5 === 0) { 109 | fives.push(v); 110 | } 111 | }, this); 112 | 113 | console.log(fives); 114 | // -> [5, 15, 25] 115 | 116 | // Lexical this 117 | var bob = { 118 | _name: 'Bob', 119 | _friends: [], 120 | printFriends: function printFriends() { 121 | this._friends.forEach(function (f) { 122 | return console.log(this._name + ' knows ' + f); 123 | }, this); 124 | } 125 | }; 126 | ``` 127 | 128 | ## Block Scoping Functions 129 | 130 | Block scoped bindings provide scopes other than the function and top level scope. This ensures your variables don't leak out of the scope they're defined: 131 | 132 | ES6: 133 | 134 | ```js 135 | // let declares a block scope local variable, 136 | // optionally initializing it to a value in ES6 137 | 138 | 'use strict'; 139 | 140 | var a = 5; 141 | var b = 10; 142 | 143 | if (a === 5) { 144 | let a = 4; // The scope is inside the if-block 145 | var b = 1; // The scope is inside the function 146 | 147 | console.log(a); // 4 148 | console.log(b); // 1 149 | } 150 | 151 | console.log(a); // 5 152 | console.log(b); // 1 153 | ``` 154 | 155 | ES5: 156 | 157 | ```js 158 | 'use strict'; 159 | 160 | var a = 5; 161 | var b = 10; 162 | 163 | if (a === 5) { 164 | // technically is more like the following 165 | (function () { 166 | var a = 4; 167 | b = 1; 168 | 169 | console.log(a); // 4 170 | console.log(b); // 1 171 | })(); 172 | } 173 | 174 | console.log(a); // 5 175 | console.log(b); // 1 176 | ``` 177 | 178 | 179 | ES6: 180 | 181 | ```js 182 | // const creates a read-only named constant in ES6. 183 | 'use strict'; 184 | // define favorite as a constant and give it the value 7 185 | const favorite = 7; 186 | // Attempt to overwrite the constant 187 | try { 188 | favorite = 15; 189 | } catch (err) { 190 | console.log('my favorite number is still: ' + favorite); 191 | // will still print 7 192 | } 193 | ``` 194 | 195 | ES5: 196 | 197 | ```js 198 | 'use strict'; 199 | // define favorite as a non-writable `constant` and give it the value 7 200 | Object.defineProperties(window, { 201 | favorite: { 202 | value: 7, 203 | enumerable: true 204 | } 205 | }); 206 | // ^ descriptors are by default false and const are enumerable 207 | var favorite = 7; 208 | // Attempt to overwrite the constant 209 | favorite = 15; 210 | // will still print 7 211 | console.log('my favorite number is still: ' + favorite); 212 | ``` 213 | 214 | ## Template Literals 215 | 216 | ES6 Template Literals are strings that can include embedded expressions. This is sometimes referred to as string interpolation. 217 | 218 | ES6: 219 | 220 | ```js 221 | // Basic usage with an expression placeholder 222 | var person = 'Addy Osmani'; 223 | console.log(`Yo! My name is ${person}!`); 224 | 225 | // Expressions work just as well with object literals 226 | var user = {name: 'Caitlin Potter'}; 227 | console.log(`Thanks for getting this into V8, ${user.name}.`); 228 | 229 | // Expression interpolation. One use is readable inline math. 230 | var a = 50; 231 | var b = 100; 232 | console.log(`The number of JS frameworks is ${a + b} and not ${2 * a + b}.`); 233 | 234 | // Multi-line strings without needing \n\ 235 | console.log(`string text line 1 236 | string text line 2`); 237 | 238 | // Functions inside expressions 239 | function fn() { return 'result'; } 240 | console.log(`foo ${fn()} bar`); 241 | ``` 242 | 243 | ES5: 244 | 245 | ```js 246 | 'use strict'; 247 | 248 | // Basic usage with an expression placeholder 249 | var person = 'Addy Osmani'; 250 | console.log('Yo! My name is ' + person + '!'); 251 | 252 | // Expressions work just as well with object literals 253 | var user = { name: 'Caitlin Potter' }; 254 | console.log('Thanks for getting this into V8, ' + user.name + '.'); 255 | 256 | // Expression interpolation. One use is readable inline math. 257 | var a = 50; 258 | var b = 100; 259 | console.log('The number of JS frameworks is ' + (a + b) + ' and not ' + (2 * a + b) + '.'); 260 | 261 | // Multi-line strings: 262 | console.log('string text line 1\nstring text line 2'); 263 | // Or, alternatively: 264 | console.log('string text line 1\n\ 265 | string text line 2'); 266 | 267 | // Functions inside expressions 268 | function fn() { 269 | return 'result'; 270 | } 271 | console.log('foo ' + fn() + ' bar'); 272 | ``` 273 | 274 | 275 | ## Computed Property Names 276 | 277 | Computed property names allow you to specify properties in object literals based on expressions: 278 | 279 | ES6: 280 | 281 | ```js 282 | var prefix = 'foo'; 283 | var myObject = { 284 | [prefix + 'bar']: 'hello', 285 | [prefix + 'baz']: 'world' 286 | }; 287 | 288 | console.log(myObject['foobar']); 289 | // -> hello 290 | console.log(myObject['foobaz']); 291 | // -> world 292 | ``` 293 | 294 | ES5: 295 | 296 | ```js 297 | 'use strict'; 298 | 299 | var prefix = 'foo'; 300 | var myObject = {}; 301 | 302 | myObject[prefix + 'bar'] = 'hello'; 303 | myObject[prefix + 'baz'] = 'world'; 304 | 305 | console.log(myObject['foobar']); 306 | // -> hello 307 | console.log(myObject['foobaz']); 308 | // -> world 309 | ``` 310 | 311 | ## Destructuring Assignment 312 | 313 | The destructuring assignment syntax is a JavaScript expression that makes it possible to extract data from arrays or objects using a syntax that mirrors the construction of array and object literals. 314 | 315 | 316 | ES6: 317 | 318 | ```js 319 | var {foo, bar} = {foo: 'lorem', bar: 'ipsum'}; 320 | // foo => lorem and bar => ipsum 321 | ``` 322 | 323 | ES5: 324 | 325 | ```js 326 | 'use strict'; 327 | 328 | var _ref = { foo: 'lorem', bar: 'ipsum' }; 329 | 330 | // foo => lorem and bar => ipsum 331 | var foo = _ref.foo; 332 | var bar = _ref.bar; 333 | ``` 334 | 335 | ES3: 336 | 337 | ```js 338 | with({foo: 'lorem', bar: 'ipsum'}) { 339 | // foo => lorem and bar => ipsum 340 | } 341 | ``` 342 | 343 | ES6: 344 | 345 | ```js 346 | var [a, , b] = [1,2,3]; 347 | ``` 348 | 349 | ES6 (shimming using `Symbol.iterator`): 350 | 351 | ```js 352 | 'use strict'; 353 | 354 | var _slicedToArray = function (arr, i) { 355 | if (Array.isArray(arr)) { 356 | return arr; 357 | } else { 358 | var _arr = []; 359 | 360 | for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { 361 | _arr.push(_step.value); 362 | 363 | if (i && _arr.length === i) { 364 | break; 365 | } 366 | } 367 | 368 | return _arr; 369 | } 370 | }; 371 | 372 | var _ref = [1, 2, 3]; 373 | 374 | var _ref2 = _slicedToArray(_ref, 3); 375 | 376 | var a = _ref2[0]; 377 | var b = _ref2[2]; 378 | ``` 379 | 380 | ES5: 381 | 382 | ```js 383 | String.prototype.asNamedList = function () { 384 | return this.split(/\s*,\s*/).map(function (name, i) { 385 | return name ? ('var ' + name + '=slice(' + i + ', ' + (i + 1) + ')[0]') : ''; 386 | }).join(';'); 387 | }; 388 | 389 | with([1,2,3]) { 390 | eval('a, , b'.asNamedList()); 391 | } 392 | ``` 393 | 394 | 395 | ## Default Parameters 396 | 397 | Default parameters allow your functions to have optional arguments without needing to check arguments.length or check for undefined. 398 | 399 | ES6: 400 | 401 | ```js 402 | function greet(msg='hello', name='world') { 403 | console.log(msg,name); 404 | } 405 | 406 | greet(); 407 | // -> hello world 408 | greet('hey'); 409 | // -> hey world 410 | ``` 411 | 412 | ES5: 413 | 414 | ```js 415 | 'use strict'; 416 | 417 | function greet() { 418 | // unfair ... if you access arguments[0] like this you can simply 419 | // access the msg variable name instead 420 | var msg = arguments[0] === undefined ? 'hello' : arguments[0]; 421 | var name = arguments[1] === undefined ? 'world' : arguments[1]; 422 | console.log(msg, name); 423 | } 424 | 425 | function greet(msg, name) { 426 | (msg === undefined) && (msg = 'hello'); 427 | (name === undefined) && (name = 'world'); 428 | console.log(msg,name); 429 | } 430 | 431 | // using basic utility that check against undefined 432 | function greet(msg, name) { 433 | console.log( 434 | defaults(msg, 'hello'), 435 | defaults(name, 'world') 436 | ); 437 | } 438 | 439 | greet(); 440 | // -> hello world 441 | greet('hey'); 442 | // -> hey world 443 | ``` 444 | 445 | ES6: 446 | 447 | ```js 448 | function f(x, y=12) { 449 | // y is 12 if not passed (or passed as undefined) 450 | return x + y; 451 | } 452 | 453 | f(3) === 15; 454 | ``` 455 | 456 | ES5: 457 | 458 | ```js 459 | 'use strict'; 460 | 461 | function f(x, y) { 462 | if (y === undefined) { 463 | y = 12; 464 | } 465 | 466 | return x + y; 467 | } 468 | 469 | f(3) === 15; 470 | ``` 471 | 472 | ## Iterators And For-Of 473 | 474 | Iterators are objects that can traverse a container. It's a useful way to make a class work inside a for of loop. 475 | The interface is similar to the iterators-interface. Iterating with a `for..of` loop looks like: 476 | 477 | ES6: 478 | 479 | ```js 480 | // Behind the scenes, this will get an iterator from the array and loop through it, getting values from it. 481 | for (let element of [1, 2, 3]) { 482 | console.log(element); 483 | } 484 | // => 1 2 3 485 | ``` 486 | 487 | ES6 (without using `for-of`, if `Symbol` is supported): 488 | 489 | ```js 490 | 'use strict'; 491 | 492 | for (var _iterator = [1, 2, 3][Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { 493 | var element = _step.value; 494 | console.log(element); 495 | } 496 | 497 | // => 1 2 3 498 | ``` 499 | 500 | ES5 (approximates): 501 | 502 | ```js 503 | // Using forEach() 504 | // Doesn't require declaring indexing and element variables in your containing 505 | // scope. They get supplied as arguments to the iterator and are scoped to just 506 | // that iteration. 507 | var a = [1,2,3]; 508 | a.forEach(function (element) { 509 | console.log(element); 510 | }); 511 | 512 | // => 1 2 3 513 | 514 | // Using a for loop 515 | var a = [1,2,3]; 516 | for (var i = 0; i < a.length; ++i) { 517 | console.log(a[i]); 518 | } 519 | // => 1 2 3 520 | ``` 521 | 522 | Note the use of `Symbol`. The ES5 equivalent would require a Symbol polyfill in order to correctly function. 523 | 524 | ## Classes 525 | 526 | This implements class syntax and semantics as described in the ES6 draft spec. Classes are a great way to reuse code. 527 | Several JS libraries provide classes and inheritance, but they aren't mutually compatible. 528 | 529 | ES6: 530 | 531 | ```js 532 | class Hello { 533 | constructor(name) { 534 | this.name = name; 535 | } 536 | 537 | hello() { 538 | return 'Hello ' + this.name + '!'; 539 | } 540 | 541 | static sayHelloAll() { 542 | return 'Hello everyone!'; 543 | } 544 | } 545 | 546 | class HelloWorld extends Hello { 547 | constructor() { 548 | super('World'); 549 | } 550 | 551 | echo() { 552 | alert(super.hello()); 553 | } 554 | } 555 | 556 | var hw = new HelloWorld(); 557 | hw.echo(); 558 | 559 | alert(Hello.sayHelloAll()); 560 | ``` 561 | 562 | ES5 (approximate): 563 | 564 | ```js 565 | function Hello(name) { 566 | this.name = name; 567 | } 568 | 569 | Hello.prototype.hello = function hello() { 570 | return 'Hello ' + this.name + '!'; 571 | }; 572 | 573 | Hello.sayHelloAll = function () { 574 | return 'Hello everyone!'; 575 | }; 576 | 577 | function HelloWorld() { 578 | Hello.call(this, 'World'); 579 | } 580 | 581 | HelloWorld.prototype = Object.create(Hello.prototype); 582 | HelloWorld.prototype.constructor = HelloWorld; 583 | HelloWorld.sayHelloAll = Hello.sayHelloAll; 584 | 585 | HelloWorld.prototype.echo = function echo() { 586 | alert(Hello.prototype.hello.call(this)); 587 | }; 588 | 589 | var hw = new HelloWorld(); 590 | hw.echo(); 591 | 592 | alert(Hello.sayHelloAll()); 593 | ``` 594 | 595 | A more faithful (albeit, slightly verbose) interpretation can be found in this [Babel](https://goo.gl/ZvEQDq) output. 596 | 597 | ## Modules 598 | 599 | Modules are mostly implemented, with some parts of the Loader API still to be corrected. Modules try to solve many issues in dependencies and deployment, allowing users to create modules with explicit exports, import specific exported names from those modules, and keep these names separate. 600 | 601 | *Assumes an environment using CommonJS* 602 | 603 | 604 | app.js - ES6 605 | 606 | ```js 607 | import math from 'lib/math'; 608 | console.log('2π = ' + math.sum(math.pi, math.pi)); 609 | ``` 610 | 611 | app.js - ES5 612 | 613 | ```js 614 | var math = require('lib/math'); 615 | console.log('2π = ' + math.sum(math.pi, math.pi)); 616 | ``` 617 | 618 | lib/math.js - ES6 619 | 620 | ```js 621 | export function sum(x, y) { 622 | return x + y; 623 | } 624 | export var pi = 3.141593; 625 | ``` 626 | 627 | lib/math.js - ES5 628 | 629 | ```js 630 | exports.sum = sum; 631 | function sum(x, y) { 632 | return x + y; 633 | } 634 | var pi = exports.pi = 3.141593; 635 | ``` 636 | 637 | lib/mathplusplus.js - ES6 638 | 639 | ```js 640 | export * from 'lib/math'; 641 | export var e = 2.71828182846; 642 | export default function(x) { 643 | return Math.exp(x); 644 | } 645 | ``` 646 | 647 | lib/mathplusplus.js - ES5 648 | 649 | ```js 650 | var Math = require('lib/math'); 651 | 652 | var _extends = function (target) { 653 | for (var i = 1; i < arguments.length; i++) { 654 | var source = arguments[i]; 655 | for (var key in source) { 656 | target[key] = source[key]; 657 | } 658 | } 659 | 660 | return target; 661 | }; 662 | 663 | var e = exports.e = 2.71828182846; 664 | exports['default'] = function (x) { 665 | return Math.exp(x); 666 | }; 667 | 668 | module.exports = _extends(exports['default'], exports); 669 | ``` 670 | 671 | ## Numeric Literals 672 | 673 | ES6: 674 | 675 | ```js 676 | var binary = [ 677 | 0b0, 678 | 0b1, 679 | 0b11 680 | ]; 681 | console.assert(binary === [0, 1, 3]); 682 | 683 | var octal = [ 684 | 0o0, 685 | 0o1, 686 | 0o10, 687 | 0o77 688 | ]; 689 | console.assert(octal === [0, 1, 8, 63]); 690 | ``` 691 | 692 | ES5: 693 | 694 | ```js 695 | 'use strict'; 696 | 697 | var binary = [0, 1, 3]; 698 | console.assert(binary === [0, 1, 3]); 699 | 700 | var octal = [0, 1, 8, 63]; 701 | console.assert(octal === [0, 1, 8, 63]); 702 | ``` 703 | 704 | ## Property Method Assignment 705 | 706 | Method syntax is supported in object initializers, for example see toString(): 707 | 708 | ES6: 709 | 710 | ```js 711 | var object = { 712 | value: 42, 713 | toString() { 714 | return this.value; 715 | } 716 | }; 717 | 718 | console.log(object.toString() === 42); 719 | // -> true 720 | ``` 721 | 722 | ES5: 723 | 724 | ```js 725 | 'use strict'; 726 | 727 | var object = { 728 | value: 42, 729 | toString: function toString() { 730 | return this.value; 731 | } 732 | }; 733 | 734 | console.log(object.toString() === 42); 735 | // -> true 736 | ``` 737 | 738 | ## Object Initializer Shorthand 739 | 740 | This allows you to skip repeating yourself when the property name and property value are the same in an object literal. 741 | 742 | ES6: 743 | 744 | ```js 745 | function getPoint() { 746 | var x = 1; 747 | var y = 10; 748 | 749 | return {x, y}; 750 | } 751 | 752 | console.log(getPoint() === { 753 | x: 1, 754 | y: 10 755 | }); 756 | ``` 757 | 758 | ES5: 759 | 760 | ```js 761 | 'use strict'; 762 | 763 | function getPoint() { 764 | var x = 1; 765 | var y = 10; 766 | 767 | return { x: x, y: y }; 768 | } 769 | 770 | console.log(getPoint() === { 771 | x: 1, 772 | y: 10 773 | }); 774 | ``` 775 | 776 | ## Rest Parameters 777 | 778 | Rest parameters allows your functions to have variable number of arguments without using the arguments object. 779 | The rest parameter is an instance of Array so all the array methods just work. 780 | 781 | ES6: 782 | 783 | ```js 784 | function f(x, ...y) { 785 | // y is an Array 786 | return x * y.length; 787 | } 788 | 789 | console.log(f(3, 'hello', true) === 6); 790 | // -> true 791 | ``` 792 | 793 | ES5: 794 | 795 | ```js 796 | 'use strict'; 797 | 798 | function f(x) { 799 | var y = []; 800 | y.push.apply(y, arguments) && y.shift(); 801 | 802 | // y is an Array 803 | return x * y.length; 804 | } 805 | 806 | console.log(f(3, 'hello', true) === 6); 807 | // -> true 808 | ``` 809 | 810 | ## Spread Operator 811 | 812 | The spread operator is like the reverse of rest parameters. It allows you to expand an array into multiple formal parameters. 813 | 814 | ES6: 815 | 816 | ```js 817 | function add(a, b) { 818 | return a + b; 819 | } 820 | 821 | let nums = [5, 4]; 822 | 823 | console.log(add(...nums)); 824 | ``` 825 | 826 | ES5: 827 | 828 | ```js 829 | 'use strict'; 830 | 831 | var _toArray = function (arr) { 832 | return Array.isArray(arr) ? arr : [].slice.call(arr); 833 | }; 834 | 835 | function add(a, b) { 836 | return a + b; 837 | } 838 | 839 | var nums = [5, 4]; 840 | console.log(add.apply(null, _toArray(nums))); 841 | ``` 842 | 843 | ES6: 844 | 845 | ```js 846 | function f(x, y, z) { 847 | return x + y + z; 848 | } 849 | // Pass each elem of array as argument 850 | f(...[1,2,3]) === 6; 851 | ``` 852 | 853 | ES5: 854 | 855 | ```js 856 | 'use strict'; 857 | 858 | function f(x, y, z) { 859 | return x + y + z; 860 | } 861 | // Pass each elem of array as argument 862 | f.apply(null, [1, 2, 3]) === 6; 863 | ``` 864 | 865 | ## Proxying a function object 866 | 867 | ES6: 868 | 869 | ```js 870 | var target = function () { 871 | return 'I am the target'; 872 | }; 873 | 874 | var handler = { 875 | apply: function (receiver, ...args) { 876 | return 'I am the proxy'; 877 | } 878 | }; 879 | 880 | var p = new Proxy(target, handler); 881 | console.log(p() === 'I am the proxy'); 882 | // -> true 883 | ``` 884 | 885 | ES5: 886 | 887 | No proxy in ES5, hard to intercept __noSuchMethod__ and others. 888 | 889 | ## Array-like object to array 890 | 891 | **Array.from** converts a single argument that is an array-like object or list (eg. `arguments`, `NodeList`, `DOMTokenList` (used by `classList`), `NamedNodeMap` (used by attributes property) into a new Array() and returns it. 892 | 893 | ES6: 894 | 895 | ```js 896 | var listFriends = function() { 897 | var friends = Array.from(arguments); 898 | friends.forEach(friend => { 899 | console.log(friend); 900 | }); 901 | }; 902 | listFriends('ann', 'bob'); 903 | // -> 'ann' 904 | // -> 'bob' 905 | 906 | 907 | var divs = document.querySelectorAll('div'); 908 | Array.from(divs).forEach(node => { 909 | console.log(node); 910 | }); 911 | // ->
...
912 | // ->
...
913 | ``` 914 | 915 | ES5: 916 | 917 | ```js 918 | var listFriends = function() { 919 | var friends = [].slice.call(arguments) 920 | friends.forEach(function(friend) { 921 | console.log(friend); 922 | }); 923 | }; 924 | listFriends('ann', 'bob'); 925 | // -> 'ann' 926 | // -> 'bob' 927 | 928 | 929 | var divsArray = [].slice.call(document.querySelectorAll('div')); 930 | divsArray.forEach(function(node) { 931 | console.log(node); 932 | }); 933 | // ->
...
934 | // ->
...
935 | ``` 936 | 937 | ## About 938 | 939 | Inspired by: 940 | 941 | * [ES6 Feature Proposals](http://tc39wiki.calculist.org/es6/) 942 | * [ES6 Features](https://github.com/lukehoban/es6features) 943 | * [ECMAScript 6 support in Mozilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla) 944 | * [Babel](https://babeljs.io) 945 | * [JS Rocks](http://jsrocks.org/) 946 | 947 | 948 | ## License 949 | 950 | This work is licensed under a [Creative Commons Attribution 4.0 International](http://creativecommons.org/licenses/by/4.0/) License. 951 | --------------------------------------------------------------------------------