2

I understand the word self has no special meaning in javascript. Below code, while if one writes as var Life = function( ....), it's clear but author decide to do var _ = self.Life = function(...). While I understand the var _ part(so that internally, it can refer to samething by shorter name), I don't get self.Life (instead of Life).. Can someone please explain this?

(function() {
    var _ = self.Life = function(seed) {
        this.seed = seed;
        this.height = seed.length;
        this.width = seed[0].length;
        this.prevBoard = [];
        this.board = cloneArray(seed);
    };
    _.prototype = {
        next: function() {
            //
        },
        toString: function() {
            return this.board.map(function(row) {
                return row.join(' ');
            }).join('\n');
        }
    };

    function cloneArray(array) {
        return array.slice().map(function(row) {
            return row.slice();
        });
    }
})();
undefined
var game = new Life([
    [0, 0, 0, 0],
    [0, 0, 1, 0],
    [0, 1, 0, 1]
]);
undefined
console.log(game + ' ');
Pointy
  • 371,531
  • 55
  • 528
  • 584
user3502374
  • 751
  • 4
  • 8
  • It probably says self = this somewhere – Jonas Wilms Sep 09 '17 at 13:08
  • 1
    Are you sure this is the entire code sample? `self.Life` refers to a variable `self` defined outside of this code. It is common - in ES5 and older code - to have the pattern `var self = this` in order to get past the fact that `function` creates a new context. – Dan Sep 09 '17 at 13:08
  • This is the code so far and when I run this in console, it works – user3502374 Sep 09 '17 at 13:09
  • 1
    Well... it shouldn't work, because you're doing `_.prototype` outside of the context where `_` is defined. I just ran it in Node 8 and it does not work. What is the engine you are using? – Dan Sep 09 '17 at 13:10
  • I just ran from chrome console – user3502374 Sep 09 '17 at 13:11
  • why is _.prototype outside of context where _ is defined? It's within the first self invoked function – user3502374 Sep 09 '17 at 13:12
  • 1
    I mis-read your code, my apologies! – Dan Sep 09 '17 at 13:13
  • Chrome defines a property named "self" on the `window` object to be a reference back to `window`. – Pointy Sep 09 '17 at 13:14
  • https://stackoverflow.com/questions/16875767/difference-between-this-and-self-in-javascript – Slai Sep 09 '17 at 13:22

2 Answers2

4

I understand the word self has no special meaning in javascript.

No, but it is a predefined global on browsers, referring to the current window (like window does*). So

var _ = self.Life = function...

...is making Life a global without falling prey to The Horror of Implicit Globals**.

Live brief example:

(function() {
  var _ = self.Life = function() {
    console.log("Hi there");
  };
  new _();
})();
new Life();

* window and self used to be slightly different references to the current window, but on modern browsers, window === self is true for the default values of window and self.

** (that's a post on my anemic little blog)

T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
  • Thank you for this answer. When I type Life by itself, I do see that self is window.(so no wonder it works this way) and just to test that theory, if I change this to self1, it does not work(as expected). – user3502374 Sep 09 '17 at 21:01
2

In this case, _ is a local variable inside the closure. But self refers to the current window in which this IIFE is getting created and executed. So, self.Life is going to make it a function attached to current window, like window.Life, so that it can be called from anywhere in the window by its direct name. You are hence able to use it out of closure as

var game = new Life([
    [0, 0, 0, 0],
    [0, 0, 1, 0],
    [0, 1, 0, 1]
]);

More clarification available in below link and in attached AListApart article

https://stackoverflow.com/a/962040/7974050

Amit Kumar Singh
  • 4,083
  • 2
  • 6
  • 22