Cómo el marketing cambió la programación orientada a objetos en JavaScript

 

 

 

  • SmashingConf Friburgo 2024
  • Accesibilidad para diseñadores, con Stéphanie Walter

  • Índice
    1. ¿Qué es la programación clásica orientada a objetos?
    2. ¿Qué es la programación orientada a objetos prototípica en JavaScript?
      1. ¿Cuál es la diferencia en JavaScript? Spoiler: Ninguno
    3. Hay pistas en la historia de JavaScript
    4. Si tan solo JavaScript adoptara sus prototipos
      1. El thisvalor en diferentes contextos
      2. El newprefijo
      3. Las múltiples formas de acceder a los prototipos
      4. Usando la __proto__propiedad literal en la inicialización
      5. Encapsulación y clases privadas
    5. Entonces, ¿clases o prototipos en JavaScript?
    6. Conclusión

    Al analizar las decisiones que rodean los prototipos de JavaScript, el artículo de Juan Diego Rodríguez analiza su origen, examina errores en el diseño y explora cómo estos factores han afectado la forma en que escribimos JavaScript hoy.

     

    Aunque el nombre de JavaScript se acuñó a partir del lenguaje Java, los dos lenguajes son mundos aparte. JavaScript tiene más en común con Lisp y Scheme , ya que comparte características como funciones de primera clase y alcance léxico.

    JavaScript también toma prestada su herencia prototípica del lenguaje Self . Este mecanismo de herencia es quizás lo que muchos (si no la mayoría) de los desarrolladores no dedican suficiente tiempo a comprender, principalmente porque no es un requisito para comenzar a trabajar con JavaScript. Esa característica puede verse como un defecto de diseño o un golpe de genialidad. Dicho esto, la naturaleza prototípica de JavaScript se comercializó y se ocultó detrás de una máscara de "Java para la web". Ampliaremos más sobre esto a medida que avancemos.

     

    JavaScript no confía en su propia naturaleza prototípica, por lo que brinda a los desarrolladores las herramientas para abordar el lenguaje sin tener que tocar un prototipo. Este fue un intento de que todos los desarrolladores lo entendieran fácilmente, especialmente aquellos que provienen de lenguajes basados ​​en clases, como Java, y luego se convertiría en uno de los mayores enemigos de JavaScript en los años venideros: no es necesario comprender cómo funciona JavaScript para código en JavaScript.

    ¿Qué es la programación clásica orientada a objetos?

    La programación orientada a objetos (POO) clásica gira en torno al concepto de clases e instancias y se usa ampliamente en lenguajes como Java, C++, C# y muchos otros. Una clase es un modelo o plantilla para crear objetos. Define la estructura y el comportamiento de los objetos que pertenecen a esa clase y encapsula propiedades y métodos. Por otro lado, los objetos son instancias de clases. Cuando creas un objeto a partir de una clase, básicamente estás creando una instancia específica que hereda la estructura y el comportamiento definidos en la clase y al mismo tiempo le da a cada objeto un estado individual.

    La programación orientada a objetos tiene muchos conceptos fundamentales, pero nos centraremos en la herencia , un mecanismo que permite que una clase adopte las propiedades y métodos de otra clase. Esto facilita la reutilización del código y la creación de una jerarquía de clases.

    Diagrama que muestra una clase con dos objetos conectados a otra clase conectada a dos objetos más. ( Vista previa grande )

    ¿Qué es la programación orientada a objetos prototípica en JavaScript?

    Explicaré los conceptos detrás del prototipo de programación orientada a objetos en Javascript, pero para una explicación detallada de cómo funcionan los prototipos, MDN tiene una excelente descripción general sobre el tema .

    La programación orientada a objetos prototípica se diferencia de la programación orientada a objetos clásica, que se basa en clases e instancias. En la programación orientada a objetos prototípica no hay clases, sólo objetos, y se crean directamente a partir de otros objetos.

    Si creamos un objeto, tendrá una propiedad incorporada llamada prototypeque contiene una referencia a su prototipo de objeto "principal" para que podamos acceder a los métodos y propiedades de su prototipo. Esto es lo que nos permite acceder a métodos como .sort()o .forEach()desde cualquier matriz, ya que cada matriz hereda métodos del Array.prototypeobjeto.

    El prototipo en sí es un objeto, por lo que el prototipo tendrá su propio prototipo. Esto crea una cadena de objetos conocida como cadena de prototipos . Cuando accede a una propiedad o método en un objeto, JavaScript primero lo buscará en el objeto mismo. Si no se encuentra, recorrerá la cadena del prototipo hasta encontrar la propiedad o alcanzar el objeto de nivel superior. A menudo terminará en Object.prototype, que tiene un nullprototipo que indica el final de la cadena.

     

    Una diferencia crucial entre la programación orientada a objetos clásica y la prototípica es que no podemos manipular dinámicamente una definición de clase una vez que se crea un objeto. Pero con los prototipos de JavaScript, podemos agregar, eliminar o cambiar métodos y propiedades del prototipo, lo que afecta a los objetos de la cadena.

    “Los objetos heredan de los objetos. ¿Qué podría estar más orientado a objetos que eso?

    —Douglas Crockford

    Diagrama que muestra el flujo entre dos objetos, cada uno de los cuales está conectado a otros dos objetos. ( Vista previa grande )

    ¿Cuál es la diferencia en JavaScript? Spoiler: Ninguno

    Entonces, sobre el papel, la diferencia es simple. En la programación orientada a objetos clásica, creamos instancias de objetos de una clase, y una clase puede heredar métodos y propiedades de otra clase. En la POO prototipo, los objetos pueden heredar propiedades y métodos de otros objetos a través de su prototipo.

    Sin embargo, en JavaScript no existe una sola diferencia más allá de la sintaxis. ¿Puedes detectar la diferencia entre los siguientes dos extractos de código?

    // With Classesclass Dog { constructor(name, color) { this.name = name; this.color = color; } bark() { return `I am a ${this.color} dog and my name is ${this.name}.`; }}const myDog = new Dog("Charlie", "brown");console.log(myDog.name); // Charlieconsole.log(myDog.bark()); // I am a brown dog and my name is Charlie.
    // With Prototypesfunction Dog(name, color) { this.name = name; this.color = color;}Dog.prototype.bark = function () { return `I am a ${this.color} dog and my name is ${this.name}.`;};const myDog = new Dog("Charlie", "brown");console.log(myDog.name); // Charlieconsole.log(myDog.bark()); // I am a brown dog and my name is Charlie.

    No hay diferencia y JavaScript ejecutará el mismo código, pero el último ejemplo es honesto acerca de lo que hace JavaScript bajo el capó, mientras que el primero lo esconde detrás del azúcar sintáctico.

    ¿Tengo algún problema con el enfoque clásico? Si y no. Se puede argumentar que la sintaxis clásica mejora la legibilidad al tener todo el código relacionado con la clase dentro de un alcance de bloque. Por otro lado, es engañoso y ha llevado a miles de desarrolladores a creer que JavaScript tiene clases verdaderas cuando una clase en JavaScript no es diferente de cualquier otro objeto de función .

    Mi mayor problema no es pretender que existan clases verdaderas, sino que no existen prototipos.

     

    Considere el siguiente código:

    class Dog { constructor(name, color) { this.name = name; this.color = color; } bark() { return `I am a ${this.color} dog and my name is ${this.name}.`; }}const myDog = new Dog("Charlie", "brown");Dog.prototype.bark = function () { return "I am really just another object with a prototype!";};console.log(myDog.bark()); // I am really just another object with a prototype!"

    Espera, ¿acabamos de acceder al prototipo de la clase? ¡Sí, porque las clases no existen! Son simplemente funciones que devuelven un objeto (llamadas funciones constructoras) e, inevitablemente, tienen un prototipo, lo que significa que podemos acceder a su .prototypepropiedad.

    Casi parece que JavaScript intenta ocultar sus prototipos. ¿Pero por qué?

    Hay pistas en la historia de JavaScript

    En mayo de 1995, Netscape involucró al creador de JavaScript, Brendan Eich, en un proyecto para implementar un lenguaje de secuencias de comandos en el navegador Netscape. La idea principal era implementar el lenguaje Scheme en el navegador debido a su enfoque mínimo. El plan cambió cuando Netscape cerró un trato con Sun Microsystems, creadores de Java, para implementar Java en la web. Muy pronto, Brendan Eich y el fundador de Sun Microsystems, Bill Joy, vieron la necesidad de un nuevo lenguaje. Un lenguaje accesible para personas cuyo enfoque principal no era sólo la programación. Un lenguaje tanto para un diseñador que intenta crear un sitio web como para un desarrollador experimentado que viene de Java.

    Con este objetivo en mente, se creó JavaScript en 10 días de intenso trabajo bajo el nombre inicial de Mocha . Se cambiaría a LiveScript para comercializarlo como un script que se ejecuta "en vivo" en el navegador, pero en diciembre de 1995 finalmente se llamaría JavaScript y se comercializaría junto con Java. Este acuerdo con Sun Microsystems obligó a Brendan a adaptar su lenguaje basado en prototipos a Java. Según Brendan Eich , JavaScript fue tratado como el “lenguaje compañero de Java” y carecía de fondos suficientes en comparación con el equipo de Java:

    “Estuve pensando todo el tiempo, ¿cómo debería ser el idioma? ¿Debería ser fácil de usar? ¿Podría la sintaxis parecerse más al lenguaje natural? [...] Bueno, me gustaría hacer eso, pero mi gerencia dijo: "Haz que parezca Java".

    La idea de Eich para JavaScript era implementar funciones de primera clase de Scheme (una característica que permitiría devoluciones de llamadas para eventos de usuario) y programación orientada a objetos basada en prototipos de Self. Ya lo ha expresado antes en su blog:

    "No estoy orgulloso, pero estoy feliz de haber elegido funciones de primera clase tipo Scheme y prototipos egoístas como ingredientes principales".

    La naturaleza prototípica de JavaScript se mantuvo, pero quedaría específicamente oscurecida detrás de una fachada de Java. Los prototipos probablemente permanecieron en su lugar porque Eich implementó prototipos propios desde el principio y luego no pudieron cambiarse, solo ocultarse. Podemos encontrar una explicación mixta en un antiguo comentario en su blog :

    “Es irónico que JS no pudiera tener clase en 1995 porque habría rivalizado con Java. Estaba limitado tanto por el tiempo como por el papel de compañero”.

     

    De cualquier manera, JavaScript se convirtió en un lenguaje basado en prototipos y, con diferencia, el más popular.

    Si tan solo JavaScript adoptara sus prototipos

    En el apuro entre la creación de JavaScript y su adopción masiva, hubo otras decisiones de diseño cuestionables en torno a los prototipos. En su libro, JavaScript: The Good Parts , Crockford explica las partes malas que rodean a JavaScript, como las variables globales y los malentendidos en torno a los prototipos.

    Como habrás notado, este artículo está inspirado en el libro de Crockford. Aunque no estoy de acuerdo con muchas de sus opiniones sobre las partes malas de JavaScript, es importante señalar que el libro se publicó en 2008, cuando ECMAScript 4 (ES4) era la versión estable de JavaScript. Han pasado muchos años desde su publicación y JavaScript ha cambiado significativamente durante ese tiempo. Las siguientes son características que creo que podrían haberse salvado del lenguaje si tan solo JavaScript hubiera adoptado sus prototipos.

    El thisvalor en diferentes contextos

    La thispalabra clave es otra de las cosas que JavaScript agregó para parecerse a Java. En Java, y en la programación orientada a objetos clásica en general, thisse refiere a la instancia actual en la que se invoca el método o constructor, simplemente eso. Sin embargo, en JavaScript, no teníamos sintaxis de clases hasta ES6, pero aun así heredamos la thispalabra clave. ¡Mi problema thises que pueden ser cuatro cosas diferentes dependiendo de dónde se invoque!

    1. thisEn el patrón de invocación de funciones

    Cuando thisse invoca dentro de una llamada de función, estará vinculado al objeto global. También estará vinculado al objeto global si se invoca desde el ámbito global.

    console.log(this); // windowfunction myFunction() { console.log(this);}myFunction(); // window

    En modo estricto y mediante el patrón de invocación de funciones, thisserá undefined.

    function getThis() { "use strict"; return this;}getThis(); // undefined

    2. thisEn el patrón de invocación de métodos

    Si hacemos referencia a una función como propiedad de un objeto, thisestará vinculada a su objeto principal.

    const dog = { name: "Sparky", bark: function () { console.log(`Woof, my name is ${this.name}.`); },};dog.bark(); // Woof, my name is Sparky.

    Las funciones de flecha no tienen su propio alcance this, sino que heredan thisde su alcance principal en el momento de la creación.

    const dog = { name: "Sparky", bark: () = { console.log(`Woof, my name is ${this.name}.`); },};dog.bark(); // Woof, my name is undefined.

    En este caso, thisestaba vinculado al objeto global en lugar de dog, por lo tanto this.namees undefined. Korean Beauty

    3. El patrón de invocación del constructor

    Si invocamos una función con el newprefijo, se creará un nuevo objeto vacío y thisestará vinculado a ese objeto.

    function Dog(name) { this.name = name; this.bark = function () { console.log(`Woof, my name is ${this.name}.`); };}const myDog = new Dog("Coco");myDog.bark(); // Woof, my name is Coco.

    También podríamos emplear thisel prototipo de la función para acceder a las propiedades del objeto, lo que podría darnos una razón más válida para usarlo.

     

    function Dog(name) { this.name = name;}Dog.prototype.bark = function () { console.log(`Woof, my name is ${this.name}.`);};const myDog = new Dog("Coco");myDog.bark(); // Woof, my name is Coco.

    4. El applypatrón de invocación

    Por último, cada función hereda un applymétodo del prototipo de función que toma dos parámetros. El primer parámetro es el valor que se vinculará thisdentro de la función, y el segundo es una matriz que se utilizará como parámetros de la función.

    // Bounding `this` to another objectfunction bark() { console.log(`Woof, my name is ${this.name}.`);}const myDog = { name: "Milo",};bark.apply(myDog); // Woof, my name is Milo.// Using the array parameterconst numbers = [3, 10, 4, 6, 9];const max = Math.max.apply(null, numbers);console.log(max); // 10

    Como puede ver, thispuede ser casi cualquier cosa y, en primer lugar, no debería estar en JavaScript. Enfoques como el uso bind()son soluciones a un problema que ni siquiera debería existir. Afortunadamente, thises completamente evitable en JavaScript moderno y puedes ahorrarte varios dolores de cabeza si aprendes a esquivarlo; una ventaja que los usuarios de la clase ES6 no pueden disfrutar.

    Crockford tiene una bonita anécdota sobre el tema en su libro:

    “Este es un pronombre demostrativo. El solo hecho de tener thisel idioma hace que sea más difícil hablar del mismo. Es como programar en pareja con Abbott y Costello”.

    "Pero si queremos crear un constructor de funciones, necesitaremos usar this". ¡No necesariamente! En el siguiente ejemplo, podemos crear un constructor de funciones que no se utiliza thisni newfunciona.

    function counterConstructor() { let counter = 0; function getCounter() { return counter; } function up() { counter += 1; return counter; } function down() { counter -= 1; return counter; } return { getCounter, up, down, };}const myCounter = counterConstructor();myCounter.up(); // 1myCounter.down(); // 0

    Acabamos de crear un constructor de funciones sin usar thiso new! Y viene con una sintaxis sencilla. Una desventaja que podrías ver es que los objetos creados a partir de counterConstructorno tendrán acceso a su prototipo, por lo que no podemos agregar métodos o propiedades desde counterConstructor.prototype.

    ¿Pero necesitamos esto? Por supuesto, necesitaremos reutilizar nuestro código, pero existen mejores enfoques que veremos más adelante.

    El newprefijo

    En JavaScript: The Good Parts , Crockford sostiene que no deberíamos usar el newprefijo simplemente porque no hay garantía de que recordaremos usarlo en las funciones previstas. Creo que es un error fácil de detectar y también se puede evitar capitalizando las funciones del constructor que desea utilizar new. Y hoy en día, los linters nos avisarán cuando llamemos a una función en mayúscula sin new, o viceversa.

     

    Un mejor argumento es simplemente que el uso newnos obliga a utilizar thisdentro de nuestras funciones o “clases” constructoras y, como vimos antes, es mejor evitarlas thisen primer lugar.

    Las múltiples formas de acceder a los prototipos

    Por las razones históricas que ya revisamos, podemos entender por qué JavaScript no adopta sus prototipos. Por extensión, no tenemos herramientas para mezclarnos con prototipos de forma tan sencilla como nos gustaría, sino más bien intentos tortuosos de manipular la cadena de prototipos. Las cosas empeoran cuando en la documentación podemos leer diferentes jergas en torno a los prototipos.

    La diferencia entre [[Prototype]], __proto__y.prototype

    Para que la experiencia de lectura sea más placentera, repasemos las diferencias entre estos términos.

    • [[Prototype]]es una propiedad interna que contiene una referencia al prototipo del objeto. Está entre corchetes dobles, lo que significa que normalmente no se puede acceder a él utilizando la notación normal.
    • __proto__puede referirse a dos posibles propiedades:
      • Puede hacer referencia a una propiedad de cualquier Object.prototypeobjeto que exponga la [[Prototype]]propiedad oculta. Está en desuso y tiene un mal rendimiento.
      • Puede hacer referencia a una propiedad opcional que podemos agregar al crear un objeto literal. El prototipo del objeto apuntará al valor que le damos.
    • .prototypees una propiedad exclusiva de funciones o clases (excluyendo funciones de flecha). Cuando se invoca usando el newprefijo, el prototipo del objeto instanciado apuntará al .prototype.

    Ahora podemos ver todas las formas en que podemos modificar prototipos en JavaScript. Después de revisarlos, notaremos que todos se quedan cortos al menos en algún aspecto.

    Usando la __proto__propiedad literal en la inicialización

    Al crear un objeto JavaScript usando literales de objeto, podemos agregar una __proto__propiedad. El objeto creado apuntará [[Prototoype]]al valor dado en __proto__. En un ejemplo anterior, los objetos creados a partir de nuestra función constructora no tenían acceso al prototipo del constructor. Podemos usar la __proto__propiedad en la inicialización para cambiar esto sin usar thiso new.

    function counterConstructor() { let counter = 0; function getCounter() { return counter; } function up() { counter += 1; return counter; } function down() { counter -= 1; return counter; } return { getCounter, up, down, __proto__: counterConstructor.prototype, };}

    La ventaja de vincular el prototipo del nuevo objeto al constructor de la función sería que podemos extender sus métodos desde el prototipo del constructor. Pero ¿de qué nos serviría si necesitáramos thisvolver a consumir?

    const myCounter = counterConstructor();counterConstructor.prototype.printDouble = function () { return this.getCounter() * 2;};myCounter.up(); // 1myCounter.up(); // 2myCounter.printDouble(); // 4

    Ni siquiera modificamos el countvalor interno sino que lo imprimimos doble. Por lo tanto, sería necesario un método de establecimiento para manipular su estado desde fuera de la declaración inicial del constructor de la función. Sin embargo, estamos complicando demasiado nuestro código ya que simplemente podríamos haber agregado un doublemétodo dentro de nuestra función.

     

    function counterConstructor() { let counter = 0; function getCounter() { return counter; } function up() { counter += 1; return counter; } function down() { counter -= 1; return counter; } function double() { counter = counter * 2; return counter; } return { getCounter, up, down, double, };}const myCounter = counterConstructor();myCounter.up(); // 1myCounter.up(); // 2myCounter.double(); // 4

    Usarlo __proto__es excesivo en la práctica.

    Es vital tener en cuenta que __proto__solo debe usarse al inicializar un nuevo objeto a través de un objeto literal. El uso del __proto__descriptor de acceso Object.prototype.__proto__cambiará el objeto [[Prototoype]]después de la inicialización, interrumpiendo muchas optimizaciones realizadas bajo el capó por los motores JavaScript. Es por eso Object.prototype.__proto__que tiene un mal rendimiento y está en desuso .

    Object.create()

    Object.create()devuelve un nuevo objeto cuyo [[Prototype]]será el primer argumento de la función. También tiene un segundo argumento que le permite definir propiedades adicionales para los nuevos objetos. Sin embargo, es más flexible y legible crear un objeto utilizando un objeto literal. Por lo tanto, su único uso práctico sería crear un objeto sin un prototipo, Object.create(null)ya que todos los objetos creados usando literales de objeto están automáticamente vinculados a Object.prototype.

    Object.setPrototypeOf()

    Object.setPrototypeOf()toma dos objetos como argumentos y mutará la cadena prototipo del primer argumento al segundo. Como vimos anteriormente, cambiar el prototipo de un objeto después de la inicialización no funciona bien, así que evítelo a toda costa.

    Encapsulación y clases privadas

    Mi último argumento contra las clases es la falta de privacidad y encapsulación. Tomemos, por ejemplo, la siguiente sintaxis de clase:

    class Cat { constructor(name) { this.name = name; } meow() { console.log(`Meow! My name is ${this.name}.`); }}const myCat = new Cat("Gala");myCat.meow(); // Meow! My name is Gala.myCat.name = "Pumpkin";myCat.meow(); // Meow! My name is Pumpkin.

    ¡No tenemos privacidad! Todas las propiedades son públicas. Podemos intentar mitigar esto con cierres:

    class Cat { constructor(name) { this.getName = function () { return name; }; } meow() { console.log(`Meow! My name is ${this.name}.`); }}const myCat = new Cat("Gala");myCat.meow(); // Meow! My name is undefined.

    Vaya, ahora this.nameestá undefinedfuera del alcance del constructor. Tenemos que cambiar this.namea this.getName()para que pueda funcionar correctamente.

     

    class Cat { constructor(name) { this.getName = function () { return name; }; } meow() { console.log(`Meow! My name is ${this.getName()}.`); }}const myCat = new Cat("Gala");myCat.meow(); // Meow! My name is Gala.

    Esto es con un solo argumento, por lo que puedes imaginar cuán innecesariamente repetitivo sería nuestro código cuantos más argumentos agreguemos. Además, aún podemos modificar nuestros métodos de objeto:

    myCat.meow = function () { console.log(`Meow! ${this.getName()} is a bad kitten.`);};myCat.meow(); // Meow! Gala is a bad kitten.

    ¡Podemos ahorrar e implementar una mejor privacidad si usamos nuestros propios constructores de funciones e incluso hacemos que nuestros métodos sean inmutables usando Object.freeze()!

    function catConstructor(name) { function getName() { return name; } function meow() { console.log(`Meow! My name is ${name}.`); } return Object.freeze({ getName, meow, });}const myCat = catConstructor("Loaf");myCat.meow(); // Meow! My name is Loaf.

    Y intentar modificar los métodos del objeto fallará silenciosamente.

    myCat.meow = function () { console.log(`Meow! ${this.getName()} is a bad Kitten.`);};myCat.meow(); // Meow! My name is Loaf.

    Y sí, estoy al tanto de la reciente propuesta de campos de clases privadas . Pero, ¿realmente necesitamos aún más sintaxis nueva cuando podríamos lograr lo mismo usando funciones de constructor personalizadas y cierres?

    Entonces, ¿clases o prototipos en JavaScript?

    En el libro más reciente de Crockford, Cómo funciona JavaScript ( PDF ), podemos ver una mejor opción que usar prototipos o clases para la reutilización de código: ¡Composición !

    Usar prototipos se siente como usar una función a medio terminar, mientras que las clases pueden llevar a jerarquías excesivamente complicadas e innecesarias (y también a "esto"). Afortunadamente, JavaScript es un lenguaje de múltiples paradigmas, y obligarnos a usar solo clases o prototipos para la reutilización del código es limitarnos con cuerdas imaginarias.

    Como dice Crockford en su libro más reciente:

    “[E]n lugar de lo mismo excepto que podemos obtener un poco de esto y un poco de aquello ”.

    — Douglas Crockford, Cómo funciona JavaScript

    En lugar de que un constructor de funciones o una clase herede de otro, podemos tener un conjunto de constructores y combinarlos cuando sea necesario para crear un objeto especializado.

    function speakerConstructor(name, message) { function talk() { return `Hi, mi name is ${name} and I want to tell something: ${message}.`; } return Object.freeze({ talk, });}function loudSpeakerConstructor(name, message) { const {talk} = speakerConstructor(name, message); function yell() { return talk().toUpperCase(); } return Object.freeze({ talk, yell, });}const mySpeaker = loudSpeakerConstructor("Juan", "You look nice!");mySpeaker.talk(); // Hi, my name is Juan and I want to tell something: You look nice!mySpeaker.yell(); // HI, MY NAME IS JUAN AND I WANT TO TELL SOMETHING: YOU LOOK NICE!

    Sin la necesidad de thisclases newy prototipos, logramos un constructor de funciones reutilizable con total privacidad y encapsulación.

    Conclusión

    Sí, JavaScript se creó en 10 días rápidamente; sí, estaba contaminado por el marketing; y sí, tiene un largo conjunto de piezas inútiles y peligrosas. Sin embargo, es un lenguaje hermoso e impulsa gran parte de la innovación que ocurre hoy en día en el desarrollo web, por lo que claramente ha hecho algo bueno.

    No creo que veamos un día en que los prototipos reciban las características que merecen, ni uno en el que dejemos de usar azúcar sintáctico clásico, pero podemos decidir evitarlos cuando sea posible.

    Desafortunadamente, esta decisión consciente de ceñirse a las partes buenas no es exclusiva de la programación orientada a objetos de JavaScript ya que, entre las prisas por






    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Cómo el marketing cambió la programación orientada a objetos en JavaScript

    Cómo el marketing cambió la programación orientada a objetos en JavaScript

    SmashingConf Friburgo 2024 Accesibilidad para diseñadores, con Stéphanie Walter Índice ¿Qué es la pro

    programar

    es

    https://aprendeprogramando.es/static/images/programar-como-el-marketing-cambio-la-programacion-orientada-a-objetos-en-javascript-1179-0.jpg

    2024-04-04

     

    Cómo el marketing cambió la programación orientada a objetos en JavaScript
    Cómo el marketing cambió la programación orientada a objetos en JavaScript

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20