"这" javascript模块中的关键字

时间:2013-08-27 08:25:38

标签: javascript

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

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.fn会记录Window而不是module

当我致电fn时,我仍然需要写module.fn,我无法写Window.fn。由于this引用Window,我觉得这很令人困惑。

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

3 个答案:

答案 0 :(得分:4)

  

由于这是指函数的所有者,为什么module.fn会记录Window而不是模块?

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

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

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

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

module.fn(); // "Object {fn: function}"

答案 1 :(得分: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

答案 2 :(得分: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]);

你需要从em原型中窃取 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();

请注意,这几乎等于“新”电话。

有更多同样有效的方法,但第一个提出的方法经常使用,非常清楚。无论如何,一切都取决于你的代码约定。