函数名可以在node.js中configuration吗?

我试图写一些JavaScript来运行客户端和服务器端。 我想dynamic重命名函数(以​​帮助debugging等)。 我有以下代码:

function genericFunction() {} Object.defineProperty(genericFunction, 'name', {writable: true}); genericFunction.name = 'specificFunction'; console.log(genericFunction.name); 

在铬(v43)中,如预期的那样输出“特定function”。 但是,在node.js(v0.10)中,我得到:

TypeError:无法重新定义属性:名称

我已经做了一些debugging,这似乎是不同的输出之间的差异

 console.log(Object.getOwnPropertyDescriptor(function () {}, 'name').configurable); 

在铬是真的,但node.js输出false。

我对规范的理解(非常有限)是对于函数名称,可configuration应该始终为真。 我在阅读规范时错过了什么? node.js是否使用不同的规范说,名称不应该是可configuration的? 还是我绊倒了一个真正的bug?

Function对象的.name属性在节点v.0.12.2中不能被改变,因为Function对象的name属性默认是writable: false和可configurable: false所以没有办法使它成为可写的。

这不符合ES6。 由于目前Chrome的实现与ES6在这方面是一致的,所以我们可以假设节点刚刚落后于V8引擎版本,而一些未来的版本将会解决这个问题。 注意:带节点的--harmony标志也不会改变这种行为。


以下是节点v.0.12.2和Chrome 44.0.2403.130 m之间的技术差异。

在节点v.0.12.2中,如果你这样做:

 function f() {} console.log(Object.getOwnPropertyDescriptor(f, "name")); 

它输出:

 {value: 'f', writable: false, enumerable: false, configurable: false} 

正如你所看到的,你不能写入.name属性,你不能重新configuration它是可写的。


在Chrome 44.0.2403.130米,你得到这个:

 {"value":"f","writable":false,"enumerable":false,"configurable":true } 

您不能默认写入,但是由于它是可configuration的,您可以将其更改为可写,然后在此之后更改name属性。


这大概是因为Chrome正在运行更新版本的V8引擎。 根据ES6规范描述 ,Chromeconfiguration看起来像正确的默认设置。


如果你在最新的Chrome中运行这个代码,你可以看到它的工作原理:

 function f() {} var alias = f; log(Object.getOwnPropertyDescriptor(f, "name")); // this name change will not work because writable === false log(alias.name); f.name = "foo"; log(alias.name); // change writable to true Object.defineProperty(f, "name", {writable: true}); log(Object.getOwnPropertyDescriptor(f, "name")); // this name change will work f.name = "foo"; log(alias.name); // utility function to put output into main window for snippet function log(args) { var str = ""; for (var i = 0; i < arguments.length; i++) { if (typeof arguments[i] === "object") { str += JSON.stringify(arguments[i]); } else { str += arguments[i]; } } var div = document.createElement("div"); div.innerHTML = str; var target = log.id ? document.getElementById(log.id) : document.body; target.appendChild(div); } 

虽然以前没有指定,但是函数的.name属性在许多引擎中是非标准的特性,这使得该属性不可写和不可configuration。

随着ECMAScript的第六版,这已经改变了,而.name现在是函数实例的一个正式指定的属性。 但是,很多引擎还没有采用这种变化。

它可以在Chrome浏览器中运行,这意味着V8的一个新版本支持这一点。 考虑更新你的node.js,或切换到io.js.


函数名可以在node.js中configuration吗?

正如你所build立的,没有(或至less不是现在)。

我对规范的理解(非常有限)是对于函数名称,可configuration应该始终为真。

是。

我在阅读规范时错过了什么?

没有。

node.js是否使用不同的规范说,名称不应该是可configuration的?

没有。

还是我绊倒了一个真正的bug?

我把它称为“缺less的function”,而不是一个错误。 Node并没有声称支持ES6,所以虽然他们打算今后做,但目前并不是一个真正的bug。