Javascript 调用私有作用域

Javascript 调用私有作用域,javascript,Javascript,我正在读一本略高于我水平的书。这本书的作者正在展示如何使用匿名函数创建私有作用域。我理解私有范围的概念,但是我不理解它是如何实现的。我确实知道这些局部变量只能在当前范围内访问(这是作者的话),但我不确定如何调用/实现它。你能给我一个例子,说明如何使用var Tim=newperson()在实际代码中使用它吗如下 使用匿名函数创建私有作用域: var Person = function(){}; (function(){ var findById = function(){ /* ... *

我正在读一本略高于我水平的书。这本书的作者正在展示如何使用匿名函数创建私有作用域。我理解私有范围的概念,但是我不理解它是如何实现的。我确实知道这些局部变量只能在当前范围内访问(这是作者的话),但我不确定如何调用/实现它。你能给我一个例子,说明如何使用
var Tim=newperson()在实际代码中使用它吗如下

使用匿名函数创建私有作用域:

var Person = function(){};

(function(){
  var findById = function(){ /* ... */ };
  Person.find = function(id){
    if (typeof id == "integer")
      return findById(id);
   };
})();
我的理解

var Tim = new Person(); 

我该叫什么?我能找到蒂姆的身份证吗

只能通过调用
Person.find来间接调用
findById

// Assuming code similar to your code above
// Assume that Tim.id === 1
var someone = Person.find(1); // Call findById to get a reference to Tim
console.log(someone.name); // Tim
findById(1) // Error, findById is not available in the global scope

首先:您提供的代码片段不会返回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
构造函数访问,该构造函数公开(因为也指定了)全局对象

每当实例化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
事件创建自己的委派器)。只要用谷歌搜索一下,你很快就会明白为什么这是一个很好的练习,但一开始有点让人畏缩

事实上,我尝试了一些类似于你的代码,但没有成功。我通过将“Person.find”改为“Person.prototype.find”来修复它。使用这样的匿名函数是拥有私有类成员的一种很好的方法,或者至少是提供私有类成员所提供的一切的方法。我很惊讶Crockford没有提到这件事。