0

I am trying to understand the below snippet of code in javascript. I have tried to google to check the usage of creating javascript function in the below format, but i did not find any references.

Below is the my understanding of the code and plz correct if this is what the code and appreciate any reference Guide to check more on this type of using notation.

  1. function(obj) --> this is basically running a function in the global scope which is run on the load of the page after the DOM is loaded.
  2. obj['test'] = 'DummyObj'; This is creating a global variable. I guess i am sure on this usage.
  3. obj['test1'] = obj['test1'] || function(){ (obj['test1'].h = obj['test1'].h||[]).push(arguments) }, obj['test1'].m = 1 * new Date()
    I am having trouble in understanding this. My analysis is this is checking for if test1 object is null it is creating a function and in that function it is checking for 'h' object and if it is null it is creating an Empty Array and pushing the local 'arguments' Object. I don't understand the second part where we have a comma and date object is created? Does it mean that it would execute as one statement and create a 'm' local variable with current Date value?
  4. The last part where we are using (window) is what i don't understand completely. What does it mean? Can you please guide me where to further read on this

(function(obj) {
    obj['test'] = 'DummyObj';
    obj['test1'] = obj['test1'] || function(){
      (obj['test1'].h = obj['test1'].h||[]).push(arguments)
    },
    obj['test1'].m = 1 * new Date();
})(window);
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
Anil Reddy
  • 21
  • 1
  • you have a `,` instead of a `;` – Roko C. Buljan Feb 22 '16 at 19:47
  • I assume you didn't write this code yourself, so where did you find this, and why aren't you writing more sensible code that does the same thing, but in a more readable, less hacky way? – Mike 'Pomax' Kamermans Feb 22 '16 at 19:48
  • The above makes no sense at all: `= obj['test1'] || ` assumes there's an `window.test1` object, else use a `function()` but than suddenly you expect an `window.test1.h` to exist which will in any case throw an error. There's nothing to understand from that code. It's also totally buggy as I've stated before. – Roko C. Buljan Feb 22 '16 at 19:51
  • Not so hard to find http://stackoverflow.com/questions/8228281/what-is-the-function-construct-in-javascript ... – Aliz Feb 22 '16 at 19:52
  • 1
    Why the downvotes? OP is just asking about some crappy deliberate obtuse code, is that so wrong? They've even provided an attempt at analysis... – Jared Smith Feb 22 '16 at 20:00

2 Answers2

0

I took the code you posted and marked it up with some comments that try to describe what is going on.

// wrap code in a self-executing function
// this creates a scope-boundary, but since you are not using
// the "var" keyword anywhere it doesn't matter much
// the "obj" argument is the global "window" variable
// made available by the execution content (most-likely your web-browser)
(function(obj) {

    // create a "test" variable that live off of the "window" object
    // so: window.test = 'DummyObj';
    obj['test'] = 'DummyObj';

    // if window.test1 is "truthy" then this will be a no-op
    // otherwise, assign window.test1 to a function
    obj['test1'] = obj['test1'] || function(){

      // if window.test1.h doesn't have a value,
      // assign it to an empty array
      // Then, add the value of window.test1.h to the
      // implicit "arguments" variable that comes with each function
      (obj['test1'].h = obj['test1'].h||[]).push(arguments)

    }; // NOTE: I changed the comma here to a semi-colon

    // set window.test1.m to the unix epoch integer value (in ms)
    obj['test1'].m = 1 * new Date();

})(window);

Overall, I would say this code is cryptic and ugly. Assigning values within the same statements as a push to an array for example. Manually pushing to the arguments array is another.

I would not recommend using this code-snippit for learning JavaScript as it may teach you some anti-patterns.

Jonathan.Brink
  • 23,757
  • 20
  • 73
  • 115
  • Thanks a lot for nice description of the steps. Now atleast i understand what's going on. – Anil Reddy Feb 22 '16 at 20:05
  • @Aliz: Thanks for referencing the article i am going through it to understand the concepts behing self executing function. Was not able to search this as i was not aware of this usage – Anil Reddy Feb 22 '16 at 20:07
0

This pattern (function(x) {})(y); is known as an immediately invoked function expression (IIFE) and is generally used to create a scope.

As for the rest, this is horrible garbage. Analyzing it is not terribly difficult but its really unclear why anyone would ever do any of this.

Here's the blow-by-blow:

//create a scope with the function wrapper, pass in the global
//window object under the alias 'obj'
(function(obj) {
    //assign sting 'DummyObj' to the 'test' property of
    //the global object, effectively creating a global variable
    //and totally nullifying the reason for wrapping this in a
    //function
    obj['test'] = 'DummyObj';
    //same thing but with the 'test1' global property/variable
    //hese the logical or operator is used to conditionally
    //assign the property. problem is *none* of this works,
    //the following will throw:
    obj['test1'] = obj['test1'] || function(){
      //when called fn will attempt to conditionally assign
      //an array to the h property of the test1 variable, 
      //ie the function itself. this is a bad idea. then it
      //pushes the arguments on to that array. this is kinda
      //sorta an attempt at making a function that caches its
      //arguments, but it doesn't really work.
      (obj['test1'].h = obj['test1'].h||[]).push(arguments)
    },
    //1 * new Date() will yield a millisecond timestamp, but
    //+new Date() and Date.now() are both clearer. note that
    //this code is also assigning a random property to the
    //function object stored in test1
    obj['test1'].m = 1 * new Date();
})(window);
Jared Smith
  • 19,721
  • 5
  • 45
  • 83