我在 Fedora 19 上安装了 Node v0.10.28 和 V8 v3.14.5.9。我遇到的问题是具有 thisArg 可选参数的方法,例如 Array。 prototype.forEach.
如果我在 Chromium v33 或 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", 1: "e", 2: "j", length: 3}
String {0: "h", 1: "e", 2: "j", length: 3}
然后是相同的代码,但处于严格模式 - jsFiddle
var y = [1, 2, 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.
然而,在 Node 上,上述两个片段都返回
{ '0': 'h', '1': 'e', '2': 'j' }
{ '0': 'h', '1': 'e', '2': 'j' }
{ '0': 'h', '1': 'e', '2': 'j' }
谁能确认这是我的 Node 环境的问题,还是 Node 的问题?
更新:只是为了确认,在 Node typeof this 上的两种情况下都返回 object。
最佳答案
与 V8 v3.14.5.9(及更早版本)一起安装的 node v0.10.28(最新稳定版)确实存在问题,但问题不在于 node 本身,而在于 V8,它有一个错误。
可以在 issue 2273 中找到错误报告。发布于 2012 年 8 月 5 日。
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();
})();
错误修复已提交到 revision r14149 中的 V8 源代码2013 年 4 月 5 日
所以这个问题长期存在并影响了所有基于 V8 引擎的环境。
我能够确认 Chrome v27 仍然受到此问题的影响,并且它正在运行 V8 v 3.16,并且可以确认带有 V8 v3.24.35.33 的 Chrome v34 不再受到影响。所以在这两者之间的某个地方,V8 的修复成为了主流。
@cookiemonster 的建议一个解决方案可能是使用更高版本的 Node (来自他们的不稳定 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);
}
}
};
该问题已被处理:
关于javascript - 带有 'thisArg' 和 'use strict' 的 Nodejs 方法;问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23484732/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer