Javascript模块模式和函数调用

Javascript模块模式和函数调用,javascript,Javascript,您好,我已经开始学习一些javascript,我无法在“正常”函数中对此进行思考。我不明白为什么下面两个函数输出不同的结果。f2输出5,而f1输出1。为什么呢 var f1 = function(){ var x= 1; var add = function(){ x=5; }; var result = function(){ console.log(x); }; return { add: add, result: result

您好,我已经开始学习一些javascript,我无法在“正常”函数中对此进行思考。我不明白为什么下面两个函数输出不同的结果。f2输出5,而f1输出1。为什么呢

var f1 = function(){
  var x= 1;

  var add = function(){
    x=5;
  };

  var result = function(){
    console.log(x);
  };

  return {
    add: add,
    result: result
  };
};

f1().add();
f1().result();

var f2= (function(){
  var x= 1;

  var add = function(){
    x=5;
  };

  var result = function(){
    console.log(x);
  };

  return {
    add: add,
    result: result
  };
})();

f2.add();
f2.result();

第一个示例显示了对
f1()
的两次调用

  • 第一次调用
    f1()
    创建一个新的变量作用域,将
    x
    设置为
    1
    ,并返回包含方法的对象。
    .add()
    然后将
    x
    设置为
    5

  • 第二次调用
    f1()
    创建另一个新的变量作用域,将
    x
    再次设置为
    1
    ,并返回包含方法的对象。
    .result()
    然后返回仍然是
    1
    x


第二个示例只调用一次
f2()
,因此
x
没有新的变量范围,也没有创建新的方法


因此基本上,
f1
的两个调用在每次调用中初始化
x
,并返回两个不同的对象,其方法在两个不同的
x
变量上更接近


f2
被调用一次,因此一个对象与返回的方法共享一个
x
变量。因此,
.add()
调用和
.result()
调用使用相同的
x
变量。

让我概括一下代码中发生了什么:

// Declares a function named f1.
var f1 = function () {
  // Searches each scope (the scope of f1, the scope containing f1, etc.) for
  // a variable named x. If found, it will reassign it to 1. If the search reaches
  // the global scope and no variable is found it will declare and initialize
  // a global variable.
  x = 1;

  // Declares a local variable named add to a function that reassigns the value of x.
  var add = function () {
    x = 5;
  };

  // Declares a local variable named result to a function that logs the value of x.
  var result = function () {
    console.log(x);
  };

  // Returns an object containing each function.
  return {
    add: add,
    result: result
  };
};

// Calls f1 and the returned add function.
f1().add();

// Calls f1 again (which reassigns x) and calls the returned result function.
f1().result();


// Creates a variable named f2 and assigns to the result of applying an anonymous
// function. f2 now references the returned object.
var f2 = (function () {
  // Reassigns x, does not create a new variable.
  x = 1;

  var add = function () {
    x = 5;
  };

  var result = function () {
    console.log(x);
  };

  return {
    add: add,
    result: result
  };
})();

// The difference now is that the function that contains add and result is only
// called once, during the initialization of f2. Had you written var g = f1();
// g.add(); g.result(); you would have gotten the exact same results.
f2.add();
f2.result();

您使用的是相同的
x
全局变量,因为您没有用
var
声明它,这是您的意图吗?对不起,我忘了。我添加了var,但f1仍然输出1。这里没有这个。:-)几乎。第一个并不需要两次调用。如果他执行f1并将结果保存在变量中,然后执行方法,则bot f1和f2将返回相同的结果result@Kenneth:是的,我所说的“requires”是指该示例显示了两个单独的调用。也许这不是最好的词。好吧,我要把结果保存在变量中的什么地方?+1,每次调用
f1
都会创建一个新的执行上下文,每次都有一个新的x,而
f2
只调用一次,相同的执行上下文位于add和result的作用域链上,因此它们共享相同的x。@user1870482:不确定您的意思。但如果希望对象方法共享同一变量,则需要保存该对象。通过立即调用函数并将对象保存到
f2
,您可以做到这一点。感谢您的详细解释。返回的对象只包含对函数的引用,对吗?@user1870482是的,当您调用f1时,返回了两个完全不同的引用(或对象),并在其中一个上调用add,然后在另一个上调用result。调用f2时,使用相同的引用调用add和result on。