【问题标题】:Understanding javascript functions, scope and closures了解 javascript 函数、范围和闭包
【发布时间】:2013-01-23 03:02:14
【问题描述】:

谁能详细解释一下这个js的sn-p是做什么的?

(function (window) {
    var test = window['test'] = {};
    test.utils = new(function(){ ... })();
})(window);

我了解该函数不是全局范围的。我知道它正在创建一个名为 test 的变量,该变量指向 window 对象中的一个属性,该属性是一个空对象。我也明白utils 是测试的属性。

我不明白最后一部分的目的是什么(window); 或者为什么utils 函数被指定为new

请解释一下。

【问题讨论】:

  • 让匿名(外部)函数中的代码“安全”不被window 篡改是一种有点误导的尝试。这是被误导的,因为它没有做到这一点:-) 代码应该通过this,而不是通过window
  • 我也不明白。您从哪里获得该代码,构造函数调用的函数表达式包含什么?
  • new(function(){ ... })(); 只是定义构造函数并一次性创建实例。与function Foo() {...}new Foo(); 相同。在这里使用对象字面量可能更容易,但我不知道,因为我不知道函数的内容是什么。

标签: javascript scope closures


【解决方案1】:

它创建一个函数并立即调用它,传入window。该函数接收一个名为window 的参数,然后在其上创建一个空对象,该对象既可用作window 上的属性,称为test,也可用作称为test 的局部变量。然后它通过new 调用一个函数来创建一个对象,并将该对象分配给test.utils

我不明白最后一部分的目的是什么(窗口);...

它在您引用的代码中实际上没有任何用途,因为传递给主(外部)函数的符号window 与接收它的参数的名称相同。如果他们的名字是不同的,那么这将是有目的的,例如:

(function(wnd) {
})(window);

这将使window 在函数中作为wnd 可用。

或者为什么 utils 函数被指定为新函数。

utils 不会是一个函数(至少,除非你用... 替换的代码正在做一些真的 奇怪的事情),它将是一个由 调用那个函数。

整个事情可以重写得更清楚:

(function(window) {

    var test;

    test = {};
    window['test'] = test;

    test.utils = new NiftyThing();

    function NiftyThing() {
    }

})(window);

window 仍然无缘无故地做这件事,但希望它可以清楚地说明 new(function() { ... })(); 位在做什么。

【讨论】:

  • 如果你使用 window 变量,它可能有助于缩小。这是我听说的唯一原因,但我认为这些事情应该由缩小器来完成 :-)
  • 那么test.utils = new(function(){ ... })();test.utils = function(){ ... }; 之间有什么区别?
  • @bflemi3:首先,test.utils 将引用一个几乎可以肯定不是函数的对象。在第二个中,test.utils 将引用一个函数。
【解决方案2】:

首先,这是一个自调用函数。

它本身被调用,将window 对象作为函数输入参数,以确保在整个函数内部,window 将具有预期的含义。

test.utils = new(function(){ ... })(); <--- This is an object constructor. 

当使用new 运算符调用该函数时,它会变成一个对象构造函数。

例如:

var conztructor = function() {
   this.name = "Matias";
};

var obj = new conztructor();
alert(obj.name); // <--- This will alert "Matias"!

(window); 的目的是创建一个新变量和引用来保存 JavaScript Window 对象实例,避免其他库可能重用 window(或任何其他)标识符并且您自己的库可能因此而中断情况。

这样做很好,可以避免更改其他库可能使用的全局范围标识符。

更新

响应一些cmets,运行这段代码:

http://jsfiddle.net/wChh6/5/

【讨论】:

  • 为什么你认为window 变量避免了全局对象的修改?
  • ^^^^^--- 它作为参考传递,修改也将适用于全局对象,这就是为什么我不明白这个jsbin.com/emaqog/1/edit背后的目的
  • @Bergi 好吧,也许我解释错了。我的意思是您避免覆盖标识符并更改设计的窗口或任何内容。
  • @Glutamat 检查我的更新,现在我解释得比以前更好:)
  • jsfiddle.net/wChh6/3 -> 这不会改变任何东西,你不能将window 设置为null。而且我真的没有看到任何目的,将对window对象的复制引用设置为null,或者
【解决方案3】:

这里发生的是声明了一个新的匿名函数。 (window) 的最后一部分调用该函数,将 window 作为参数传递。

在内部,对test.utils = new(function(){ ... })(); 的调用会创建一个新对象(其内容由传递给new 的函数定义)并将其分配给test.utils

【讨论】:

    【解决方案4】:

    当您使用最后一个括号定义函数时,该函数在使用给定参数加载后自行执行,在您的情况下为window

    (function (window) {
        var test = window['test'] = {};
        test.utils = new(function(){ ... })();
    })(window);
    

    JS function definition : meaning of the last parentheses

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-20
      • 2016-07-28
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 2012-01-24
      • 2018-02-04
      相关资源
      最近更新 更多