The problem does exist with node v0.10.28 (latest stable) installed along with V8 v3.14.5.9 (and earlier versions), but the problem is not node itself but with V8, which has a bug.
The bug report can be found in issue 2273 posted on Aug 5, 2012.
A strict mode function should receive a non-coerced 'this' value. That is, 'this' can be undefined/null instead of the global object, and primitive values instead of boxed values.
It does not matter whether the caller function is in strict mode or not. However, built-in functions such as 'Array.prototype.forEach' incorrectly do the coercion even though the function to be called is in strict mode.
Test case:
(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();
})();
The bug fix was committed to the V8 source code in revision r14149 on Apr 5, 2013
So the problem was long standing and affected all environments that were based on the V8 engine.
I was able to confirm that Chrome v27 was still affected with this issue and it was running V8 v 3.16, and can confirm that Chrome v34 with V8 v3.24.35.33 is no longer affected. So somewhere between these 2 the fix for V8 went mainstream.
A suggestion by @cookiemonster A solution may be to use a later version of node (from their unstable repo) but I can not confirm this.
I have not been able to find any report of this issue in the node issues list.
The only other solution is to test for this bug (code given above) and to shim the affected methods yourself. I have tested this solution and it works, here is the shim that I tested with. (taken from the es5-shim project)
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);
}
}
};
The issue has been taken up with: