根据这篇文章(https://www.intertech.com/Blog/encapsulation-in-javascript/),以下代码是JS中的封装示例。它的作用基本上是限制修改变量fullName的可能性,所以只有当新的fullName没有数字时才可以更改它。
var person = (function () {
var fullName = "Jason Shapiro";
var reg = new RegExp(/\d+/);
return {
setFullName : function (newValue) {
if( reg.test(newValue) ) {
alert("Invalid Name");
}
else {
fullName = newValue;
}
},
getFullName : function () {
return fullName;
}
}; // end of the return
}());
alert(person.getFullName()); // Jim White is printed again.
person.setFullName( 42 ); // Invalid Name; the name is not changed
这对我来说似乎都是逻辑,但我无法得到的是如果这些函数在返回块中,他怎么能调用getFullName或setFullName。
答案 0 :(得分:3)
因为正在使用名为自调用函数的对象初始化对象person
:
(function () {
// body of the function
}());
上面的匿名函数将在定义后立即调用。自调用函数的好处是它们使我们能够执行一次代码而不会混淆全局命名空间(不声明任何全局变量)。 Reference
因此,正好使用返回值初始化您当时的对象。
在您的情况下,使用:
{
setFullName: function(newValue) {
if (reg.test(newValue)) {
alert("Invalid Name");
} else {
fullName = newValue;
}
},
getFullName: function() {
return fullName;
}
};
因此,对象person
将使用这些功能进行初始化,因此您可以调用getFullName
和setFullName
。
答案 1 :(得分:3)
这个例子没有什么太令人惊讶的了;我们只需要打破它。
正在声明名为person
的变量。
什么样的对象是人?好吧,这是在零参数上调用匿名函数的结果。
当调用该匿名函数时,它返回一个对象。
该函数返回的对象有两个属性setFullName
和getFullName
。
函数返回的对象是变量person
的值。因此,person.getFullName
和person.setFullName
都是有效的表达式。
我认为混淆点可能是您认为getFullName
和setFullName
的范围仅限于return
表达式中的代码。但是,JavaScript是一种非常动态的语言。可以随时向对象添加属性和从对象中删除属性。它是在运行时,而不是编译时,JavaScript解释器检查是否存在属性。
答案 2 :(得分:1)
在person
变量中,我们有一个IIFE(立即调用的函数表达式),当解释器到达此行时立即执行。这个函数返回一个对象,所以最后,person
变量是一个对象,而且我们知道,对象也可以包含函数,我们可以像这样轻松地调用这个对象的函数:
person.getFullName();
person.setFullName(42);
答案 3 :(得分:1)
我认为你在代码中没有注意到的是它的形式:声明一个函数并立即运行。存储在person
中的值不是函数,而是包含两个函数的对象。
function () { ... }
是一个功能。
(function () { ... )())
是该函数的返回值。