Javascript return 带冒号

Javascript return with colon

我正在学习JavaScript并且遇到了下面的结构:

var Test = (function () {

  function func1() {
      //do something.....
  }

  function func2() {
      //do something.....
  }

  function func3() {
      //do something.....
  }

  return {
      func1: func1,
      func2: func2,
      func3: func3
  };

})();

我想知道 return 块在做什么。这是一个很常用的JavaScript结构吗?请让我知道在哪里可以获得更多相关信息。

这是揭示模块模式

返回的对象包含对 IIFE 中定义的函数的引用。所以里面定义的函数对匿名函数是private

但是如果你想在外面使用内部函数,你可以使用返回的对象。

Test 的值将是

var Test = {
    func1: func1,
    func2: func2,
    func3: func3
};

并且您可以从外部调用 func1 作为

Test.func1();

这就是Javascript模仿class的方式。由于没有 visibility specifiers 使用模块模式,variables/methods 可以设为 public/private.

揭示模块模式的灵感来自模块模式。在揭示模块模式中,仅在 object.

中返回对 private variables/methods 的引用

该模式背后的主要思想是避免邪恶的全局变量。这看起来类似于 IIFE,只是返回的是一个对象而不是函数。 IIFE 中定义的 variables/methods 是函数的 private。要访问 IIFE 内部的任何 variable/method,需要将其添加到返回的对象中,然后才能从 IIFE 外部访问它。这种模式利用了闭包,因此即使在返回对象后,IIFE 中定义的variables/methods 也可以访问。

来自 Addy Osmani 的书 Learning Javascript Design patterns

The Revealing Module pattern came about as Heilmann was frustrated with the fact that he had to repeat the name of the main object when we wanted to call one public method from another or access public variables. He also disliked the Module pattern’s requirement for having to switch to object literal notation for the things he wished to make public.

The result of his efforts was an updated pattern where we would simply define all of our functions and variables in the private scope and return an anonymous object with pointers to the private functionality we wished to reveal as public.

优点:

  1. 封装。 IIFE里面的代码是对外封装的
  2. 干净、有条理且可重用的代码
  3. 隐私。它允许创建私有 variables/methods。私有 variables/methods 无法从 IIFE 外部访问。

缺点:

  1. 如果一个私有函数引用了一个public函数,那个public函数不能被覆盖

进一步阅读:

  1. https://en.wikipedia.org/wiki/Module_pattern
  2. https://carldanley.com/js-revealing-module-pattern/
  3. How to use Revealing module pattern in JavaScript

编辑

来自 from @Mike

It's of note that it's common to create an object (eg, var me = {};) and then declare the would-be public members on it (me.func1 = function() { /* ... */ };), returning that object at the end (return me;). This avoids the repetition that we see in the return statement of OP's code (where all the public stuff is repeated).

这与其他编程语言中的 class 类似。因此,您可以使用 Test.func1 访问 public func1 成员,并使用 Test.func1().

像普通函数一样调用它

它是 return 语句中的文字对象。这就像创建一个对象然后 returning 它:

var obj = {
    func1: func1,
    func2: func2,
    func3: func3
};
return obj;

文字对象语法创建一个对象并设置其属性,就像:

var obj = new Object();
obj.func1 = func1;
obj.func2 = func2;
obj.func3 = func3;
return obj;

returning 对象的目的是向外部代码显示函数内部的函数,同时为函数可以使用的私有变量创建范围。

当不使用私有变量时,代码的作用与:

var Test = {
  func1: function() {
      //do something.....
  },
  func2: function() {
      //do something.....
  },
  func3: function() {
      //do something.....
  }
};

私有变量在函数作用域内声明,并且只能由其中的函数访问。示例:

var Test = (function () {

  var name;

  function setName(str) {
    name = str;
  }

  function getName() {
    return name;
  }

  return {
      setName: setName,
      getName: getName
  };

})();

Test.setName("John Doe");
var name = Test.getName();