我正在查看 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/