SitePoint Sponsor

User Tag List

Results 1 to 22 of 22
  1. #1
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,871
    Mentioned
    206 Post(s)
    Tagged
    12 Thread(s)

    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 & Pullo

  2. #2
    #titanic {float:none} silver trophy
    molona's Avatar
    Join Date
    Feb 2005
    Location
    from Madrid to Heaven
    Posts
    8,171
    Mentioned
    233 Post(s)
    Tagged
    1 Thread(s)
    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

  3. #3
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,871
    Mentioned
    206 Post(s)
    Tagged
    12 Thread(s)
    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.

  4. #4
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,784
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Pullo View Post
    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.

    Code:
    var foo = function foo() {
        console.log(foo === foo);  
    };
    foo();
    The relevant part of this is foo === foo which is true


    Code:
    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.


    Code:
    Number("1") - 1 == 0;
    1-1 = 0 therefore true.


    Code:
    (true + false) > 2 + true;
    (1 + 0) > 2 + 1 is false.


    Code:
    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:

    Code:
    function bar() {
        var foo;
        function foo() {}
        return foo;
    }
    alert(typeof bar());
    so it alerts function.


    Code:
    "1" - - "1";
    1 - -1 = 1 + 1 = 2


    Code:
    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.


    Code:
    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.



    Code:
    [] + [] + 'foo'.split('');
    'foo'.split('') creates the string 'f,o,o'

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



    Code:
    new Array(5).toString();
    Creates an array of five entries all of which are undefined and then converts then to a string giving ',,,,'



    Code:
    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']



    Code:
    String('Hello') === 'Hello';
    JavaScript treats string primitives and string objects as the same type when doing comparisons
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  5. #5
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,871
    Mentioned
    206 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by felgall View Post
    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.
    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.

    Quote Originally Posted by felgall View Post
    Code:
    var foo = function foo() {
        console.log(foo === foo);  
    };
    foo();
    The relevant part of this is foo === foo which is true
    I got this right, too.
    foo is a function which is equal to itself.

    Quote Originally Posted by felgall View Post
    Code:
    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).
    I got this wrong, as I missed the fact that a linefeed terminates a return statement

    Quote Originally Posted by felgall View Post
    Code:
    Number("1") - 1 == 0;
    1-1 = 0 therefore true.
    Yup!

    Quote Originally Posted by felgall View Post
    Code:
    (true + false) > 2 + true;
    (1 + 0) > 2 + 1 is false.
    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

    Quote Originally Posted by felgall View Post
    Code:
    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:

    Code:
    function bar() {
        var foo;
        function foo() {}
        return foo;
    }
    alert(typeof bar());
    so it alerts function.
    Good explanation. I knew that the function and the var would get hoisted, but I couldn't remember in which order.

    Quote Originally Posted by felgall View Post
    Code:
    "1" - - "1";
    1 - -1 = 1 + 1 = 2
    Indeed.
    Although the quotes had me a bit confused

    Quote Originally Posted by felgall View Post
    Code:
    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.
    This I don't get.
    I would have thought both run in same scope.

    Quote Originally Posted by felgall View Post
    Code:
    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.
    Yup.

    Quote Originally Posted by felgall View Post
    Code:
    [] + [] + 'foo'.split('');
    'foo'.split('') creates the string 'f,o,o'

    concatenating an empty array to a string does not change the string.
    I went for ["f", "o", "o"], which is what it would have returned in Ruby.

    Quote Originally Posted by felgall View Post
    Code:
    new Array(5).toString();
    Creates an array of five entries all of which are undefined and then converts then to a string giving ',,,,'
    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/pri...ipt-array.html

    Quote Originally Posted by felgall View Post
    Code:
    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']
    Indeed

    Quote Originally Posted by felgall View Post
    Code:
    String('Hello') === 'Hello';
    JavaScript treats string primitives and string objects as the same type when doing comparisons
    I didn't know/remember this (but guessed correctly )

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

  6. #6
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,784
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Pullo View Post
    This I don't get.
    I would have thought both run in same scope.
    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.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  7. #7
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,246
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    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).
    "First make it work. Then make it better."

  8. #8
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,784
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    [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).
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  9. #9
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,246
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by felgall View Post
    With regard to lexical environment - go() is defined within global scope and bar() is defined within baz scope.
    "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.
    "First make it work. Then make it better."

  10. #10
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,871
    Mentioned
    206 Post(s)
    Tagged
    12 Thread(s)
    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!

  11. #11
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,387
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    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.

  12. #12
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,784
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    "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.
    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.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  13. #13
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,246
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by felgall View Post
    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".
    "First make it work. Then make it better."

  14. #14
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,246
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    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.
    "First make it work. Then make it better."

  15. #15
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,784
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    IFunctions create a new lexical environment (scope), plain objects do not.
    Thanks. I wasn't aware that the way you define the objects makes a difference.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  16. #16
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,871
    Mentioned
    206 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by fretburner View Post
    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.
    Hey fretburner,

    Thanks for the link. Most informative.

    Now I have a question.

    From earlier on in this thread:

    Quote Originally Posted by felgall
    Code:
    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:

    Code:
    function bar() {
        var foo;
        function foo() {}
        return foo;
    }
    alert(typeof bar());
    so it alerts function.
    However, in the article the author says:

    Quote Originally Posted by David Shariff
    ... we know from the creation stage that functions are created on the activation object before variables, and if the property name already exists on the activation object, we simply bypass the decleration.
    So doesn't that mean that this code:

    Code:
    function bar() {
        return foo;
        foo = 10;
        function foo() {}
        var foo = '11';
    }
    alert(typeof bar());
    is actually evaluated thus by the JS interpreter:

    Code:
    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?

  17. #17
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,246
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    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:

    ...

    is actually evaluated thus by the JS interpreter:

    ...

    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.
    "First make it work. Then make it better."

  18. #18
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,246
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    ... 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.
    "First make it work. Then make it better."

  19. #19
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,871
    Mentioned
    206 Post(s)
    Tagged
    12 Thread(s)
    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.

  20. #20
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,246
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    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.
    "First make it work. Then make it better."

  21. #21
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,387
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    It was my understanding that the author was using an imaginary object to make it easier to explain the concepts, as in the article he says:
    It is possible to represent each execution context conceptually as an object with 3 properties
    and goes on to talk about the activation / variable object.

  22. #22
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,871
    Mentioned
    206 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    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.
    Thank you, I just read through that.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •