枚举类型的范围

Scope in enumerated type

我正在查看 O'Reilly 出版的 "Javascript: the definitive guide" 一书中的示例。这里报一个枚举函数:

function enumeration(namesToValues) {
     // This is the dummy constructor function that will be the return value.
     var enumeration = function() { throw "Can't Instantiate Enumerations"; };

     // Enumerated values inherit from this object.
    var proto = enumeration.prototype = {
    constructor: enumeration, // Identify type
    toString: function() { return this.name; }, // Return name
    valueOf: function() { return this.value; }, // Return value
    toJSON: function() { return this.name; } // For serialization
    };

    enumeration.values = []; // An array of the enumerated value objects

    // Now create the instances of this new type.
    for(name in namesToValues) { // For each value
    var e = inherit(proto); // Create an object to represent it
    e.name = name; // Give it a name
    e.value = namesToValues[name]; // And a value
    enumeration[name] = e; // Make it a property of constructor
    enumeration.values.push(e); // And store in the values array
    }

    // A class method for iterating the instances of the class
    enumeration.foreach = function(f,c) {
    for(var i = 0; i < this.values.length; i++) f.call(c,this.values[i]);
    };

    // Return the constructor that identifies the new type
    return enumeration;
}

至少可以说我很困惑。

这里我们在第一行报告了一个enumeration函数,在它里面有一个同名的构造函数。我假设我们指的不是同一个函数(来自全局环境的调用将调用第一行 enumeration 而不是构造函数,对吗?)。

我们分配给proto enumeration.prototype。我们现在指的是什么?我们是将 enumeration.prototype 属性 添加到第一行的 enumeration 函数还是第三行的构造函数?

然后我们将 enumeration 构造函数分配给 constructor 属性。为什么它引用第三行的构造函数而不是第一行enumeration?是不是因为构造函数在内部作用域?

然后我们声明enumeration.values。我们是否再次向第一行的函数添加 属性?

最后,函数return是什么?本身?一个对象?

我对 javascript 没有经验,所以我可能遗漏了明显的细节。

据我所知,主要有一点让您感到困惑:enumeration的两种用法。

为了方便解释,我将第一行的enumeration称为outerEnumeration,第三行的innerEnumeration.

我假设我们指的不是同一个函数

对,确实是两个不同的函数

在全局范围内,是的,enumeration 将引用第一行声明的函数(又名 outerEnumeration)。如果没有 var enumeration 声明,outerEnumeration 中的 enumeration 也会引用它自己。

但由于 var enumeration 是在函数范围内声明的,所以它具有优先权。因此有一个 innerEnumeration 由变量 enumeration:

引用
var enumeration = function() { throw "Can't Instantiate Enumerations"; };

您可能希望 take a closer look at JavaScript scope 更好地理解手头的问题。

我们分配给 proto enumeration.prototype。我们现在指的是什么?

innerEnumeration

var enumeration 声明在 outerEnumeration 的整个函数体中都有效,因为它不会在任何地方被覆盖。

然后我们将枚举构造函数赋值给构造函数属性。为什么它引用第三行的构造函数而不是第一行枚举?

同上原因

然后我们声明enumeration.values。我们是否再次向第一行的函数添加 属性?

同样,innerEnumeration函数对象

最后,函数return是什么?本身?一个对象?

innerEnumeration

它 return 是具有所有属性(.prototype.values 等)的 innerEnumeration 函数。然后,可以创建 innerEnumeration 的实例。例如通过:

new enumeration(namesToValues);

Object.create(enumeration.prototype).constructor(namesToValues);

(这里的enumeration指的是outerEnumeration)。

我希望这可以帮助您更好地理解此函数的内部工作原理。您还有其他问题吗?