Почему for (var я in Math) не перебирает Math. * В Javascript?

По какой-либо причине (var я in Math) {console.log(i)} не отображает ожидаемый tan, cos, atan2, E, PI в Javascript.

Ответ 1

Потому что Math - это встроенный объект, свойства которого помечены неперечислимыми. Это связано с тем, что многие построенные объекты имеют такое поведение, поэтому цикл по массиву с for..in не даст вам проблем до тех пор, пока Array.prototype не будет расширен с помощью пользовательских функций, которые по умолчанию всегда перечисляются.

До недавнего времени неперечислимый был внутренним свойством, недоступным обычным кодом Javascript. Тем не менее, в EMCAScript 5 указывается возможность установить перечислимость и возможность записи (попробуйте изменить значение Math.PI) любого свойства объекта через Object.defineProperty().

Он также предоставляет Object.getOwnPropertyNames() как способ получить список всех свойств объекта независимо от их перечислимости.

Object.getOwnPropertyNames(Math);

//returns
["LN10", "PI", "E", "LOG10E", "SQRT2", "LOG2E", "SQRT1_2", "LN2", "cos", "pow", "log", "tan", "sqrt", "ceil", "asin", "abs", "max", "exp", "atan2", "random", "round", "floor", "acos", "atan", "min", "sin"]

Насколько я знаю, единственными браузерами, которые в настоящее время поддерживают эти функции, являются Chrome и Safari. Firefox должен поддерживать его в версии 4. IE9 Я не уверен, но Microsoft заявила, что они намерены в конечном итоге поддерживать стандарт EMCAScript 5.

Я не верю, что есть какой-либо способ подражать этой функции в интерпретаторах Javascript без явной поддержки.

Ответ 2

Как и большинство встроенных объектов в JavaScript, свойства и методы объекта Math определены в спецификации ECMAScript (раздел 15.8.1) как неперечислимые через (недоступные для script) DontEnum атрибут. В ECMAScript 5 вы можете пометить свойства и методы ваших собственных объектов как неперечислимые:

var o = {};

Object.defineProperty(o, "p", {
    enumerable: false,
    value: 1
});

Object.defineProperty(o, "q", {
    enumerable: true,
    value: 2
});

for (var i in o) {
    console.log(i + "=>" + o[i]);
}
// q=>2