0

I create a JS object in my code (The module pattern):

var Validator = {
    regexEmail: /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/,

    settings: {
        error_class: "error-field",
        formValid: true
    },

    init: function (form, default_error_class) {
        self = this;
        alert(self == window);
    },
};

When running the "init" function on chrome, I get false for self == window (expected). But when I try it on IE9 I get true(!). Can you tell me why? I would expect 'this' to capture my custom Validator object and not the window

benams
  • 4,308
  • 9
  • 32
  • 74
  • 2
    that depends on how you call it. Perhaps you pass the function as an event handler? – John Dvorak Mar 24 '13 at 09:12
  • Just a more detailed explanation: `self = this` assigns `this` to the global variable `self`. Your code would "work" if `self` wasn't a special global variable. `window.self` refers back to `window` and it appears that in some browsers, this property/global variable was made read-only. – Felix Kling Mar 24 '13 at 10:50

4 Answers4

2

Fix your scope when defining 'self'. Also, use explicit not implicit comparators, i.e. === not ==.

var Validator = {
    regexEmail: /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/,

    settings: {
        error_class: "error-field",
        formValid: true
    },

    init: function (form, default_error_class) {
        var self = this;
        alert(self === window);
    },
};

Validator.init();
Geuis
  • 41,122
  • 56
  • 157
  • 219
1

You could use an immediately executed anonymous constructor function

var Validator = new function(){
    this.regexEmail = 
        /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
    this.settings = {
        error_class: "error-field",
        formValid: true
    };
    this.init = function (form, default_error_class) {
        console.log(this === window);
    };
    return this;
}();
Validator.init(); //=> false
KooiInc
  • 119,216
  • 31
  • 141
  • 177
0

use alert(self === window); instead of the equality operator. Also you can check the accepted answer here for more details about the 2 operators: Which equals operator (== vs ===) should be used in JavaScript comparisons?

One more thing: as Genius said, fix your scope:

var self=this; 
Community
  • 1
  • 1
DVM
  • 1,229
  • 3
  • 16
  • 22
0

I'd argue that IE is actually correct in this case.

Because you didn't use var when defining self it is an implicit global. When you try to set this global self it fails, because the global object, which in the browser is window already has a window.self property, which is a reference to the window.

HTML Living Standard says:

The window, frames, and self IDL attributes must all return the Window object's browsing context's WindowProxy object.

Which would imply that window.self should be immutable.

So, window.self == window and it alerts true.

However because of historical hacks to remain compatible with some old sites, there is a bug/feature in WebKit and Gecko that allows you to overwrite it even though you really shouldn't be able to. It seems (at least in Gecko) to have to do with split objects.

Community
  • 1
  • 1
Useless Code
  • 12,123
  • 5
  • 35
  • 40