我试图编写一些javascript来运行客户端和服务器端。我想动态重命名函数(以帮助调试等)。 我有以下代码:
function genericFunction() {}
Object.defineProperty(genericFunction, 'name', {writable: true});
genericFunction.name = 'specificFunction';
console.log(genericFunction.name);
在chrome(v43)中输出" specificFunction"正如所料。但是,在node.js(v0.10)中,我得到:
TypeError:无法重新定义属性:name
我做了一点调试,这似乎是输出
之间的差异console.log(Object.getOwnPropertyDescriptor(function () {}, 'name').configurable);
在Chrome上它是真的,但node.js输出false。
我对the spec的理解非常有限,对于函数名称,可配置应始终为true。 我在阅读规范时遗漏了什么吗? node.js是否使用不同的规范,其中的名称不应该是可配置的?或者我是否已经发现了一个真正的错误?
答案 0 :(得分:3)
无法在节点v.0.12.2中更改Function对象上的.name
属性,因为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
属性,也无法将其重新配置为可写。
在Chrome 44.0.2403.130 m中,您可以看到:
{"value":"f","writable":false,"enumerable":false,"configurable":true }
默认情况下,您无法写入,但由于它是可配置的,您可以将其更改为可写,然后更改名称属性。
这可能是因为Chrome正在运行更新版本的V8引擎。根据{{3}},Chrome配置看起来是正确的默认设置。
如果您在最新的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);
}
&#13;
答案 1 :(得分:0)
虽然之前没有指定,但.name
property函数在许多引擎中都是非标准功能,这使得该属性不可写且不可配置。
随着ECMAScript的第6版发生了变化,.name
现在已成为函数实例的正式特性。但是,许多引擎尚未采用这种改变。
它在您的Chrome浏览器中有效表明其中一个较新版本的V8支持此功能。请考虑更新您的node.js,或切换到io.js.
可以在node.js中配置函数名吗?
如你所知,没有(或至少目前不是)。
我(非常有限)对规范的理解是,对于函数名,可配置应始终为真。
是
我在阅读规范时遗漏了什么吗?
没有
node.js是否使用不同的规范,说明名称不可配置?
没有
或者我是否已经发现了一个真正的错误?
我称之为&#34;缺少功能&#34;,而不是错误。 Node还没有声称支持ES6,所以虽然他们计划将来做,但目前并不是真正的bug。