简体   繁体   中英

JS difference between types of global variables

According to this:

(function(window) {
    window.MyClass1 = function(val) {
        this.val = val;
        console.log(this.val);
    };
}(window));

(function() {
    window.MyClass2 = function(val) {
        this.val = val;
        console.log(this.val);
    };
}());

(function() {
    this.MyClass3 = function(val) {
        this.val = val;
        console.log(this.val);
    };
}());

(function() {
    MyClass4 = function(val) {
        this.val = val;
        console.log(this.val);
    };
}());

new MyClass1('works1');
new MyClass2('works2');
new MyClass3('works3');
new MyClass4('works4');

on jsFiddle

What is the difference between MyClass1, MyClass2, MyClass3 and MyClass4? Aren't all of them attached to the window object in the exact same way? What's the best practice and why?

What is the difference between MyClass1, MyClass2, MyClass3 and MyClass4? Aren't all of them attached to the window object in the exact same way?

There's no meaningful difference between MyClass1 and MyClass2 .

MyClass3 will not work in strict mode because this inside the IIFE will be undefined , not equal to window .

MyClass4 will not work in strict mode because strict mode disallows implicit globals (variables assigned to without declaration) such as MyClass4 .

In non-strict mode, all four will work. In my opinion, implicit globals are simply evil (way too prone to accidents) so MyClass4 should be ruled out even in non-strict mode. And, if MyClass3 wants to assign to window , it seems it may as well just refer to window.MyClass3 (like MyClass2 does) rather than go through this which just makes the code less obvious and incompatible with strict mode.

What's the best practice and why?

The best practice would be an implementation that works in both strict and non-strict mode and is as simple as possible to achieve the goal. Since the IIFE is not adding any functionality that is being used, I don't see why it's needed in this circumstance. Simplicity is somewhat governed by opinion, but I'd say nothing more than this is needed:

function MyClass1(val) {
    this.val = val;
    console.log(this.val);
};

var x = new MyClass1("foo");
console.log(x.val);            // "foo"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM