JavaScript冒号与return

55

我正在学习 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中很常用的结构吗?请告诉我在哪里可以获得更多关于此的信息。

3个回答

72
这是“揭示模块模式”。
返回的对象包含对IIFE内定义的函数的引用。因此,在匿名函数内部定义的函数是“私有”的。
但是,如果您想在外部使用内部函数,可以使用返回的对象。
“Test”的值将是什么。
var Test = {
    func1: func1,
    func2: func2,
    func3: func3
};

你可以从外部调用func1,如下:

Test.func1();

这是Javascript模拟类的方式。由于没有使用模块模式中的可见性规范,变量/方法可以被设为公共或私有。请注意保留HTML标签。

enter image description here

揭示模块模式受到模块模式的启发。在揭示模块模式中,只有对 私有 变量/方法的引用被返回到一个 对象 中。

该模式的主要思想是避免 邪恶的全局变量。这看起来与 IIFE 相似,除了返回的是一个对象而不是函数。在 IIFE 内定义的变量/方法是函数的 私有 部分。要访问 IIFE 内部的任何变量/方法,需要将其添加到返回的对象中,然后可以从 IIFE 的外部访问它们。这种模式利用了 闭包,因此在返回对象之后,IIFE 内部定义的变量/方法仍然可以访问。

来自 Addy Osmani 的书 《学习 JavaScript 设计模式》

揭示模块模式的出现是由于Heilmann对于在调用一个公共方法或访问公共变量时需要重复主对象名称感到不满。他也不喜欢模块模式要求使用对象字面量表示法来公开所需内容的要求。他的努力结果是更新了一种模式,我们可以在私有作用域中定义所有函数和变量,并返回一个匿名对象,其中包含指向我们希望公开为公共的私有功能的指针。 优点:
  1. 封装性。IIFE内部的代码与外界隔离
  2. 清晰、有组织和可重用的代码
  3. 隐私性。它允许创建私有变量/方法。私有变量/方法无法从IIFE之外访问。
缺点:
  1. 如果私有函数引用公共函数,则无法覆盖该公共函数

进一步阅读:

  1. https://en.wikipedia.org/wiki/Module_pattern模块模式
  2. https://carldanley.com/js-revealing-module-pattern/揭示模块模式的JavaScript实现
  3. 如何在JavaScript中使用揭示模块模式

编辑

来自@Mike评论值得注意的是,通常会创建一个对象(例如var me = {};),然后在其上声明将要公开的成员(me.func1 = function() { /* ... */ };),最后返回该对象(return me;)。这避免了我们在OP代码的返回语句中看到的重复(其中所有公共内容都被重复)。


2
值得注意的是,通常会创建一个对象(例如 var me = {};),然后在其上声明将要公开的成员(me.func1 = function() { /* ... */ };),最后返回该对象(return me;)。这避免了我们在 OP 代码的返回语句中看到的重复(其中所有公共内容都被重复)。 - Kat

15

这是在返回语句中的一个字面对象。它就像创建一个对象,然后将其返回:

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;
返回对象的目的是将函数内部的功能展示给外部代码,同时为函数可以使用的私有变量创建一个作用域。
当不使用私有变量时,代码执行的与下面相同:
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();

1
当不必要时,为什么要使用new Object()或字符串表示法? - Seiyria
@Seiyria:要做与文字对象符号相同的事情,但没有文字对象符号。我只是将字符串符号更改为常规属性标识符而已。 :) - Guffa
1
我想我的观点是var object = {}var object = new Object()好得多。它更有意义并且性能更好 - Seiyria
1
@Seiyria:是的,它确实可以,但那是一个对象字面量,我想展示一下对象字面量的作用。 - Guffa

1
那就像其他编程语言中的类一样工作。因此,您可以使用 Test.func1 访问公共成员 func1 并像普通函数一样调用它,例如 Test.func1()

2
感谢那些提供反馈的人,不管怎样,我们都要热爱2016年的SE社区。 - Iulian Onofrei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接