Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
就JavaScript引擎而言,实现原型委托而不是基于类的继承是否有好处?_Javascript - Fatal编程技术网

就JavaScript引擎而言,实现原型委托而不是基于类的继承是否有好处?

就JavaScript引擎而言,实现原型委托而不是基于类的继承是否有好处?,javascript,Javascript,看一看带有类的现代JavaScript,我的理解是,这些都是语法上的糖分,覆盖了ECMAScript2015之前使用的相同的基于原型的对象模型。我喜欢直接使用原型链,但类肯定更容易 所以在我看来,在JavaScript中,程序很可能都是根据基于类的语法指定的,但很可能是根据原型对象的规则执行的。因此,在JavaScript的编写方式和执行方式之间总是需要进行某种转换 不管JavaScript是如何通过浏览器和其他引擎实现的,我的问题是: 从编写JavaScript引擎的角度来看,实现面向对象的语

看一看带有类的现代JavaScript,我的理解是,这些都是语法上的糖分,覆盖了ECMAScript2015之前使用的相同的基于原型的对象模型。我喜欢直接使用原型链,但类肯定更容易

所以在我看来,在JavaScript中,程序很可能都是根据基于类的语法指定的,但很可能是根据原型对象的规则执行的。因此,在JavaScript的编写方式和执行方式之间总是需要进行某种转换

不管JavaScript是如何通过浏览器和其他引擎实现的,我的问题是:

从编写JavaScript引擎的角度来看,实现面向对象的语言在原型委托而不是类方面是否有性能或其他好处?

==编辑


一个类似的问题()的注释表明,传统意义上的类更容易在编译器级别实现,因为它们可以在内存中静态布局(我认为这是隐含的),但这不允许动态结构,如JavaScript允许的。因此,在我看来,原型委托可能非常适合在编译器级别实现动态对象?

JavaScript在某种程度上是在执行之前编译的。这就是语言编写方式和执行方式之间的“转换”。此外,正如您所说,较新的ES规范的许多特性实际上是语法糖

不管您如何声明这些类,它们最终都会编译成类似的抽象语法树(如果我错了,请纠正我)。它可以通过像Babel这样的中间编译器,也可以直接通过正在执行的实现

从这个角度来看,从编写JavaScript引擎的角度来看,使用更抽象的类定义的主要缺点是它需要支持更广泛的语法


可能的方式是通过将类语法简化为更本地的原型语法(中间编译)——这就是我将如何实施它的方法。这将导致编译阶段的性能受到轻微影响。

另一个角度是对象组合

考虑这一点:

class X { method() {} }
class Y extends X { method2() {} }

const y = new Y();
现在,在“经典”OOP中,
y
将是一个对象,它将有两个方法,
method
method2

在原型(经典JavaScript)意义上,
y
是一个对象。对象本身什么都没有,但在其原型上,它有一个
method2
。第一个
方法在哪里?好吧,如果你深入挖掘原型的构造函数,你会发现它也有一个原型,其中有
方法
的一部分

从节点REPL复制粘贴:

> class X { method() {} }
undefined
> class Y extends X { method2() {} }
undefined
> const y = new Y();
undefined
> y
Y {}
> y.prototype
undefined
> y.__proto__
Y {}
> y.__proto__.constructor
[Function: Y]
> y.__proto__.constructor.__proto__
[Function: X]
您需要能够支持对事物原型进行猴补丁的人:

> X.prototype.method = () => console.log('I am here now!');
[Function]
> y.method();
I am here now!

“从…实现面向对象语言的角度”。。。这不应该与您正在创建的实现语言一起标记吗?原型继承模型的好处主要是灵活性——它与duck类型方法配合得非常好。“JavaScript编写方式和执行方式之间的某种转换”——这种脱节可能没有您想象的那么大。不管怎样,在幕后,所有这些都被转换成完全不同的数据结构。编译器可以在解析语法时或多或少地进行内联翻译。其实大部分都是速记,没什么了。我不太确定你想要什么答案。像JavaScript这样的灵活语言编写引擎比C语言或C++语言的静态语言更难,因为优化必须在运行时(如死代码删除、内联、……)进行。优势在于语言的用户。“JavaScript是在执行之前编译的——这是语言的一个整体属性”——呃,JavaScript是被解释的?我甚至记得有一个特定的实现,它只有一个解析器和一个解释器在AST上运行,以最小化内存占用。我认为将JS代码进行的转换称为“编译”(具有词汇范围和提升)是公平的,但我也看到了这会引起混乱。它不是像C这样的编译语言(有人可能会说C也可以被解释——人类可以理解的任何东西),但不是像BASIC这样的真正解释语言。我将进行编辑。@Bergi FWIW V8(Chrome的JS引擎)的更高版本在加载脚本时立即从源代码中创建字节码。然后在JVM中解释这个字节码,当可以进行优化时,相关部分被编译成本机代码(在上下文的生命周期内)。但这与问题无关——我认为关键是JavaScript对OOP/继承甚至没有经典的理解——它是基于原型的。语法,或者对于这个问题,如何编译和优化这些东西并不重要。您仍然必须支持原型。