如何调用这个javascript函数,它使用的是什么模式?

时间:2013-06-09 04:38:18

标签: javascript closures

我在示例代码中遇到了这种类型的函数,它看起来被广泛使用。但我无法弄清楚如何调用它,或者实际上,它代表什么模式。

 l = function (a1){
  someVar = {
    someFn: function(a2){
       console.log(a1);
       console.log(a2);
    }
  }
}

我如何执行someFn?这是否与闭包有关?

更新:

这是代码的使用方式。正如@ joseph-the-dreamer猜测的那样,它被用作模块的一部分,其中:

  App.module("Module", function(a1) {
      someVar = {
        someFn: function(a2){
           console.log(a1);
           console.log(a2);
        }
      }
  })

3 个答案:

答案 0 :(得分:7)

从目前的状态来看,您需要先致电l,设置someVar才能访问someFn。否则,您根本无法访问someFn

但如果没有someVar的任何变量声明,调用l将创建一个隐含的全局 someVar。隐含全局变量不是一个好习惯。您应该在某处声明someVar,即使您认为它是全球性的。

var someVar;

l = function (a1){
  someVar = {
    someFn: function(a2){
       console.log(a1);
       console.log(a2);
    }
  }
}

l(1);
someVar.someFn(2);

//1
//2

您还可以return someVar from calling l访问someVar。请注意,这次someVarl中的局部变量。

var l = function (a1){
  var someVar = {
    someFn: function(a2){
      console.log(a1);
      console.log(a2);
    }
  }
  return someVar;
}

l(1).someFn(2);

至于模式,我认为你所拥有的是module pattern的不完整形式。通常,模块模式将事物包装在IIFE中,并返回一个对象作为模块的接口。

答案 1 :(得分:1)

如果someVar不是l()范围之外的变量,那么无法调用someFn(),因为someFn()是私有的someVar的成员函数。

否则,如果您有权访问someVar,则可以像someFn()一样致电someVar.someFn()注意,在这种情况下,console.log(a1)的行为会很奇怪,因为a1仅在上次调用l()后才被分配。

答案 2 :(得分:0)

在JavaScript中,有两种类型的变量:全局本地

//local
var foo = "foo";

//global
bar = "bar";

从我在示例中看到的内容,l是一个用于存储匿名函数的全局变量。在这个函数中有一个名为someVar的全局变量,它存储一个对象,该对象具有一个名为someFn的局部变量,用于存储匿名函数。

要执行someFn,您必须执行以下操作:

l("Foo");               //This does not output anything
someVar.someFn("Bar");  //This will output "Foo" and then "Bar"

当您致电l("Foo");时,您正在创建全局变量someVar。这反过来意味着您可以在someVar中存储的匿名函数范围之外的任何位置使用l。您正在为参数a1使用闭包。

全局变量可以在任何地方使用,我谦卑地建议限制其使用,因为它会污染全局范围,这意味着它非常容易出错。

不使用全局变量的方法会更好。这里的小例子:

"use strict";

var l = function(a1) { //constructor
  var _a1 = a1; //private variable
  this.someFn = function(a2) { //public method
     console.log(_a1);
     console.log(a2);
  };
};

var object1 = new l("Foo");
var object2 = new l("Foo");
object1.someFn(1); //outputs "Foo" and then 1
object2.someFn(2); //outputs "Foo" and then 2