Posts

Showing posts with the label jslang

Why is (0,obj.prop)() not a method call?

This blog post explores references , a mechanism used by the ECMAScript language specification to explain the difference between the following two expressions: obj.prop() (0, obj.prop)() Method calls versus function calls Consider the following object: var obj = { getThis: function () { "use strict"; return this; }, }; If you call obj.getThis , you have a method call ( this points to the object in which the method is stored): > obj.getThis() === obj true If you store obj.getThis in a variable and then call it, you are making a function call: > var func = obj.getThis; > func() undefined The effect is the same if you use the comma operator. Quick recap – the comma operator works like this: (expr1, expr2) === expr2 That is, both expressions are evaluated, the result of the whole expression is expr2 . If you apply the comma operator to obj.getThis before calling it, you are also making a f...

Five little-known facts about ES5 object literals

This blog post describes five little known facts about ECMAScript 5 (ES5) object literals: ECMAScript 5 has getters and setters Trailing commas are legal You often don’t have to quote property keys You can use reserved words as unquoted property keys Using objects as dictionaries is surprisingly tricky ECMAScript 5 has getters and setters ECMAScript 5 supports getters and setters. You can create them either via property descriptors or via object literals: var obj = { get foo() { return Math.random(); }, set foo(value) { console.log('SET foo = '+value); }, }; Let’s use obj in a REPL: > obj.foo 0.6029663002118468 > obj.foo 0.99780507478863 > obj.foo = 123; SET foo = 123 Trailing commas are legal Starting with ES5, it is legal to put a comma after the last property. That helps whenever you want to rearrange properties, especially if there is one property per line: var translation...

ECMAScript 6 promises (2/2): the API

Image
This blog post is outdated. Please read chapter “ Promises for asynchronous programming ” in “Exploring ES6”. This blog post is an introduction to asynchronous programming via promises in general and the ECMAScript 6 (ES6) promise API in particular. It is second in a series of two posts – part one explains foundations of asynchronous programming (which you may need to learn in order to fully understand this post). Given that the ECMAScript 6 promise API is easy to polyfill for ECMAScript 5, I’m mainly using function expressions and not ECMAScript 6 arrow functions , even though the latter are much less verbose. Promises Promises are a pattern that helps with one particular kind of asynchronous programming: functions (or methods) that return their results asynchronously. To implement such a function, you return a promise , an object that is a placeholder for the result. The caller of the function registers callbacks with the promise to be notified once the result has been computed. Th...

ECMAScript 6 promises (1/2): foundations

Image
This blog post is outdated. Please read chapter “ Asynchronous programming (background) ” in “Exploring ES6”. This blog post explains foundations of asynchronous programming in JavaScript. It is first in a series of two posts and prepares you for part two , which covers promises and the ECMAScript 6 promise API. The JavaScript call stack When a function f calls a function g , g needs to know where to return to (inside f ) after it is done. This information is usually managed with a stack, the call stack . Let’s look at an example. function h(z) { // Print stack trace console.log(new Error().stack); // (A) } function g(y) { h(y + 1); // (B) } function f(x) { g(x + 1); // (C) } f(3); // (D) return; // (E) Initially, when the program above is started, the call stack is empty. After the function call f(3) in line (D), the stack has one entry: Location in global scope After the function call g(x + 1) in line (C), the stack...

Preventing function signature mismatch in ES5 and ES6

In some cases, using a function (or method) with a callback can lead to surprising results – if the signature of the latter does not match the expectations of the former. This blog post explains this phenomenon and suggests fixes. Function signature mismatch Let’s look at an example [1] : > ['1','2','3'].map(parseInt) [1,NaN,NaN] Here, map() expects the following signature: callback(element, index, array) But parseInt() has the signature: parseInt(string, radix?) It’s not a problem that parseInt ’s arity is less than the 3 expected by map ; JavaScript does not complain if you ignore arguments. However, index and the optional radix don’t match semantically. Whenever you are using a library function as a callback, you are taking a risk: its signature may not match semantically, it may even change later on. Preventing mismatch Prevention via arrow functions In ECMAScript 6, arrow functions [2] give you the means to be explicit about the sig...