简体   繁体   English

可以在node.js中配置函数名称吗?

[英]Can function names be configured in node.js?

I'm trying to write some javascript to run both client and server side. 我正在尝试编写一些JavaScript以同时运行客户端和服务器端。 I'd like to dynamically rename functions (to aid debugging etc). 我想动态重命名功能(以帮助调试等)。 I have the following code: 我有以下代码:

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

In chrome (v43) this outputs "specificFunction" as expected. 在chrome(v43)中,这将按预期输出“ specificFunction”。 However, in node.js (v0.10), I get: 但是,在node.js(v0.10)中,我得到:

TypeError: Cannot redefine property: name TypeError:无法重新定义属性:name

I've done a little debugging and this seems to be down to the different between the output of 我做了一些调试,这似乎归因于

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

On chrome it's true, but node.js outputs false. 在chrome上为true,但是node.js输出false。

My (very limited) understanding of the spec is that for function names, configurable should always be true. 对规范的了解(非常有限)是对于函数名称,可配置应该始终为true。 Have I missed something in reading the spec? 我在阅读规格时错过了什么吗? Does node.js use a different spec which says names shouldn't be configurable? node.js是否使用不同的规范来说明名称不可配置? Or have I stubbled across a genuine bug? 还是我一直在寻找真正的错误?

The .name property on Function objects cannot be changed in node v.0.12.2 because the name property on Function objects defaults to writable: false and configurable: false so there's no way to make it writable. 无法在节点v.0.12.2中更改Function对象上的.name属性,因为Function对象上的name属性默认为writable: false和可configurable: false因此无法使其可写。

This is not in agreement with ES6. 这与ES6不同。 Since the current implementation of Chrome is in agreement with ES6 in this regard, we can assume that node is just behind in V8 engine version and some future version will fix this. 由于在这方面,Chrome的当前实现与ES6一致,因此我们可以假定该节点在V8引擎版本中紧随其后,将来的某个版本将对此进行修复。 Note: The --harmony flag with node does not change this behavior either. 注意:带有节点的--harmony标志也不会更改此行为。


Here's the technical difference between node v.0.12.2 and Chrome 44.0.2403.130 m. 这是节点v.0.12.2和Chrome 44.0.2403.130 m之间的技术区别。

In node v.0.12.2, if you do this: 在节点v.0.12.2中,如果执行以下操作:

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

It outputs: 它输出:

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

As you can see, you cannot write to the .name property and you cannot reconfigure it to be writable. 如您所见,您无法写入.name属性,也无法将其重新配置为可写。


In Chrome 44.0.2403.130 m, you get this: 在Chrome 44.0.2403.130 m中,您会得到以下信息:

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

You cannot write to it by default, but because it is configurable, you could change it to writable and then change the name property after that. 默认情况下,您无法对其进行写入,但是由于它是可配置的,因此可以将其更改为可写,然后在其后更改name属性。


This is presumably because Chrome is running a more recent version of the V8 engine. 大概是因为Chrome浏览器正在运行V8引擎的最新版本。 Per the ES6 spec description , the Chrome configuration looks like the proper default. 根据ES6规范说明 ,Chrome配置看起来像是正确的默认设置。


If you run this code in the latest Chrome, you can see that it works: 如果您在最新的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); } 

While previously not specified at all, the .name property of functions was a non-standard feature in many engines, which made the property to be non-writable and non-configurable though. 尽管以前没有完全指定,但函数的.name属性是许多引擎中的非标准功能,尽管如此,该属性还是不可写且不可配置的。

With the 6th Edition of ECMAScript this has changed, and .name is now an officially specced property of function instances. 随着ECMAScript第六版的改变, .name现在是函数实例的正式指定属性。 However, many engines have not yet adopted this change. 但是,许多引擎尚未采用此更改。

That it works in your Chrome browser suggests that one of the newer versions of V8 supports this. 它可以在您的Chrome浏览器中正常工作,这表明较新的V8版本之一支持此功能。 Consider updating your node.js, or switch to io.js. 考虑更新您的node.js,或切换到io.js。


Can function names be configured in node.js? 可以在node.js中配置函数名称吗?

As you have established, no (or at least, not currently). 如您所确定,没有(或至少目前不是)。

My (very limited) understanding of the spec is that for function names, configurable should always be true. 我对规范的了解(非常有限)是对于函数名称,可配置应该始终为true。

Yes. 是。

Have I missed something in reading the spec? 我在阅读规格时错过了什么吗?

No. 没有。

Does node.js use a different spec which says names shouldn't be configurable? node.js是否使用不同的规范来说明名称不可配置?

No. 没有。

Or have I stubbled across a genuine bug? 还是我一直在寻找真正的错误?

I'd call it a "missing feature", not a bug. 我将其称为“缺少的功能”,而不是错误。 Node doesn't claim to support ES6 yet, so while they do plan to do in the future it's not really a bug currently. Node尚未声称支持ES6,因此尽管他们计划在将来进行支持,但它实际上并不是一个错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM