在我使用 JavaScript 语言的这段时间里,我使用了不同的方法来通过类(或对象字面量)的模拟来创建对象。
我使用过的表格如下:
闭包:
var NombreClase = (function () { function NombreClase () {} NombreClase.prototype.metodo = function () { // código } NombreClase.metodoEstático = function () { // código } function metodoPrivado () { // código } return NombreClase; })();
原型 (
prototype
) :function NombreClase (arg1, arg2) { this.arg1 = arg1; this.arg2 = arg2; } NombreClase.prototype.metodo = function () { // código } NombreClase.metodoEstático = function () { // código }
文字对象:
var NombreClase = { prop: 'foo', metodo: function () { // body... } };
我想客观的知道什么是最好的使用方法?有没有别的方法?为什么推荐它?
JavaScript 的继承系统与大多数具有适当类的语言的工作方式不同。在javascript中没有类,有原型,它们与类有相似之处,但它们的行为并不完全像它们。
两种继承类型之间的第一个最明显的区别是,在传统类中,它们生成新对象的模型并负责其初始化,也就是说,它们具有构造函数并定义所创建对象将具有的方法。这是 C# 中的一个示例
对象属性(读取属性、方法等)的定义受在同一类和父类中声明的方法的限制,并且可以在同一类定义中控制所述属性的可见性。
在 javascript 中,这类似地工作,但根本区别在于初始化代码或构造函数(读取函数)是同一类内部的代码,继承系统由原型管理。结果大致相同,但职责是分开执行的。
所有属性都是公开的,您必须借助技巧来实现封装。也可以在同一个构造函数的执行中创建新的属性
这样做的缺点是现在每个对象都有不同的方法副本,因此原型用于使方法创建更有效,因为所有实例共享相同的方法。
很明显,该语言非常宽松,没有面向对象编程中通常指定的类设计,因此模拟一个类产生了无数不同的实现,所有这些都专注于弥补语言的缺点。
基本上有两种方法可以创建一个类,所有可以使用的库都将在内部使用一种方法或另一种方法。
关闭
如您所见,原型没有在任何地方使用,这具有操作员
instanceof
停止工作的直接缺点。正如我之前提到的,在构造函数中创建方法的效率也较低。优点是通常在 javascript 中,setTimeout(hijo.imprime.bind(hijo), 1000)
由于关键字的工作方式,您必须执行此类操作this
,在这种情况下您可以直接执行setTimeout(hijo.imprime, 1000)
.原型
这是首选的变体,您会发现许多实现的行为略有不同,但基本上都是这样做的
Como puedes ver toda la definición es radicalmente diferente a la definición estandard de una clase ya que se encuentra dispersa y no es muy fácil de razonar. El truco de este método siempre consiste en reemplazar o modificar la propiedad
prototype
de la función(clase) para establecer una cadena de herencia ya que en javascript cuando una propiedad es referenciada el interprete busca en su prototipo y en el prototipo de su padre y así sucesivamente hasta que llega a Object.prototype.Las soluciones giran siempre en torno a este mecanismo. Aquí te dejo la implementación de util.inherits de node que usa el método Object.create para establecer el prototipo. Este tiene la peculiar característica de usar una propiedad
super_
para almacenar una referencia a la clase padre para su posterior uso.Clases ES6
Estas clases son azúcar sintáctico sobre la herencia prototípica tradicional de javascript.
Mucho más limpio y fácil de entender pero sigue siendo herencia de prototipos hasta el punto que es posible heredar de una simple función
Aquí hay una lista de las librerías más notables que implementan OOP directamente en javascript o que compilan a este
好吧,我认为这三个都是有用的,问题是我们在工作时更舒服。
关闭
我觉得使用这些很舒服,因为如果我们使用设计模式,很容易组装一个模块化模式。允许轻松阅读代码。公共和私人功能的概念是分开的。它是最接近类的东西。
原型
原型对我来说似乎更基本,更强大的是能够更改特定功能而无需修改主要对象的问题,公共和私有功能的管理变得更加复杂。
目的
它是一个简单的对象,您没有创建这样的类。
我的建议是使用闭包,因为它是最接近类的东西,如果你使用面向对象编程,它会很容易阅读和创建它们。对于性能问题,我认为这取决于您给它的复杂性,但我认为没有太大区别。
创建一个原生 JavaScript 类。
在它引入的许多东西中,ECMAScript 6 包括使用关键字定义类
class
:如果您使用的是 Node.js,则这些类在最新版本中可用。在早期版本中,它们可通过选项 获得
--harmony
。问题通常来自想要在浏览器中使用这些功能,在这种情况下,建议使用Babel,这是一个支持类等的 ES6 到 ES5 编译器。如果您的要求包括 ES5 支持,Babel 也可用于 Node.js。
在第三种情况下,没有模拟一个类,因为它只有一个具有属性和函数的对象。
第二,将函数分配给原型时,方法是在函数的原型中定义的,这意味着“类”的所有实例的方法都有一个副本,方式与它类似在其他成语中实现。
第一种情况,不仅实现了上述,而且由于有闭包,所以也可以在最外层的函数之外封装没有作用域的私有方法,这是最接近类的东西。
除了私有方法之外,这种形式类似于TypeScript,它是 JavaScript 的超集,将其类编译为 JavaScript。
打字稿:
JavaScript:
我无法告诉您在 Javascript 中创建类的最佳或最差方式是什么,因为考虑到给定程序员的偏好,这将成为讨论的主题。
关于性能问题,我不确切知道创建类的一种或另一种方式会推断出什么,我认为它们中的任何一个都是相同的性能,您真正需要考虑的是方法调用中的性能并获取变化很小的数据,例如,一个好的做法是在 javascript 中实现缓存
关于在 javascript 中创建类,无论
emules
类是什么,我建议您在容器/命名空间中创建它。我将把我在网上找到的这篇JavaScript 面向对象编程作为参考,也许在那里你会找到在 javascripts 中创建类的最佳方法。
如果您的代码要扩展得如此之多以至于您需要类,我的建议是您停止考虑它并从
打字稿
TypeScript 是 javascript 语言的超集,它结合了 OOP 和强类型功能。在生成 TypeScript 项目时,“编译”的结果是简单的高性能和功能标准 javascript。
TypeScript 已经包含对ECMA Script 6的全面支持,并已被业内大公司采用,例如
还有更多
它很容易学习,因为作为超集,您可以继续使用您已经了解的有关 javascript 的所有内容。
打字稿演练
例子
在 Ceylon,我们使用第二种方法,原型方法,但构造函数是私有函数。我们定义一个这样的类型:
创建实例:
我们根据Douglas Crockford的“JavaScript: The Good parts”一书进行了这个设计。除了一些额外的机制,它甚至允许我们实现多重继承。
一个不错的选择是使用 babeljs 能够使用 es6/7 功能,例如类。
https://babeljs.io/
这是最近非常流行的工作方式,您可以将 babeljs 与 webpack 或 browserify 一起使用,以在一个单独的包中编译和优化所有代码。
我得出的结论是,有 3 种好方法可以做到这一点。并就该主题创建了以下帖子:
http://ricardogeek.com/3-ways-to-define-classes-in-javascript/
我希望它可以帮助你:)