This Week in JavaScript - 10 February 2014

Your weekly update of JavaScript news and goodies.

Top of the hour

JavaScript Web Quiz - how high can you score?
You might not need jQuery - as unthinkable as it sounds
Malware hides behind JavaScript - attack uses malware encoded as images and delivered through iframe injection
And just like that Grunt and RequireJS are out - it’s all about Gulp and Browserify now
JS1k: The JavaScript code golfing competition - has now begun

Tutorials

How to make a responsive gallery with directional-aware hover
Draggable elements that push others out of the way
A re-introduction to JavaScript (JS Tutorial) - from MDN
A Dive Into Plain JavaScript - Thank you @ralph.m
Implementing Backwards-Compatible CSS3 Animated Transitions

Frameworks

Yet Another Framework Syndrome - before you go all framework happy
5 Rules for Better Backbone Code
Get your Backbone straight - how to structure a Backbone app
Processing Forms in AngularJS - AngularJS forms are nifty, HTML5 friendly, and incredibly fun to code!
7 Minimal Node.js Web Frameworks for 2014 and Beyond

Libraries

JointJS - JavaScript diagramming library
JZed.js - The functional jQuery alternative
Base Transcoder - If you need to translate bases a lot
The best ever spinner for blocking your code
AreYouSure.js - Inline confirmation dialogs for Javascript.

So how did you score on the JavaScript Web Quiz?
Let us know and we’ll compare scores

Please PM us if you have anything of interest for the next issue, and happy reading! - Paul & [URL=“http://www.sitepoint.com/forums/private.php?do=newpm&u=184222”]Pullo

Creating a quizz is a very interesting way to promote your book. I have to say that my score was 50% (or 10) which I think is great because I haven’t used Javascript in one year. It should have been 11 but I was a bit too quick to click on one of the answers :slight_smile:

Hey molona,

Glad to see you having a go at the quiz - congratulations on a great score!
I too, scored 50% - but some of the questions were devilish (function hoisting and all that).

@fretburner ; @paul_wilkins ; @felgall ; fancy having a go?
It would be fun to examine some of the questions and find out why the answer is what it is.

I rushed through it the first time and got just under half of them right. They are all good examples of how NOT to write JavaScript as many of the answers are not obvious unless you take the time to properly examine the code.

To start off on why the code in the questions give those results, here’s my analysis of the first twelve questions.

var foo = function foo() {
    console.log(foo === foo);  
};
foo();

The relevant part of this is foo === foo which is true

function aaa() {
    return
    {
        test: 1
    };
}
alert(typeof aaa());

A return without a value after it returns undefined (and the object is a different statement as a linefeed terminates a return statement.

Number("1") - 1 == 0;

1-1 = 0 therefore true.

(true + false) > 2 + true;

(1 + 0) > 2 + 1 is false.

function bar() {
    return foo;
    foo = 10;
    function foo() {}
    var foo = '11';
}
alert(typeof bar());

Hoisting the declarations and removing the unreachable statements makes this the equivalent of:

function bar() {
    var foo;
    function foo() {}
    return foo;
}
alert(typeof bar());

so it alerts function.

"1" - - "1";

1 - -1 = 1 + 1 = 2

var x = 3;

var foo = {
    x: 2,
    baz: {
        x: 1,
        bar: function() {
            return this.x;
        }
    }
}

var go = foo.baz.bar;

alert(go());
alert(foo.baz.bar());

For both answers foo.baz.bar() gets run - the difference is the scope it runs in which determines which of the x values that this.x refers to

First value:

go() executes in global scope so this is window so x is 3

Second value:

foo.baz.bar() runs bar in baz scope so x = 1.

new String("This is a string") instanceof String;

A bit of a trick question since a new String is of course an instance of a String.

[] + [] + 'foo'.split('');

‘foo’.split(‘’) creates the string ‘f,o,o’

concatenating an empty array to a string does not change the string.

new Array(5).toString();

Creates an array of five entries all of which are undefined and then converts then to a string giving ‘,’

var myArr = ['foo', 'bar', 'baz'];
myArr.length = 0;
myArr.push('bin');
console.log(myArr);

Setting the length of an array to zero empties the content so this returns [‘bin’]

String('Hello') === 'Hello';

JavaScript treats string primitives and string objects as the same type when doing comparisons

Yeah, that’s for sure and I think they are intended to be quite devious.
Nonetheless, it’s fun to workout why the answers are like they are, as these are things that come up from time to time.

I got this right, too.
foo is a function which is equal to itself.

I got this wrong, as I missed the fact that a linefeed terminates a return statement

Yup!

I didn’t realise that any arithmetic operation will convert booleans to numbers.
This is quite amusing, as you can do: true + true + true === 3

Good explanation. I knew that the function and the var would get hoisted, but I couldn’t remember in which order.

Indeed.
Although the quotes had me a bit confused

This I don’t get.
I would have thought both run in same scope.

Yup.

I went for ["f", "o", "o"], which is what it would have returned in Ruby.

Yup.
I also remembered this trick of creating an array with n amount of undefined entries: Array.apply(0, Array(n))
Which I read about here: http://ariya.ofilabs.com/2013/07/prime-numbers-factorial-and-fibonacci-series-with-javascript-array.html

Indeed

I didn’t know/remember this (but guessed correctly :))

Thanks for taking the time to post those explanations Stephen.
I appreciate that.

var go defines go as being in global scope

var foo defines foo as in global scope

baz is defined in foo scope and bar is defined in baz scope

So even though go() runs foo.baz.bar() the function bar() runs in global scope when called using go() and in baz scope when called as foo.baz.bar()

I got about half of them wrong the first time through. It was only when writing up the explanations that I actually looked at them closely enough to figure out the reasons why the answers were what they are.

I think the word “scope” is ambiguous. There are a couple different things in JavaScript that can be thought of as “scope”.

  • There’s the variable lexical environment. This determines what variables a function has access to. This is probably what we most commonly think of as “scope”.

  • And there’s the this binding. This determines what the value of “this” will be during a particular function execution. This seems to be what felgall is referring to when he says “scope”.

When we invoke bar/go as a function and not as a method, then the global object is implicitly bound to “this”, so return this.x returns the global x (3). But when we call bar as a method – foo.baz.bar() – then baz is bound to “this”, so return this.x returns baz.x (1).

[QUOTE=Jeff Mott;5634354There are a couple different things in JavaScript that can be thought of as “scope”…[/QUOTE]

I actually refer to both.

With regard to lexical environment - go() is defined within global scope and bar() is defined within baz scope.

In the example being discussed the this binding is binding “this” to the object whose lexical scope the function is running in.

Can you provide an example of how the code being discussed could be modified so that “this” binding does not match the lexical scope of the object the function is called from (without using bind, call or apply).

“go” is defined in the global lexical environment, yes. But, “bar” is not defined in the “baz” lexical environment. In fact, there’s no such thing as the baz lexical environment. A new variable lexical environment is created when we create a function. So the function bar creates a new variable lexical environment, but the only relationship baz has to bar is that bar is a property of the object baz.

Just wanted to say thank you both for the explanations.
That really cleared it up for me (especially the bit about the this binding).

Good night!

Talking of ‘lexical environments’, the guy who wrote the JS test in question also wrote an interesting article on JavaScript’s Execution Context. He also mentions hoisting and how that works behind the scenes. It’s a good read for anyone who want’s to dive into this stuff in a little more depth.

I have always though of objects and functions in JavaScript as being effectively the same thing. I haven’t come across any instance where they behave differently.

So basically what you are saying is that because “baz” is an object rather than a function that the correct terminology is different even though the end result is the same.

It’s much more than terminology. You’ve probably heard the phrase, “JavaScript has function scope.” The “scope” being described in that phrase is the variable lexical environment. Functions create a new lexical environment (scope), plain objects do not. The most we can say about Baz is that it’s one among many possible objects that could be bound to “this”.

Based on this and other things you’ve written, I think you’re under the impression that variables and object properties are the same thing. For global variables, that’s actually true. But that’s the only time it’s true. Variables declared inside functions don’t belong to any object, nor do new object properties create new variables.

Thanks. I wasn’t aware that the way you define the objects makes a difference.

Hey fretburner,

Thanks for the link. Most informative.

Now I have a question.

From earlier on in this thread:

However, in the article the author says:

So doesn’t that mean that this code:

function bar() {
    return foo;
    foo = 10;
    function foo() {}
    var foo = '11';
}
alert(typeof bar());

is actually evaluated thus by the JS interpreter:

barExecutionContext = {
    scopeChain: { ... },
    variableObject: {
        arguments: {
            length: 0
        },
        foo: pointer to function foo()
    },
    this: { ... }
}

and that var foo is effectively ignored, as the property name already exists on the activation object.

Or did I get that wrong?

Looks like you got that exactly right. Both the David Shariff blog post and the ECMAScript spec say that function declarations are evaluated before variable declarations, so the var foo statement is ignored.

EDIT: I should rephrase that. The var declaration is ignored — not the whole statement. If not for the return, then foo = ‘11’ would have still been evaluated.

Thanks Jeff.
I just wanted to be sure that I had understood that correctly.

You mentioned the ECMAScript spec.
Do you know of any accessible way to browse that?
I downloaded the current version, but a search for “hoist”, “function declaration”, “variable declaration” and “activation object” didn’t turn up anything.
Could you point me to the bit where I can read that function declarations are evaluated before variable declarations.

Appreciate the help.

It’s interesting. “Hoisting” is certainly established terminology, but that term doesn’t appear to have originated from the spec. It’s nowhere in there. “Activation object” isn’t in there either. I’m not sure where that term came from. What the blog post calls the activation object appears to be what the spec calls the VariableEnvironment.

“FunctionDeclaration” is in there, but without the space. They write it in upper-camel case, a formal name of a grammar symbol.

The part about function declarations before variable declarations is in section 10.5 Declaration Binding Instantiation. Step 4 binds function parameters to the VariableEnvironment. Step 5 binds function declarations. Steps 6 and 7 binds “arguments”. And finally step 8 binds variable declarations.

EDIT: It appears that earlier versions of the ECMAScript spec uses the term “Activation Object”. That term appears in the 3rd edition. We’re currently in the 5th edition.