Search code examples
javascriptgoogle-chromethisundefinedself

Chrome browser ignores var self = this;


I'm writing some jQuery javascript code and was debugging an issue in Google Chrome (latest stable 24 on Mac OS X 10.7 Lion) when I found that

MyWidget = Widget.extend({
        _item_id : undefined,
        container : undefined,
        initialize : function(config) {
            var self = this;
            self.container = $(config.container_id);
            self._item_id = config.item_id;
            if (typeof(config.changeElement) !== 'undefined') {
                self._changeElement = config.changeElement;
                $(self._changeElement).unbind('change', OtherWidget.has_setting_changed);

                $(self._changeElement).change(function (event) {
                         self.changeSetting($(event.target).val()); // had 'this' here before
                });

                self._load();
            }
        },
        _load : function() {
            var self = this;  // <-- here is what fails
            self.changeState('Loading');
            if (typeof(self._item_id) === 'undefined' || this._item_id === '') {
                self.changeState('Create');
            } else {
                self._loadItem();
            }
        },

        changeSetting : function(item_id) {
                this._item_id = item_id;
                this._load();
                this._reloadOtherWidget();
        },
...
});

showed in the debugger: "self: undefined". The assignment was inside a member function, if that makes any difference. I ended up just using 'this' directly, since it was simple code. I know I'm clobbering ('shadowing') some kind of built-in reference to the window, but I thought it would work... Am I dealing with a known issue?

I saw this related post which seemed to indicate it would work: that, self or me — which one to prefer in JavaScript?


Solution

  • At the point where you put

             var self = this;  // <-- here is what fails
    

    it's already too late : you're in the function you call.

    You could do this :

    MyWidget = Widget.extend((function(){
           var self = {
               _item_id : undefined,
              container : undefined
            };
            self.initialize = function(config) {
                self.container = $(config.container_id);
                self._item_id = config.item_id;
                if (typeof(config.changeElement) !== 'undefined') {
                    self._changeElement = config.changeElement;
    
                    self._load();
                }
            };
            self._load = function() {
                self.changeState('Loading');
                if (typeof(self._item_id) === 'undefined' || this._item_id === '') {
                    self.changeState('Create');
                } else {
                    self._loadItem();
                }
            };
           return self;
    })());