javascript - 枚举类型的范围

标签 javascript constructor scope this

我正在查看 O'Reilly 出版的《Javascript:权威指南》一书中的一个示例。这里报一个枚举函数:

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.prototype分配给proto。我们现在指的是什么?我们是将 enumeration.prototype 属性添加到第一行的 enumeration 函数中还是添加到第三行的构造函数中?

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

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

最后,函数返回什么?本身?一个物体?

我对 javascript 没有经验,所以我可能会错过明显的细节。

最佳答案

据我所知,有一个要点让您感到困惑:枚举的两种用途。

为了更容易解释,我将在第一行调用outerEnumeration上的enumeration,并在第三行调用innerEnumeration

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

是的,它们确实是两个不同的函数

在全局范围内,是的,枚举将引用第一行声明的函数(也称为outerEnumeration)。如果没有 var enumeration 声明,outerEnumeration 内的 enumeration 也会引用自身。

但是由于 var 枚举 是在函数作用域内声明的,因此它具有优先权。因此,存在一个由变量 enumeration 引用的 innerEnumeration:

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

您可能想要take a closer look at JavaScript scope更好地理解当前的问题。

我们分配给 enumeration.prototype 原型(prototype)。我们现在指的是什么?

innerEnumeration

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

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

原因同上

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

同样,innerEnumeration函数对象

最后,函数返回什么?本身?一个对象?

innerEnumeration

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

new enumeration(namesToValues);

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

(这里enumeration指的是outerEnumeration)。

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

关于javascript - 枚举类型的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33148444/

相关文章:

javascript - Firebase实时数据交互

java - 具有许多必需参数的构造函数

c++ - 在类中调用另一个构造函数作为全局

javascript - 只有最后一次循环迭代才能成功注册我的点击事件?

java - 如何检查字符串是否为回文?

javascript - 当计数器达到特定数字时如何触发 JavaScript?

javascript - 通过向新添加的元素添加事件监听器来删除它们

javascript - Packery 附加方法添加三个项目。如何添加一项?

c++ - 当异步回调调用虚函数时会发生什么,而基类构造函数尚未返回?

ruby - 为什么尚未定义的局部作用域变量会引用同名实例变量?