首先:您提供的代码段不会返回 id,但会在传递 id 时返回一些东西。我必须承认,当涉及到私有作用域时,这个例子并不是最好的例子。我会给你一个更详细的,但我希望更清楚的例子:
(function ()
{
var personObjects = [];
var findById = function(id)
{
return personObjects[id];
}
var Person = function (name)
{
this.id = personObjects.length;//first available index ~= auto increment
this.name = name;
personObjects.push(this);
};
Person.find = function(id)
{
//I woudl do: id = +id;, but sticking to your example
if (typeof id === 'number')
{
return findById(id);
}
return undefined;
}
window.Person = Person;//expose to global object
})();
那么,我们这里有什么。您说您了解范围,所以我假设您知道此处声明的所有变量在包装函数返回后都将继续存在,但它们仅对在同一范围中声明的函数可见。如果不是:personObjects
数组和findById
函数对象仍然存在,但只能由Person
构造函数访问,构造函数暴露(因为也分配了)全局对象。
每当实例化一个人对象时,我都会使用数组的长度来确定下一个可用的 ID,从而为每个对象创建一个唯一的 ID。当您将有效的 id(数组键)传递给它时,函数 findById 只会返回对其中一个对象的引用。该Person.find
方法调用这个封闭的函数,但在这样做之前会对参数进行一些检查。在某些非常特殊的情况下,这对于调试或在长原型链中使用通用 setter 和 getter 可能很有用。这就是为什么,至少对我来说,这个例子作为一个起点有点牵强。
无论如何,您可以findById
像这样调用这个私有方法 ( ):
var tim = new Person('tim');
Person.find(0);// returns a reference to tim
//or even
var tom = new Person('Tom');
tim.find(1);//returns tom
tom.find(0);//returns tim
tim.find(tom.id);//...
同样,这种方法在 AFAIK 中不太常见,要练习/习惯范围和闭包,我建议使用一些魔术和事件委托(例如:尝试为移动设备上setInterval
的事件创建自己的委托者)。tab
只需谷歌它们,您很快就会明白为什么这是一个很好的练习,但一开始有点令人生畏。