javascript ecmascript-6

Javascript: ¿Cuál es la diferencia entre Function y Class?



ecmascript-6 (2)

Con el lanzamiento de ECMAScript 6 en junio de 2015, se introdujo la sintaxis de clases de Javascript.

Esta sintaxis:

class Polygon { constructor(width, height) { this.width = width; this.height = height; } }

es básicamente lo mismo que:

function Polygon(width, height) { this.width = width; this.height = height; }

Entonces, ¿cuál es el beneficio de usar la clase en lugar de la función tradicional? ¿Y en qué condiciones debo usar la clase en lugar de la función?


Existen algunas diferencias entre la Clase y la Función: la mayoría de las personas comenzarán diciendo que la Clase es "solo azúcar de sintaxis", pero que el azúcar sí importa bastante. Cuando el analizador JS procesa el código JavaScript, el analizador los guardará en diferentes nodos AST, como se muestra aquí, ClassDeclaration y ClassExpression son diferentes tipos de nodos en el árbol AST resultante:

https://github.com/estree/estree/blob/master/es2015.md#classes

Puede ver que para este analizador, la nueva especificación de Clases ES6 introduce una serie de nuevos elementos AST a la sintaxis:

  • ClassBody
  • Método Definición
  • Declaración de clase
  • ClassExpression
  • MetaProperty

Dado que la sintaxis AST no es estándar, puede haber más o menos tipos dependiendo del analizador, pero es importante tener en cuenta que cuando el código ingrese la declaración de clase o la expresión de clase, el motor de JavaScript lo interpretará de manera diferente.

Esto significa que las declaraciones de clase y función no se pueden intercambiar. Puedes ver esto si intentas escribir

class notWorking { return 1; // <-- creates a parser error };

Esto se debe a que cuando el analizador encuentra la palabra clave de clase, comenzará a tratar el siguiente código como ClassBody de ClassDeclaration o ClassExpression y luego espera encontrar MethodDefinitions.

Este es un pequeño problema , porque crear variables privadas se vuelve un poco más desafiante. La declaración de función podría definir una variable privada claramente como esta:

function myClass() { var privateVar; }

La declaración de clase no puede tener esto:

class myClass { var privateVar; // ERROR: should be a method }

Esto se debe a que la sintaxis de la clase solo permite declarar métodos dentro del cuerpo de la clase. Al menos ahora mismo.

Sin embargo, existe una propuesta para crear campos privados:

https://github.com/zenparsing/es-private-fields

Por lo tanto, en el futuro podrías decir

class myClass { #privateVar; // maybe this works in the future? }

Hay una respuesta separada teniendo en cuenta las propiedades privadas en las clases de ES6, lo que sugiere algunas soluciones, como el uso de símbolos:

Propiedades privadas en clases de JavaScript ES6

var property = Symbol(); // private property workaround example class Something { constructor(){ this[property] = "test"; } }

Naturalmente, hay más diferencias entre clases y funciones. Una de ellas es la elevación 1 : a diferencia de las funciones, no puede declarar la clase en ninguna parte del alcance:

Una diferencia importante entre las declaraciones de función y las declaraciones de clase es que las declaraciones de función se izan y las declaraciones de clase no. Primero debes declarar tu clase y luego acceder a ella

Las declaraciones de clase y las declaraciones de función son bastante similares;

function foo1() {} // can be used before declaration class foo2{} // new foo2(); works only after this declaration

Las expresiones de clase funcionan de manera bastante similar a las expresiones de función, por ejemplo, se pueden asignar a una variable:

var myClass = class foobar {};

Más diferencias son 1

  1. El cuerpo de expresión / declaración de clase siempre se ejecuta en modo estricto ; no es necesario especificarlo manualmente
  2. Las clases tienen un constructor de palabras clave especial: puede haber solo una de ellas o se genera un error. Las funciones pueden tener múltiples definiciones de variable de función denominada "constructor"
  3. Las clases tienen una palabra clave especial super que se relaciona con el constructor de clases padre. Si está dentro del constructor, puede llamar a super (x, y); para llamar al constructor de la clase principal, pero dentro del Método puede llamar a super.foobar () para crear una llamada a cualquier función de la clase principal. Este tipo de funcionalidad no está disponible para las funciones estándar, aunque puede emularlo con algún pirateo personalizado.
  4. Dentro del cuerpo de la clase, puede definir la función con una palabra clave estática para que se pueda llamar usando solo ClassName.FunctionName () -syntax.
  5. Tanto las declaraciones de clase como las expresiones pueden usar la palabra clave extend como la clase Dog extender Animal
  6. MethodDeclaration no necesita la función -prefix, por lo tanto, puede definir la función "ok" dentro de la clase "m" de esta manera: class m {ok () {}} . En realidad, ni siquiera está permitido definir la función como clase m {function ok () {}}

Sin embargo, una vez que el analizador ha completado su trabajo, la instancia de clase se ejecuta esencialmente de la misma manera que cualquier otro objeto.

La nueva sintaxis de la clase ES6 es esencialmente una forma más clara de expresar objetos de una manera tradicional OOP y, si te gusta, entonces debes usarla.

EDITAR: también, la sintaxis de la Clase ES6 también tiene otra limitación: no permite que las funciones miembro utilicen un enlace léxico usando la flecha gorda. ES7 parece tener 1 que lo permite. Eso puede ser útil, por ejemplo, cuando se vinculan métodos a controladores de eventos, la pregunta relacionada está here .

1 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes


class no es más que un azúcar sintáctico sobre la creación de la clase lógica de JavaScript utilizando la function . si está utilizando una function como class la función completa es actuar como un constructor, si desea poner otras funciones miembro, debe hacerlo en un constructor como this.something = ... , o var something = ... en caso de que de miembros privados (si no está inyectando desde el exterior, suponga que está creando objetos con otros métodos / propiedades), pero en el caso de la clase, toda la función no es en realidad un constructor, puede separarla explícitamente con otras funciones y datos de miembros.