Javascript与冒号返回
我正在学习JavaScript,并且遇到了下面的结构:
var Test = (function () { function func1() { //do something..... } function func2() { //do something..... } function func3() { //do something..... } return { func1: func1, func2: func2, func3: func3 }; })();
我想知道回传块在做什么。 这是一个非常常用的JavaScript结构? 请让我知道在哪里可以得到更多的信息。
这是揭示模块模式 。
返回的对象包含对IIFE中定义的函数的引用。 所以里面定义的函数对于匿名函数是私有的。
但是如果你想使用外部的内部函数,你可以使用返回的对象。
Test
的价值将是
var Test = { func1: func1, func2: func2, func3: func3 };
你可以从外面调用func1
Test.func1();
这是Javascript 模拟 类的方式。 由于没有使用Module模式的可见性说明符 ,因此variables/方法可以是public / private。
揭示模块模式受到Module模式的启发。 在显示模块模式时,只有对私有variables/方法的引用才返回到一个对象中 。
模式背后的主要思想是避免邪恶的全局variables 。 这看起来类似于IIFE,除了返回一个对象而不是函数。 IIFE中定义的variables/方法对函数是私有的。 要访问IIFE内部的任何variables/方法,需要将其添加到返回的对象中,然后才能从IIFE外部访问。 这个模式利用了闭包 ,所以即使在对象返回之后,IIFE中定义的variables/方法也是可访问的。
来自Addy Osmani的书“ 学习Javascriptdevise模式”
Heilmann感到沮丧的是,当我们想从另一个公共方法调用公共方法或访问公共variables时,他不得不重复主要对象的名称。 他也不喜欢模块模式的需求,因为他希望公开的东西不得不转换为对象文字符号。
他的努力的结果是一个更新的模式,我们将简单地定义私人范围内的所有函数和variables,并返回一个匿名对象,指向我们希望公开的私有function的指针。
优点:
- 封装。 IIFE内部的代码是从外部封装的
- 清洁,组织和可重用的代码
- 隐私。 它允许创build私有variables/方法。 私有variables/方法不能从IIFE之外触及。
缺点:
- 如果一个私有函数引用一个公共函数,则该公共函数不能被覆盖
进一步阅读:
- https://en.wikipedia.org/wiki/Module_pattern
- https://carldanley.com/js-revealing-module-pattern/
- 如何在JavaScript中使用Revealing模块模式
编辑
来自@Mike的 评论
需要注意的是,创build一个对象(例如,
var me = {};
)是很常见的,然后在其上声明可能的公共成员(me.func1 = function() { /* ... */ };
) ,最后返回这个对象(return me;
)。 这避免了我们在OP代码的返回语句中看到的重复(所有的公共内容都被重复)。
这是return语句中的一个字面值对象。 这就像创build一个对象,然后返回它:
var obj = { func1: func1, func2: func2, func3: func3 }; return obj;
文字对象语法创build一个对象并设置其属性,如下所示:
var obj = new Object(); obj.func1 = func1; obj.func2 = func2; obj.func3 = func3; return obj;
返回对象的目的是为了向外面的代码揭示函数内部的函数,同时为函数可以使用的私有variables创build一个范围。
当不使用私有variables时,代码将执行相同的操作:
var Test = { func1: function() { //do something..... }, func2: function() { //do something..... }, func3: function() { //do something..... } };
私有variables在函数范围内声明,并且只能由其中的函数访问。 例:
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();
这就像其他编程语言中的类一样。 因此,可以使用Test.func1
访问公共func1
成员,并使用Test.func1()
将其称为正常函数。