Я прочитал JavaScript "Руководство по определению", вот список enumeration class
главы 9.6.2:
function inherit(p) {
if (p == null) throw TypeError(); // p must be a non-null object
if (Object.create) // If Object.create() is defined...
return Object.create(p); // then just use it.
var t = typeof p; // Otherwise do some more type checking
if (t !== "object" && t !== "function") throw TypeError();
function f() {}; // Define a dummy constructor function.
f.prototype = p; // Set its prototype property to p.
return new f(); // Use f() to create an "heir" of p.
}
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 (var 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;
}
var Coin = enumeration({ Penny: 1, Nickel: 5, Dime: 10, Quarter: 25 });
var c = Coin.Dime; // This is an instance of the new class
console.log(c); // => { [Number: 10] name: 'Dime', value: 10 }
// Construct other object with 'name' and 'value'.
var o = Object.create({});
o.name = 'Dime';
o.value = 10;
console.log(o); // => { name: 'sam', value: 10 }
Когда я запускаю его на node
, вывод кода
{ [Number: 10] name: 'Dime', value: 10 }
Но когда я Object.create({})
объект o
с Object.create({})
и .
синтаксис, такой как объект enumeration
. А затем распечатайте его. Выход:
{ name: 'Dime', value: 10 }
Почему в node
он печатает дополнительные [Number: 10]
? Но в консоли браузера это не будет.
Моя версия node
- v4.2.6
и linux
.
В узле console.log()
вызывает util.inspect
чтобы получить "удобное для пользователя" строковое представление объекта, что добавляет [Number: 10]
и, следовательно, отличие от выхода браузера.
Что касается того, почему узел испускает [Number: 10]
для перечисления против POJO, обратите внимание, что прототип перечисления определяет valueOf, который предназначен для предоставления примитивного значения для объекта.
Добавление valueOf
к прототипу POJO будет испускать [Number: 10]
:
pojoProto = {
valueOf : function() { return this.value; }
};
pojo = inherit(pojoProto);
pojo.name = 'Dime';
pojo.value = 10;
console.log(pojo); //{ [Number: 10] name: 'Dime', value: 10 }
Для справки, здесь реализация узла console.log
(обратите внимание на делегацию на util.format
которая использует inspect
):
Console.prototype.log = function log(...args) {
write(this._ignoreErrors,
this._stdout,
'${util.format.apply(null, args)}\n',
this._stdoutErrorHandler);
};
console.log(o)
, он также будет вызыватьutil.inspect
, но поля[ Number ]
. И я нашел ключевое свойство name этоvalue
. И есть ли ссылка?[Number]
и добавлен исх.