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

时间:2015-08-13 00:56:40

标签: javascript node.js ecmascript-6

我试图编写一些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是否使用不同的规范,其中的名称不应该是可配置的?或者我是否已经发现了一个真正的错误?

2 个答案:

答案 0 :(得分:3)

无法在节点v.0.12.2中更改Function对象上的.name属性,因为Function对象上的name属性默认为writable: falseconfigurable: 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;
&#13;
&#13;

答案 1 :(得分:0)

虽然之前没有指定,但.name property函数在许多引擎中都是非标准功能,这使得该属性不可写且不可配置。

随着ECMAScript的第6版发生了变化,.name现在已成为函数实例的正式特性。但是,许多引擎尚未采用这种改变。

它在您的Chrome浏览器中有效表明其中一个较新版本的V8支持此功能。请考虑更新您的node.js,或切换到io.js.

  

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

如你所知,没有(或至少目前不是)。

  

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

  

我在阅读规范时遗漏了什么吗?

没有

  

node.js是否使用不同的规范,说明名称不可配置?

没有

  

或者我是否已经发现了一个真正的错误?

我称之为&#34;缺少功能&#34;,而不是错误。 Node还没有声称支持ES6,所以虽然他们计划将来做,但目前并不是真正的bug。