javascript – 具有’thisArg’和’use strict’的Nodejs方法;问题

前端之家收集整理的这篇文章主要介绍了javascript – 具有’thisArg’和’use strict’的Nodejs方法;问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在Fedora 19上安装了v0.10.28节点V8 v3.14.5.9.我遇到的问题是有一个方法,它有一个可选的参数,如Array.prototype.forEach.

如果我在Chromium v​​33或Firefox v28 – jsFiddle上执行以下代码

var y = [1,2,3];

y.forEach(function (element) {
    console.log(this);
},'hej');

我得到一个输出

String {0: "h",1: "e",2: "j",length: 3}
String {0: "h",length: 3}

然后相同的代码,但严格模式 – jsFiddle

var y = [1,3];

y.forEach(function (element) {
    'use strict';
    console.log(this);
},'hej');

我得到一个输出

hej
hej
hej

这些是根据ECMA5规范sec-function.prototype.call所预期的结果.

The thisArg value is passed without modification as the this value. This is a change from Edition 3,where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. Even though the thisArg is passed without modification,non-strict mode functions still perform these transfromations upon entry to the function.

例如sec-array.prototype.foreach

If a thisArg parameter is provided,it will be used as the this value for each invocation of callbackfn. If it is not provided,undefined is used instead.

和相关的伪代码

Let funcResult be the result of calling the [[Call]] internal method of callbackfn with T as thisArgument and a List containing kValue,k,and O as argumentsList.

但是,在节点上,上述代码片段都将返回

{ '0': 'h','1': 'e','2': 'j' }
{ '0': 'h','2': 'j' }

任何人都可以确认这是否与我的节点环境有关,或者这是节点的问题吗?

更新:只是为了确认,在这两种情况下,这个返回对象的节点类型.

解决方法

节点v0.10.28(最新版本)与V8 v3.14.5.9(及更早版本)一起安装,问题确实存在,但是问题不在于节点本身,而是具有V8的问题.

错误报告可以在2012年8月5日发布的issue 2273中找到.

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();
})();

错误修复在2013年4月5日的revision r14149版中承诺了V8源代码

所以这个问题长期存在,影响了所有基于V8引擎的环境.

我确认Chrome v27仍然受到此问题的影响,并且正在运行V8 v 3.16,并且可以确认Chrome V34与V8 v3.24.35.33不再受到影响.所以在这两个之间,V8的修复就成了主流.

@cookiemonster的建议解决方案可能是使用更高版本的节点(从他们的不稳定的repo),但我无法确认.

我在node issues list没有找到任何关于这个问题的报道.

唯一的其他解决方案是测试这个错误(上面给出的代码),并自己填充受影响的方法.我已经测试了这个解决方案,它的工作原理,这里是我测试的垫片. (取自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);
        }
    }
};

这个问题已经解决了:

> idiomatic.js
> es5-shim
> nodejs

猜你在找的JavaScript相关文章