0

我已经在全球范围内定义了以下模块:

var module = (function () {

  console.log(this);

  this.fn = function () {
    console.log(this);
  }

  return this;
})();

http://www.quirksmode.org/js/this.html

In JavaScript |this| always refers to the “owner” of the function we're executing, or rather, to the object that a function is a method of.

第一次调用console.log日志Window作为 的值this,我理解。但是,第二次调用console.log.

既然this指的是函数的所有者,为什么module.fnlogWindow而不是module呢?

当我打电话时fn我仍然要写module.fn,我不能写Window.fn。由于this指的是Window我觉得这很混乱。

编辑:我忘了this在我的例子中返回。

4

3 回答 3

4

既然 this 指的是函数的所有者,为什么 module.fn 记录窗口而不是模块?

外部函数的返回值是window因为它不会在任何特定的上下文中被调用,所以module最终window也是如此。

看来您应用模块模式的方式是错误的。它应该返回在其余代码中使用的公共接口:

var module = (function () {
  console.log(this);

  // public interface
  return {
    fn: function () {
      console.log(this);
    }
  }
})();

module.fn(); // "Object {fn: function}"
于 2013-08-27T08:37:33.973 回答
2

您的模式是错误的,您正在做一个封闭的范围并设置module为从该范围返回:

// This is the design pattern:

var module = (function () {
  var module = {};

  var localVar = 1;

  module.moduleVar = 2;

  module.fn = function () {
    console.log(this);
  }


  return module;
})();

console.log(module.fn); // function() { console.log(this) ;}
console.log(module.moduleVar); // 2
console.log(module.localVar); // undefined
于 2013-08-27T08:31:02.193 回答
2

在您的示例中,全局对象接收fn. 它是window浏览器的对象。那是因为您在没有特定上下文的情况下就地调用该函数(有效地构造了一个新范围)。最后,您的module对象只是对window(因为return this;)的引用。

是什么this

在 JavaScript 中,this是当前上下文,即在特定时间调用函数的对象。它不是函数的“持有者”。您始终可以从其他对象中“窃取”该方法,并将apply其(字面意思)转移到您自己的对象中。

arguments假设您出于某种原因想要对对象进行切片。它看起来就像一个数组,但它不是一个数组。arguments.slice(2,4)不起作用(假设 ECMAScript < 5)。该怎么办?

Array.prototype.slice.apply(arguments, [2,4]);

您需要从 Array 原型中窃取slice函数,并在您的参数上使用 if 。在slice调用内部,“this”是特定时间的参数对象。

如何构造一个有效的模块?

你的工作是return模块对象。你不想弄乱上下文。只要您不直接在模块对象上应用该功能,它就无关紧要。

最简单的解决方案是最简单的。

var module = (function() {
   // do something internally, great for "private" stuff

   // then return the "public" interface
   return {
       doSomething: function() {
          // do something
       },
       introduce: function() {
           console.log(this);
       }
   };
})();

module.introduce(); // Object {doSomething: function, introduce: function}
module.doSomething();

另一种方法。

或者,this如果您真的愿意,您可以使用应用程序来完成您的工作。

var module = {};
(function(){
   this.doSomething = function() {
      // do something
   };
   this.introduce = function() {
       console.log(this);
   };
}).apply(module);

module.introduce(); // Object {doSomething: function, introduce: function}
module.doSomething();

请注意,这几乎等于“新”调用。

有更多同样有效的方法可以做到这一点,但第一个提出的方法经常使用并且非常清晰。无论如何,一切都取决于您的代码约定。

于 2013-08-27T08:58:39.750 回答