0

然后,我想,更完整的问题是,“当 Javascript 引擎已知时(基于每个流行的引擎),这些考虑因素如何受到影响。”

我觉得我需要问“社区”的原因是因为像 Strongloop 这样创建 Node.js 之类的东西的人,也编写了 util.inherits 之类的代码,一个函数在其中,而不是:TheConstructorFunction.prototype.constructor = TheConstructorFunction他们创建了一个属性定义,它本身有 4 个属性正在设置:

ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
        value: ctor,
        enumerable: false,
        writable: true,
        configurable: true
    }
});

这对我来说似乎效率低下,但是,与这样的代码作者相比,我只是努力编写更好的 Javascript 3 年。有没有解释为什么这有效或无效?

一个答案说 util.inherits 并不是低效的,因为子类操作很少见。但是考虑到一些库处理在构建到测试结果观察之间发生的成百上千的子类操作,如果 Node.js 内部使用 util.inherits,那么这会影响其使用者的开发时间。我认为,在这个级别上,效率确实很重要,我希望 util.inherits 不会在内部使用。我什至不明白 util.inherits 的目的。为什么要拥有它?我认为它促进了复合效率低下。 require('util').inherits(C1,C2);几乎是同义词,可能比C1.prototype=Object.create(C2.prototype); C1.prototype.constructor=C1; 如果它只是为了吸引消费者,我很冷静。我担心这些专业人士是否在内部使用该功能,因为更大的库将取决于 Node.js 的效率。至于制作.constructor不可枚举......我认为它的“可枚举性”很重要的情况很少见,应该留给消费者,但如果内部操作取决于 util.inherits,这并不是真的留给消费者。

4

2 回答 2

1

这对我来说似乎效率低下

不,效率在这里并不重要。子类化是一种罕见的操作,即使代码比简单的赋值慢(很可能没有太大区别),这也不会影响性能。

重要的是正确性utils.inherit,尤其是对于无处不在的库函数。那么他们为什么要使用属性属性呢?为了使不可枚举,就像它是本机创建的对象的标准一样,因此通常是预期的。.constructor.prototype

鉴于此处不需要考虑速度和内存,因此您似乎期望的优化不会在此处进行。

于 2016-09-29T18:59:41.370 回答
0

JavaScript 引擎的作者最好回答这个问题。

这是一个称为性能调整的过程。

这是谷歌的指南这是 Mozilla 的指南

让 Node.js 快速运行 javascript 是 Strongloop 业务的核心。他们认真对待javascript 优化。

有一些这样的陷阱

大多数情况下,不要阻塞事件循环——使用 Promise、异步操作、回调等。

用合理的实际测试用例对您的代码进行基准测试。确保检查覆盖范围。

一旦你找到了寻找性能调整的主要原因,你就必须开始深入挖掘。您必须分析您的代码。

Thorsten Lorenz 有一个老化但仍然主要相关的GitHub 存储库,其中包含许多有用的内部 V8 信息。

有很多开发人员会发布博客文章比如这个人。你必须确保他们知道他们在说什么。他是这样的。

Bluebird 是一个众所周知的 Promises 实现,是正确优化的巅峰之作。他们有一篇文章和一个关于他们注意到的事情的指南,这些事情只是扼杀优化的常见事情。

更新

您给出的 util.s 实现继承链的示例可能应该是一个单独的问题。我不确定他们是否在那里修补猴子,我必须查看其余的课程和原型。

请参阅这篇 MDN 文章,了解实现继承的已知方法的优缺点和变体,特别是对于Object.create.

扩展内置原型(又名“猴子补丁”)的唯一充分理由是向后移植较新 JavaScript 引擎的功能;例如 Array.forEach 等。

以下是为什么会发生这种事情的一些原因。不久前我回答了一个关于将一个类注入到继承链的顶部的问题,目的是为它们的所有孩子添加一个扩展方法。这不是一个好主意。

事实证明,Object.createutil.js实施中inherits可能是最初的优化尝试。根据早期的修订,它使原型隐式不可变,理论上提高了方法解析性能。学究式地说,它从来都不是正确的,而且本质上一直是围绕 JavaScript 的原型继承功能进行的破解。新修订版将其替换为Object.setPrototypeOf.

编辑:如果您对此投了反对票,我将不胜感激。

于 2016-09-29T17:40:30.080 回答