Ответ 1
Проблема существует с node v0.10.28 (последняя стабильная), установленная вместе с V8 v3.14.5.9 (и более ранними версиями), но проблема не в самой node, а в V8, у которой есть ошибка.
Отчет об ошибке можно найти в проблеме 2273, опубликованной 5 августа 2012 года.
Функция строгого режима должна получать не принудительное значение 'this'. То есть 'this' может быть undefined/null вместо глобального объекта и примитивными значениями вместо значений в коробке.
Не имеет значения, находится ли функция вызывающего абонента в строгом режиме или нет. Однако встроенные функции, такие как "Array.prototype.forEach", неправильно выполняют принуждение, даже если вызываемая функция находится в строгом режиме.
Тестовый пример:
(function() {
var logger = function() {
"use strict";
console.log(this);
};
var strictCaller = function() {
"use strict";
logger.call("foo");
};
var nonStrictCaller = function() {
logger.call("foo");
};
var forEachCaller = function() {
[123].forEach(logger, "foo");
};
// call from strict function: logs primitive value
strictCaller();
// call from non-strict function: logs primitive value
nonStrictCaller();
// call through forEach: logs *boxed* value (WRONG)
forEachCaller();
})();
Исправлена ошибка с исходным кодом V8 в версия r14149 от 5 апреля 2013 г.
Таким образом, проблема была длительной и затрагивала все среды, которые были основаны на двигателе V8.
Я смог подтвердить, что Chrome v27 по-прежнему был затронут этой проблемой, и он запускал V8 v 3.16 и может подтвердить, что Chrome v34 с V8 v3.24.35.33 больше не затрагивается. Итак, где-то между этими 2 исправление для V8 прошло в основном.
Предложение от @cookiemonster. Решением может быть использование более поздней версии node (из их нестабильного репо), но я не могу подтвердить это.
Мне не удалось найти отчет об этой проблеме в node списке проблем.
Единственное другое решение - проверить эту ошибку (приведенный выше код) и самостоятельно подделать затронутые методы. Я тестировал это решение, и он работает, вот прокладка, с которой я тестировал. (взято из проекта es5-shim)
Array.prototype.forEach = function forEach(fun /*, thisp*/ ) {
'use strict';
var object = Object(this),
thisp = arguments[1],
i = -1,
length = object.length >>> 0;
// If no callback function or if callback is not a callable function
if (Object.prototype.toString.call(fun) !== '[object Function]') {
throw new TypeError(); // TODO message
}
while (++i < length) {
if (i in object) {
// Invoke the callback function with call, passing arguments:
// context, property value, property key, thisArg object
// context
fun.call(thisp, object[i], i, object);
}
}
};
Проблема была решена с помощью