JS全局变量的类型有哪些区别?

3
根据此:
(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');

jsFiddle

MyClass1、MyClass2、MyClass3 和 MyClass4 之间有什么区别?它们不都以完全相同的方式附加到 window 对象上吗? 最佳实践是什么,为什么?


2
MyClass3和MyClass4在严格模式下不可用。 - anqooqie
3
MyClass3会附加到被调用的functionthis引用中,但这不一定是全局对象(例如在requirejs模块内部)。因此,使用this可能会有些棘手。 - Nikos M.
2
"MyClass4" 可能会抛出错误,因为没有 "var" 声明和附加对象。 - Nikos M.
1
总之,以上4个例子仅在非常特定的情况下才是等效的,而不适用于其余情况。 - Nikos M.
感谢您。所以3和4是不好的;但1和2有什么区别吗?1只是“规范的方式”吗? - John Doe Smith
1
1和2之间没有实际区别。也许不同优化的脚本引擎可以比全局变量更快地查找本地变量。或者也可能不是这样。"最佳实践"是使用函数声明并删除无意义的IIFE。 - RobG
1个回答

1
“MyClass1”,“MyClass2”,“MyClass3”和“MyClass4”有什么区别?它们不是以完全相同的方式附加到窗口对象上吗? MyClass1MyClass2之间没有实质性的区别。 MyClass3在严格模式下无法工作,因为IIFE中的this将是undefined,而不是等于windowMyClass4在严格模式下无法工作,因为严格模式禁止隐式全局变量(未声明即被赋值的变量),例如MyClass4
在非严格模式下,所有四个都可以工作。我认为,隐式全局变量非常危险(太容易出现意外),因此即使在非严格模式下也应该排除MyClass4。如果MyClass3想要分配给window,那么它似乎可以直接引用window.MyClass3(像MyClass2一样),而不是通过this,这只会使代码更不明显,并与严格模式不兼容。

最佳实践是什么,为什么?

最佳实践应该是在严格模式和非严格模式下都能正常工作,并且尽可能简单地实现目标。由于IIFE没有添加任何被使用的功能,我不认为它在这种情况下是必要的。简洁性有些受意见影响,但我认为只需要这样做:

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接