枚举类型的范围

时间:2015-10-15 12:20:59

标签: javascript constructor scope this

我正在看一本书中的例子" Javascript:权威指南"由O' Reilly出版。这里报告了一个枚举函数:

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。我们再一次在第一行的函数中添加一个属性吗?

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

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

1 个答案:

答案 0 :(得分:1)

据我所知,有一个主要问题让你困惑:enumeration的两种用途。

为了便于解释,我会在第一行enumeration和第三行outerEnumeration上调用innerEnumeration

我假设我们没有提到相同的功能

是的,它们确实是两种不同的功能

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

但由于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功能对象

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

innerEnumeration

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

new enumeration(namesToValues);

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

(此处enumeration指的是outerEnumeration)。

我希望这有助于您更好地理解此功能的内部工作原理。你还有其他问题吗?