0

From below example, I think I understand all the code except I cannot get my head around why this.assert and this.test is needed?? Can't this code stand without them?

This is from the book Secrets of the javascript ninja

 <script>   
    (function() {
        var results;
        this.assert = function assert(value,desc) {
            var li = document.createElement("li");
            li.className = value ? "pass" : "fail";
            li.appendChild(document.createTextNode(desc));
            results.appendChild(li);

            if (!value) {
                li.parentNode.parentNode.className = "fail";
            }
            return li;
        };
        this.test = function test(name,fn) {
            console.log("JOT");
            results = document.getElementById("results");
            console.log("this is" , results)
            results = assert(true, name).appendChild(
                document.createElement("ul"));
            fn();
        };
    })();

    window.onload = function() {
            console.log("before");
        test("A test.", function() {
            console.log("after a test");
            assert(true, "First assertion completed");
            console.log("after assert1");
            assert(true, "Second assertion completed");
            console.log("after assert2");
            assert(true, "Third assertion completed");
            console.log("after assert3");
        });
        test("Another test.", function() {
            assert(true, "First test completed");
            assert(true, "Second test completed");
            assert(false, "Third test fail");
        });
        test("Another test.", function() {
            assert(true, "First test completed");
            assert(true, "Second test completed");
            assert(true, "Third test completed");
        });
    };
</script>
user3502374
  • 781
  • 1
  • 4
  • 12
  • What do you mean "why are they needed"? If they weren't there, you wouldn't be able to call them in the window.onload method. – VtoCorleone Apr 07 '14 at 01:30
  • The use of named function expressions here is ill advised. Some versions of [IE have issues with them](http://kangax.github.io/nfe/#jscript-bugs), and the names *should* only be available within the function itself. Given that the names aren't used within the functions themselves, it doesn't seem sensible to have them. I also don't think this is a sensible way to create properties of the global object. It also seems to me that it should fail in strict mode. – RobG Apr 07 '14 at 01:55
  • The use of named function expressions is a good idea. It helps debugging. – guest Apr 07 '14 at 02:33
  • Given the issues with IE and strict mode, and that they can be replaced with function declarations, I don't see the point. Consider instead: `(function(global){var result; function assert(){...}; global.assert = assert; ...}(this));`. Works everywhere (including strict mode), names are available inside functions for debugging, they are explicitly added as globals and the closure to *result* is preserved. Lots of wins there. :-) – RobG Apr 07 '14 at 02:48

1 Answers1

1

this in the top function refers to the global object, because it's called neither as a constructor nor as a method. In a web browser, the global object is window.

Anyway, assigning a property to the global object allows you to reference it as a global variable. Later on in the code, assert and test are available in the onload function.

So why not just say window.assert = ...? One reason is that the construction in the code sample is slightly more portable, in case you need to run it in a JavaScript environment where the global object isn't window.

guest
  • 6,450
  • 30
  • 44
  • Appreciate everyone's answer(collectively it helped me to understand better). What got me more confused was the fact that function name assert and this.assert had same name. (It helped me great deal to go either anonymous function or name function differently. – user3502374 Apr 07 '14 at 03:21