Rubyist's Quick Guide to ECMAScript 5

Rubyist's Quick Guide to ECMAScript 5

Describes most important features added to JavaScript in the ES5 version (released in 2009) and available in the latest versions of popular browsers. This includes library additions:

- Array extensions (isArray, forEach, map, filter, reduce, reduceRight, every, some, indexOf, lastIndexOf)
- Date extensions (now, toISOString)
- String extensions (trim, trimLeft, trimRight)
- Function extensions (bind)
- JSON parsing (JSON.parse, JSON.stringify)

And some language/syntax extensions:

- object getters and setters
- object properties (configurable, enumerable)
- object introspection (keys, getPrototypeOf)
- object creation using prototypal inheritance (Object.create)
- protecting objects (seal, freeze)
- strict mode

145a2482320cc755549b37feb424d8c5?s=128

Kuba Suder

April 03, 2012
Tweet

Transcript

  1. 1.

    Rubyist’s Quick Guide to ECMAScript 5 Kuba Suder @psionides •

    jsuder • http://psionides.eu • Lunar Logic
  2. 3.

    ECMA-what?... • What you know as JavaScript, as an ECMA

    standard • “an unwanted trade name that sounds like a skin disease” – Brendan Eich
  3. 4.

    ECMA-what?... • What you know as JavaScript, as an ECMA

    standard • “an unwanted trade name that sounds like a skin disease” – Brendan Eich • ECMAScript 3 • Last version before ES5 – released in 1999 (!)
  4. 5.

    ECMA-what?... • What you know as JavaScript, as an ECMA

    standard • “an unwanted trade name that sounds like a skin disease” – Brendan Eich • ECMAScript 3 • Last version before ES5 – released in 1999 (!) • ECMAScript 4 • Dark ages: developed for 10 years, then abandoned
  5. 6.

    ECMA-what?... • What you know as JavaScript, as an ECMA

    standard • “an unwanted trade name that sounds like a skin disease” – Brendan Eich • ECMAScript 3 • Last version before ES5 – released in 1999 (!) • ECMAScript 4 • Dark ages: developed for 10 years, then abandoned • ECMAScript 5 • Minor update to ES3 to unify the various dialects and engines (2009)
  6. 7.

    ECMA-what?... • What you know as JavaScript, as an ECMA

    standard • “an unwanted trade name that sounds like a skin disease” – Brendan Eich • ECMAScript 3 • Last version before ES5 – released in 1999 (!) • ECMAScript 4 • Dark ages: developed for 10 years, then abandoned • ECMAScript 5 • Minor update to ES3 to unify the various dialects and engines (2009) • ECMAScript 6 / Harmony • The future – lets, arrows, classes and all the other cool stuff
  7. 8.

    ECMAScript 5 • Subset of ES4 – the least controversial

    parts • Extensions for: • Array • Date • Function • Object • String • Safe JSON parsing • Extended object properties • Strict mode
  8. 9.

    Array extensions • Array.isArray • map • filter • reduce,

    reduceRight • every • some • forEach • indexOf, lastIndexOf
  9. 10.

    Array.isArray Array.isArray([]); // => true Array.isArray(7); // => false •

    old way: x instanceof Array • old (proper) way, works across frames: Object.prototype.toString.call(x) === ‘[object Array]’
  10. 11.
  11. 12.

    Array#filter ['Ruby', 'Java', 'Perl', 'PHP'].filter(function(el, i, arr) { return el.match(/r/i);

    }); // => [“Ruby”, “Perl”] • unfortunately there’s no “Enumerable#detect”... = Enumerable#select in Ruby
  12. 13.

    Array#reduce var a = [4, 8, 15, 16, 23, 42];

    a.reduce(function(sum, el, i, arr) { return sum + el }); // => 108 a.reduce(function(sum, el) { return sum + el }, 9000); // => 9108 • there’s also Array#reduceRight and it does exactly what you think = Enumerable#inject in Ruby
  13. 14.

    Array#every var countries = ['Poland', 'Portugal', 'Peru']; var startsWithP =

    function(el, i, arr) { return el.match(/^P/); }; countries.every(startsWithP); // => true countries.push("India"); countries.every(startsWithP); // => false = Enumerable#all? in Ruby
  14. 15.

    Array#some var names = ['Marcin', 'Łukasz', 'Michał']; var endsWithA =

    function(el, i, arr) { return el.match(/a$/); }; names.some(endsWithA); // => false names.push("Ania"); names.some(endsWithA); // => true = Enumerable#any? in Ruby
  15. 16.

    Array#forEach ['one', 'two', 'three'].forEach(function(el, i, arr) { console.log(i + ":

    " + el); }); // 0: one // 1: two // 2: three • problem: no “break” instruction • use Array#every or Array#some and return false/true to stop • or use exceptions = Array#each in Ruby
  16. 17.

    Array#indexOf, #lastIndexOf var list = ['a', 'b', 'c', 'd', 'a',

    'b', 'c']; list.indexOf('c'); // => 2 list.indexOf('c', 3); // => 6 list.lastIndexOf('c'); // => 6 • yes, this really didn’t exist before ES5 (including IE8!) = Array#index, #rindex in Ruby
  17. 19.

    Date.now var d = Date.now(); // => 1365692504996 var date

    = new Date(d); date.toISOString(); // => "2013-04-11T15:01:44.996Z" = Time.now.to_i in Ruby
  18. 20.

    String#trim, #trimLeft, #trimRight var str = " text "; str.trim();

    // => "text" str.trimLeft(); // => "text " str.trimRight(); // => " text" = String#strip, #lstrip, #rstrip in Ruby
  19. 21.

    Function#bind var a = { city: "Krakow", printCity: function() {

    console.log(this.city) } }; a.printCity(); // => "Krakow" var printCity = a.printCity; printCity(); // => undefined (this == window) var boundPrint = a.printCity.bind(a); boundPrint(); // => "Krakow" (this == a) = $.proxy, _.bind
  20. 22.

    JSON parsing var json = ‘{"a":1,"b":{"c":2}}’; var obj = JSON.parse(json);

    // => { a: 1, b: { c: 2 }} JSON.stringify(obj); // => "{\"a\":1,\"b\":{\"c\":2}}" • you could use eval, but eval is evil (just ask Crockford) • polyfill: json2.js (by Crockford) • included in IE8 (!)
  21. 23.

    Object extensions • Getters and setters • Protecting objects •

    Defining properties • Object introspection • Prototypal inheritance
  22. 24.

    Getters & setters var obj = { get v() {

    return 42 }, set v(x) { this.x = x } }; obj.v = 5; console.log(obj.v); // => 42
  23. 25.

    Protecting objects • Object.preventExtensions(o) • New fields can’t be added

    • Object.isExtensible(o) === false • Object.seal(o) • Fields can’t be added or deleted • Object.isSealed(o) === true • Object.freeze(o) • Fields can’t be added, deleted or modified • Object.isFrozen(o) === true
  24. 26.

    Defining object properties var obj = {}; Object.defineProperty(obj, 'x', {

    value: 5, writable: false }); obj.x; // => 5 obj.x = 1; obj.x; // => still 5 • other options: • get, set – specifies getter/setter • enumerable – tells if the field is listed when iterating with “for i in ...” • configurable – if the field can be deleted or its properties changed
  25. 27.

    Object introspection var obj = { x: 1 }; Object.keys(obj);

    Object.getOwnPropertyNames(obj); // => ["x"] (like Hash#keys) Object.getOwnPropertyDescriptor(obj, 'x'); // => { value: 1, writable: true, enumerable: true, // configurable: true } var a = []; Object.getPrototypeOf(a); // => Array.prototype
  26. 28.

    Prototypal inheritance var Fruit = { color: ‘red’ }; var

    apple = Object.create(Fruit); apple.__proto__; // => Fruit apple.color; // => ‘red’ • objects inheriting from objects, instead of classes inheriting from classes • was possible before, but required creating an anonymous class
  27. 29.

    Strict mode “use strict”; // yes, it’s just a string

    bug = 0; // => ReferenceError: bug is not defined • like a built-in JSLint • throws errors instead of ignoring problems • missing in older browsers (IE <10, FF <4)
  28. 30.

    Browser support • Full support in: • IE 9 (strict

    mode in 10) • FF 4 • Chrome 7 (strict mode in 13) • Opera 12 • Safari 5.1 (bind in 5.1.4) • ... and NodeJS • Compatibility table: http://kangax.github.com/es5-compat-table
  29. 32.

    What’s the point? • more natural and readable (for a

    Rubyist): list.map(...).forEach(...) vs. _.each(_.map(list, ...), ...) • doesn’t require libraries (except the shim, for now) • future-proof (should still work like this in 2020) • potentially faster if implemented natively
  30. 33.

    let es6 = (es5) => es5 + 1 Coming to

    a browser near you in 2013-14 (?)