Category Archives: Javascript

Exploring ES6

Given that most of my work these days is HTML5 based, I figured it was time to start looking into ES6 – A long overdue update to Javascript.

For someone that’s used to working with C++ (and AS3), I like IDEs – every developer does. But JS is an ugly beast. An IDE can’t do things like find a function definition or where a var is used with JS (other than through text search which is rarely accurate since the var name is likely not unique). So ES6 features like modules and classes look great.

To my surprise, modules aren’t yet supported in Chrome or Firefox. You need to use Babel or Traceur. I’ve been using RequireJS for the 30k LOC project at work but I thought I could start considering native support with import/export. No go.

What’s worse is that import isn’t explicitly supported by Babel.  You need to use browserify because Babel will translate imports to CommonJS.  So my gulp script is (once again) starting to look awkward.

Ideally, I want to code in ES6, use a watcher to compile automatically, and debug in Chrome’s dev tools with source maps so that I don’t ever see the fugliness.

I’ll post my results if and when I get something feasible.

Javascript scope and the “self” argument

Really great post on the Node.js group from “Zhami” (at http://yellowhelium.com/ I believe).  You can see the original post here: http://groups.google.com/group/nodejs/browse_thread/thread/d5c4cefdc255c548

“this” is an interesting entity in JavaScript functions; its value in a function depends on the nature of the function and how the function was invoked. Douglas Crockford describes four invocation patterns [1]. When you see the idiom “var self = this;” [2], most likely the invocation pattern is for a method [3]. In such case, “this” is a reference to the object containing the method. Such an object may have other properties which can be accessed via “this” by dot notation:

e.g., this.propertyName.

JavaScript does not have block scoping, it has function scoping [4]. A variable declared with a var statement (anywhere) within a function has scope within that function and within any (inner) functions declared within that (outer) function. The inner function’s accessing of the value of the outer functions variable is a “closure.” While quite powerful, their use can sometimes bear gotchas, still, they are immensely useful [5].

In a simple (illustrative, not useful) example:

var foo = function (k) {
var i, bar;
i = 3;
bar = function (j) {
i = i + 1;
return i + j;
}
return bar(k);
}

Inner function bar is lexically scoped within outer function foo. Inner function bar can refer to outer function foo’s variables (and arguments). Inner function bar has access to foo’s variable “i” by closure. Any invocation of bar will use the *current* value of i (not
the initially lexically declared value; such mutation of variables accessed by closure is often a source of gotchas with callback functions).

btw: in this simple example, “k” is also accessible to bar, and so doesn’t need to be passed in:

var foo = function (k) {
var i, bar;
i = 3;
bar = function () {
i = i + 1;
return i + k;
}
return bar();
}

Now, consider the case where you have a method of an object that has some properties, and that the method has an inner function which wants to access the value of a property (again, a highly contrived example):


var o = {
i: 3,
bar: function (k) {
var bar;
bar = function () {
i = i + 1;
return i + k;
}
return bar();
}
}

This is created with the expectation that we can invoke:
o.bar(n); // where n is some numeric value
The problem with the above code is that bar has not declared “i” nor is there any variable “i” in its scope chain (i.e., method bar doesn’t declare “i” either) [6]. At first blush you may say, “ah, but ‘this’ in foo refers to the object” and try:

var o = {
i: 3,
bar: function (k) {
var bar;
console.log("i = " + this.i);
bar = function () {
var i = this.i; // gain local access to the property
i = i + 1;
return i + k;
}
return bar();
}
}

But this doesn’t work (double entendre intended).

Presuming that bar is invoked as a method of object o, “this” within foo does provide access to object o’s properties. However, function bar is invoked by the function invocation pattern, and within it, “this” is set to the global context, *not* the object.
So, to make the above concept work, we can create a closure to provide access to the object:


var o = {
i: 3,
bar: function (k) {
var bar,
self = this;
bar = function () {
self.i = self.i + 1;
return self.i + k;
}
return bar();
}
}

In the above, the variable “self” is assigned a value that is a reference to the object. Unless “self” is mutated, it remains a reference to the object. More practical use cases involve callbacks and (often, anonymous) functions:


var o = {
i: 3,
bar: function (k) {
var bar,
self = this;
someAsyncFunction( arg, function (callbackArg) {
// here, "this" is a reference to the global context
// object o properties can be accessed via the "self"
closure, e.g.:
self.i = self.i + 1;
});
}
}

Idiomatically, you may also see “var that = this” and “var me = this”. Personally, I now avoid “self” because, alas, many Browsers define a global “self” variable, and so I have had bugs caused by not declaring “var self = this” when I needed it, yet “self” was defined (arggh).

Note: I have typed all this in and have *not* executed the code, so use at your own risk (lol).

1. “JavaScript: The Good Parts”, http://oreilly.com/catalog/9780596517748

2. Since I minify most of my JS code, I am diligent about including
semicolons.

3. a “method” is a function that is a property of an object.

4. I am appalled by how much JS code I see posted in which coders use
var statements in a way that implies they believe there is block
scope.

5. Clsoures are a good way of creating private object members: see
Stoyan Stefanov “JavaScript Patterns”.

6. Granted, there may be a global variable — but that would be
horrific programming practice.

JSONP and jQuery

Nice little trick I just found out about the getJSON function in jQuery. If you add an extra “?” to the end of the url, it’ll read it as JSONP.  JSONP simply wraps the server’s response (JSON object) in a function. It’s a way to work around cross domain issues. We can finally use the widget creator anywhere, no just on the artist’s own site.