Javascript 函数作用域差异

Javascript function scope difference

这有什么区别:

(function() {
    function func1(){
        console.log(1);
    };
    func1.prototype.func2 = function(){
        console.log(2);
    };
    window.func1 = new func1();
})();

还有这个:

function func1(){
    console.log(1);
};
func1.prototype.func2 = function(){
    console.log(2);
};

我知道第一个示例只会创建内部函数 func1 的副本并将其放在 window 范围内,但第二个示例已经在 window 范围内。使用第一个示例有什么性能或优势吗?

第一种情况可以在一定程度上进行封装。 new func1() 无法从 window 范围创建更多 func1 个对象。 (但正如 RobG 在评论中所说,可以使用 newFunc1 = new window.func1.constructor() 创建新对象)...

有时多个JS脚本可能有同名的函数导致冲突。这是一种解决方案,因为 func1 在此处的匿名函数范围内。

它也可以充当单例设计模式(不完全是模式)。

假设您要创建一个游戏,而该游戏需要一个单一但复杂的 gameEngine 对象。可以从任何地方访问游戏引擎,但只需要一个实例。在那种情况下,您可以使用第一种情况来封装游戏引擎的复杂性,只创建一个全局对象并避免与其他外部函数发生函数冲突....


第二种情况是正常的程序。在第二种情况下,func1 函数(构造函数)是可见的,并且可以使用 new func1().

从 window 范围创建任何对象

第一名:

  • 您可以调用这些类型的表达式立即调用的函数表达式。
  • 这种方法的基本用途是创建一个函数,然后立即执行它。
  • 并且在此方法中声明的任何变量在全局上下文中都将不可见。

    例如:

    // An immediately-invoked function expression.
    
    (function() {
        var foo = "Hello world";
    })();
    
    console.log( foo ); // undefined!
    
  • 如果需要,您可以提供访问器。

  • 这种方法可以在许多场景中使用,如前面的答案所述,并且 jQuery 将其用作一种基本的启动技术,使 jQuery 中只有一个对象在上下文中可见。
    参见:Wiki or Learn jQuery

第 2:

  • 这是为 Prototype (something like Object Oriented) JavaScript 创建原型的基本方法。

例如:

// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  console.info('Shape moved.');
}; 

这将创建 Shape 的原型,然后将 move 方法添加到该原型。
参见 Mozilla Site for Detail