CINXE.COM

<!DOCTYPE html><html lang="es" data-theme-enabled="1"><head><script>window.currentUser = null;</script><script>window.shopCurrency = "EUR";</script><script>window.localCurrency = "EUR";</script><script>window.countryCode = "us";</script><script>window.rateShopTo = {"EUR":1,"USD":1.078956993853182,"AMD":421.5874435300883};</script><title itemprop="name">Sintaxis básica de `class`</title><link href="/pack/styles.100020a0bc7cf13be729.css" rel="stylesheet"><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes, minimum-scale=1.0"><meta name="apple-mobile-web-app-capable" content="yes"><!-- chrome autotranslate is enabled only for "en" main version--><meta name="google" content="notranslate"><script>if (window.devicePixelRatio > 1) document.cookie = 'pixelRatio=' + window.devicePixelRatio + ';path=/;expires=Tue, 19 Jan 2038 03:14:07 GMT';</script><link href="//fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic" rel="stylesheet"><link rel="apple-touch-icon-precomposed" href="/img/favicon/apple-touch-icon-precomposed.png"><link rel="canonical" href="https://es.javascript.info/class"><meta name="msapplication-TileColor" content="#222A2C"><meta name="msapplication-TileImage" content="/img/favicon/tileicon.png"><link rel="icon" href="/img/favicon/favicon.png"><meta itemprop="image" content="https://es.javascript.info/img/site_preview_en_512x512.png"><meta property="og:title" content="Sintaxis básica de `class`"><meta property="og:image" content="https://es.javascript.info/img/site_preview_en_1200x630.png"><meta property="og:image:type" content="image/png"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta property="fb:admins" content="100001562528165"><meta name="twitter:card" content="summary"><meta name="twitter:title" content="Sintaxis básica de `class`"><meta name="twitter:site" content="@iliakan"><meta name="twitter:creator" content="@iliakan"><meta name="twitter:image" content="https://es.javascript.info/img/site_preview_en_512x512.png"><meta name="google-adsense-account" content="ca-pub-6204518652652613"><link rel="prev" href="/classes"><link rel="next" href="/class-inheritance"><script data-collect-dnt="true" async src="https://scripts.simpleanalyticscdn.com/latest.js"></script><script>window.GA_ID = "UA-2056213-15";</script><script>window.YANDEX_METRIKA_ID = 32184394;</script><script>{function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-2LWB61WGYJ")}</script> <script async src="https://www.googletagmanager.com/gtag/js?id=G-2LWB61WGYJ"></script><script>window.metrika={reachGoal:function(){}},window.yandex_metrika_callbacks=[function(){try{window.metrika=new Ya.Metrika({id:YANDEX_METRIKA_ID,webvisor:!0,clickmap:!0,params:{user:window.currentUser&&window.currentUser.id}}),metrika.trackLinks({delay:150}),window.addEventListener("error",function(r){window.metrika.reachGoal("JSERROR",{src:(r.filename||r.errorUrl)+": "+(r.lineno||r.errorLine),stack:r.stack||r.error&&r.error.stack,message:r.message})})}catch(r){}}];</script><script src="//mc.yandex.ru/metrika/watch.js" async></script><script>window.RECAPTCHA_ID = "6LfmLAEVAAAAAJMykMnf7aY8nkyTRmYi2ynx51R1";</script><script src="/pack/init.bfbd8f163f7371f4e613.js"></script><script src="/pack/head.f0ef0d46af631501e6b2.js" defer></script><meta property="og:title" content="Sintaxis básica de `class`"><meta property="og:type" content="article"><script src="/pack/tutorial.7c36b8184a7e0fd79e5d.js" defer></script><script src="/pack/footer.d61f12af96e4007b382f.js" defer></script></head><body class="no-icons"><script>window.fontTest();</script><div class="page-wrapper page-wrapper_sidebar_on"><!--[if IE]><div style="color:red;text-align:center">Lo sentimos, Internet Explorer no es compatible. Utilice un navegador más nuevo.</div><![endif]--><div class="sitetoolbar sitetoolbar_tutorial"><script>window.langs = [{"code":"ar","name":"Arabic"},{"code":"az","name":"Azerbaijani"},{"code":"bg","name":"Bulgarian"},{"code":"bn","name":"Bengali"},{"code":"bs","name":"Bosnian"},{"code":"ca","name":"Catalan"},{"code":"cs","name":"Czech"},{"code":"da","name":"Danish"},{"code":"de","name":"German"},{"code":"el","name":"Greek"},{"code":"en","name":"English"},{"code":"es","name":"Spanish"},{"code":"fa","name":"Persian (Farsi)"},{"code":"fi","name":"Finnish"},{"code":"fr","name":"French"},{"code":"he","name":"Hebrew"},{"code":"hi","name":"Hindi"},{"code":"hr","name":"Croatian"},{"code":"hu","name":"Hungarian"},{"code":"hy","name":"Armenian"},{"code":"id","name":"Indonesian"},{"code":"it","name":"Italian"},{"code":"ja","name":"Japanese"},{"code":"ka","name":"Georgian"},{"code":"kk","name":"Kazakh"},{"code":"km","name":"Central Khmer"},{"code":"ko","name":"Korean"},{"code":"ku","name":"Kurdish"},{"code":"ky","name":"Kyrgyz"},{"code":"lt","name":"Lithuanian"},{"code":"me","name":"Montenegrin"},{"code":"ml","name":"Malayalam"},{"code":"ms","name":"Malay"},{"code":"my","name":"Burmese"},{"code":"nl","name":"Dutch"},{"code":"no","name":"Norvegian"},{"code":"pa","name":"Punjabi"},{"code":"pl","name":"Polish"},{"code":"pt","name":"Portuguese"},{"code":"ro","name":"Romanian"},{"code":"ru","name":"Russian"},{"code":"si","name":"Sinhala"},{"code":"sk","name":"Slovak"},{"code":"sl","name":"Slovenian"},{"code":"sq","name":"Albanian"},{"code":"sr","name":"Serbian"},{"code":"ta","name":"Tamil"},{"code":"te","name":"Telugu"},{"code":"test","name":"Test"},{"code":"th","name":"Thai"},{"code":"tk","name":"Turkmen"},{"code":"tr","name":"Turkish"},{"code":"ug","name":"Uyghur"},{"code":"uk","name":"Ukrainian"},{"code":"ur","name":"Urdu"},{"code":"uz","name":"Uzbek"},{"code":"v2","name":"v2"},{"code":"vi","name":"Vietnamese"},{"code":"zh-hant","name":"Chinese Traditional"},{"code":"zh","name":"Chinese"}];</script><script>window.lang = "es";</script><div class="sitetoolbar__content"><div class="sitetoolbar__lang-switcher"><button class="sitetoolbar__dropdown-button" data-dropdown-toggler>ES</button><div class="sitetoolbar__dropdown-wrap"><div class="sitetoolbar__dropdown-body"><div class="sitetoolbar__lang-switcher-body"><div class="supported-langs supported-langs_toolbar"><div class="supported-langs__container"><ul class="supported-langs__list" style="height:200px"><li class="supported-langs__item"><a class="supported-langs__link" href="https://ar.javascript.info/class"><span class="supported-langs__brief">AR</span><span class="supported-langs__title">عربي</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://javascript.info/class"><span class="supported-langs__brief">EN</span><span class="supported-langs__title">English</span></a></li><li class="supported-langs__item supported-langs__item_current"><a class="supported-langs__link" href="https://es.javascript.info/class"><span class="supported-langs__brief">ES</span><span class="supported-langs__title">Español</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://fa.javascript.info/class"><span class="supported-langs__brief">FA</span><span class="supported-langs__title">فارسی</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://fr.javascript.info/class"><span class="supported-langs__brief">FR</span><span class="supported-langs__title">Français</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://id.javascript.info/class"><span class="supported-langs__brief">ID</span><span class="supported-langs__title">Indonesia</span></a></li></ul><ul class="supported-langs__list" style="height:200px"><li class="supported-langs__item"><a class="supported-langs__link" href="https://it.javascript.info/class"><span class="supported-langs__brief">IT</span><span class="supported-langs__title">Italiano</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://ja.javascript.info/class"><span class="supported-langs__brief">JA</span><span class="supported-langs__title">日本語</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://ko.javascript.info/class"><span class="supported-langs__brief">KO</span><span class="supported-langs__title">한국어</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://learn.javascript.ru/class"><span class="supported-langs__brief">RU</span><span class="supported-langs__title">Русский</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://tr.javascript.info/class"><span class="supported-langs__brief">TR</span><span class="supported-langs__title">Türkçe</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://uk.javascript.info/class"><span class="supported-langs__brief">UK</span><span class="supported-langs__title">Українська</span></a></li></ul><ul class="supported-langs__list" style="height:20px"><li class="supported-langs__item"><a class="supported-langs__link" href="https://zh.javascript.info/class"><span class="supported-langs__brief">ZH</span><span class="supported-langs__title">简体中文</span></a></li></ul></div><div class="supported-langs__text"><p>Queremos que este proyecto de código abierto esté disponible para personas de todo el mundo.</p> <p><a href="https://javascript.info/translate">Ayuda a traducir</a> el contenido de este tutorial a tu idioma!</p> </div></div></div></div></div></div><div class="sitetoolbar__logo-wrap"><a class="sitetoolbar__link sitetoolbar__link_logo" href="/"><img class="sitetoolbar__logo sitetoolbar__logo_normal" src="/img/sitetoolbar__logo_en.svg" width="200" alt="" role="presentation"/><img class="sitetoolbar__logo sitetoolbar__logo_normal sitetoolbar__logo_dark" src="/img/sitetoolbar__logo_en-white.svg" width="200" alt="" role="presentation"/><img class="sitetoolbar__logo sitetoolbar__logo_small" src="/img/sitetoolbar__logo_small_en.svg" width="70" alt="" role="presentation"/><img class="sitetoolbar__logo sitetoolbar__logo_small sitetoolbar__logo_dark" src="/img/sitetoolbar__logo_small_en-white.svg" width="70" alt="" role="presentation"/><script>Array.prototype.forEach.call(document.querySelectorAll("img.sitetoolbar__logo"),function(e){let t=document.createElement("object");t.type="image/svg+xml",t.className=e.className,t.style.cssText="left:0;top:0;position:absolute",t.onload=function(){t.onload=null,e.style.visibility="hidden"},t.data=e.src,e.parentNode.insertBefore(t,e)});</script></a></div><div class="sitetoolbar__nav-toggle-wrap"><button class="sitetoolbar__nav-toggle" type="button"></button></div><nav class="sitetoolbar__sections"><ul class="sitetoolbar__sections-list"></ul></nav><div class="sitetoolbar__right-button-wrap"><a class="sitetoolbar-right-button sitetoolbar-right-button_courses" href="/ebook"><span class="sitetoolbar-right-button__extra-text">Comprar</span>EPUB/PDF</a></div><div class="sitetoolbar__theme-switcher"><div class="theme-changer"><label class="theme-changer__label" for="theme-changer-input" data-tooltip="Change theme"><input class="theme-changer__input" type="checkbox" id="theme-changer-input" data-theme-changer="data-theme-changer"/><span class="theme-changer__icon theme-changer__icon_light-theme"></span><span class="theme-changer__icon theme-changer__icon_dark-theme"></span></label></div></div><div class="sitetoolbar__search-wrap"><div class="sitetoolbar__search-content"><button class="sitetoolbar__search-toggle" type="button"></button><form class="sitetoolbar__search" method="GET" action="/search"><div class="sitetoolbar__search-input"><div class="text-input"><input class="text-input__control" name="query" placeholder="Buscar en Javascript.info" required="required" type="text"/></div><button class="sitetoolbar__find" type="submit">Buscar</button></div></form></div></div></div><div class="tablet-menu"><div class="tablet-menu__line"><div class="tablet-menu__content"><form class="tablet-menu-search" action="/search/"><input class="tablet-menu-search__input" type="search" name="query" placeholder="Buscar en el tutorial" required="required"/><button class="tablet-menu-search__button" type="submit" name="type" value="articles">Buscar</button></form></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><a class="map" href="/tutorial/map" data-action="tutorial-map"><span class="map__text">Mapa del Tutorial</span></a></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><div class="theme-changer theme-changer_tablet-menu theme-changer_has-label"><label class="theme-changer__label" for="theme-changer-input-tablet" data-tooltip="Change theme"><input class="theme-changer__input" type="checkbox" id="theme-changer-input-tablet" data-theme-changer="data-theme-changer"/><span class="theme-changer__icon theme-changer__icon_light-theme"></span><span class="theme-changer__icon theme-changer__icon_dark-theme"></span><span class="theme-changer__label-text theme-changer__label-text_light-theme">Light theme</span><span class="theme-changer__label-text theme-changer__label-text_dark-theme">Dark theme</span></label></div></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><div class="share-icons"><span class="share-icons__title">Compartir</span><a class="share share_tw" href="https://twitter.com/share?url=https%3A%2F%2Fes.javascript.info%2Fclass" rel="nofollow"></a><a class="share share_fb" href="https://www.facebook.com/sharer/sharer.php?s=100&amp;p%5Burl%5D=https%3A%2F%2Fes.javascript.info%2Fclass" rel="nofollow"></a></div></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><select class="tablet-menu__nav input-select input-select input-select_small" onchange="if(this.value) window.location.href=this.value"><option value="https://ar.javascript.info/class">عربي</option><option value="https://javascript.info/class">English</option><option value="https://es.javascript.info/class" selected>Español</option><option value="https://fa.javascript.info/class">فارسی</option><option value="https://fr.javascript.info/class">Français</option><option value="https://id.javascript.info/class">Indonesia</option><option value="https://it.javascript.info/class">Italiano</option><option value="https://ja.javascript.info/class">日本語</option><option value="https://ko.javascript.info/class">한국어</option><option value="https://learn.javascript.ru/class">Русский</option><option value="https://tr.javascript.info/class">Türkçe</option><option value="https://uk.javascript.info/class">Українська</option><option value="https://zh.javascript.info/class">简体中文</option></select></div></div></div><progress class="tutorial-progress" data-sticky value="66" max="94" data-tooltip="Lección 66 de 94"></progress></div><div class="page page_sidebar_on page_inner_padding"><script>if(localStorage.noSidebar){document.querySelector(".page").classList.remove("page_sidebar_on");let e=document.querySelector(".page-wrapper");e&&e.classList.remove("page-wrapper_sidebar_on")}setTimeout(function(){document.querySelector(".page").classList.add("page_sidebar-animation-on")});</script><div class="page__inner"><main class="main main_width-limit"><header class="main__header"><div class="main__header-inner"><div class="main__header-group"><ol class="breadcrumbs"><li class="breadcrumbs__item breadcrumbs__item_home"><a class="breadcrumbs__link" href="/"><span class="breadcrumbs__hidden-text">Tutorial</span></a></li><li class="breadcrumbs__item" id="breadcrumb-1"><a class="breadcrumbs__link" href="/js"><span>El lenguaje JavaScript</span></a></li><li class="breadcrumbs__item" id="breadcrumb-2"><a class="breadcrumbs__link" href="/classes"><span>Clases</span></a></li><script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Tutorial","item":"https://es.javascript.info/"},{"@type":"ListItem","position":2,"name":"El lenguaje JavaScript","item":"https://es.javascript.info/js"},{"@type":"ListItem","position":3,"name":"Clases","item":"https://es.javascript.info/classes"}]}</script></ol><div class="updated-at" data-tooltip="Última actualización el 3 de julio de 2022"><div class="updated-at__content">3 de julio de 2022</div></div></div><h1 class="main__header-title">Sintaxis básica de `class`</h1></div></header><div class="content"><article class="formatted" itemscope itemtype="http://schema.org/TechArticle"><meta itemprop="name" content="Sintaxis básica de `class`"><div itemprop="author" itemscope itemtype="http://schema.org/Person"><meta itemprop="email" content="iliakan@gmail.com"><meta itemprop="name" content="Ilya Kantor"></div><div itemprop="articleBody"><blockquote class="quote"><div class="quote__i"><div class="quote__text"><p>En informática, una clase es una plantilla para la creación de objetos de datos según un modelo predefinido. Las clases se utilizan para representar entidades o conceptos, como los sustantivos en el lenguaje. Cada clase es un modelo que define un conjunto de variables —el estado—, y métodos apropiados para operar con dichos datos —el comportamiento—.</p> </div></div><footer class="quote__footer"> <cite class="quote__author">Wikipedia</cite> </footer></blockquote><p>En la práctica a menudo necesitamos crear muchos objetos del mismo tipo: usuarios, bienes, lo que sea.</p> <p>Como ya sabemos del capítulo <a href="/constructor-new">Constructor, operador &quot;new&quot;</a>, <code>new function</code> puede ayudar con eso.</p> <p>Pero en JavaScript moderno hay un constructor más avanzado, “class”, que introduce características nuevas muy útiles para la programación orientada a objetos.</p> <h2><a class="main__anchor" name="la-sintaxis-class" href="#la-sintaxis-class">La sintaxis “class”</a></h2><p>La sintaxis básica es:</p> <div id="kq3finp24" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class MyClass { // métodos de clase constructor() { ... } method1() { ... } method2() { ... } method3() { ... } ... }</code></pre> </div> </div> </div><p>Entonces usamos <code>new MyClass()</code> para crear un objeto nuevo con todos los métodos listados.</p> <p>El método <code>constructor()</code> es llamado automáticamente por <code>new</code>, así podemos inicializar el objeto allí.</p> <p>Por ejemplo:</p> <div id="q17drsm02m" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class User { constructor(name) { this.name = name; } sayHi() { alert(this.name); } } // Uso: let user = new User(&quot;John&quot;); user.sayHi();</code></pre> </div> </div> </div><p>Cuando se llama a <code>new User(&quot;John&quot;)</code>:</p> <ol> <li>Un objeto nuevo es creado.</li> <li>El <code>constructor</code> se ejecuta con el argumento dado y lo asigna a <code>this.name</code>.</li> </ol> <p>…Entonces podemos llamar a sus métodos, como <code>user.sayHi()</code>.</p> <div class="important important_warn"> <div class="important__header"><span class="important__type">No va una coma entre métodos de clase</span></div> <div class="important__content"><p>Un tropiezo común en desarrolladores principiantes es poner una coma entre los métodos de clase, lo que resulta en un error de sintaxis.</p> <p>La notación aquí no debe ser confundida con la sintaxis de objeto literal. Dentro de la clase no se requieren comas.</p> </div></div> <h2><a class="main__anchor" name="que-es-una-clase" href="#que-es-una-clase">¿Qué es una clase?</a></h2><p>Entonces, ¿qué es exactamente <code>class</code>? No es una entidad completamente nueva a nivel de lenguaje como uno podría pensar.</p> <p>Desvelemos la magia y veamos lo que realmente es una clase. Ayudará a entender muchos aspectos complejos.</p> <p>En JavaScript, una clase es un tipo de función.</p> <p>Veamos:</p> <div id="uvyi64mvoa" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:6,&quot;end&quot;:6}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class User { constructor(name) { this.name = name; } sayHi() { alert(this.name); } } // La prueba: User es una función alert(typeof User); // function</code></pre> </div> </div> </div><p>Lo que la construcción <code>class User {...}</code> hace realmente es:</p> <ol> <li>Crea una función llamada <code>User</code>, la que se vuelve el resultado de la declaración de la clase. El código de la función es tomado del método <code>constructor</code> (se asume vacío si no se escribe tal método).</li> <li>Almacena los métodos de clase, tales como <code>sayHi</code>, en <code>User.prototype</code>.</li> </ol> <p>Después de que el objeto <code>new User</code> es creado, cuando llamamos a sus métodos estos son tomados del prototipo, tal como se describe en el capítulo <a href="/function-prototype">F.prototype</a>. Así el objeto tiene acceso a métodos de clase.</p> <p>Podemos ilustrar el resultado de la declaración de <code>class User</code> como:</p> <figure><div class="image" style="width:486px"> <div class="image__ratio" style="padding-top:19.34156378600823%"></div> <object type="image/svg+xml" data="/article/class/class-user.svg" width="486" height="94" class="image__image" data-use-theme> <img src="/article/class/class-user.svg" alt="" width="486" height="94"> </object> </div></figure><p>Aquí el código para inspeccionarlo:</p> <div id="93pl1tsqsh" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class User { constructor(name) { this.name = name; } sayHi() { alert(this.name); } } // una clase es una función alert(typeof User); // function // ...o, más precisamente, el método constructor alert(User === User.prototype.constructor); // true // Los métodos están en User.prototype, por ejemplo: alert(User.prototype.sayHi); // el código del método sayHi // Hay exactamente dos métodos en el prototipo alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi</code></pre> </div> </div> </div><h2><a class="main__anchor" name="no-es-solamente-azucar-sintactica" href="#no-es-solamente-azucar-sintactica">No es solamente azúcar sintáctica</a></h2><p>A veces se dice que <code>class</code> es “azúcar sintáctica” (sintaxis que es diseñada para una lectura más fácil, pero que no introduce nada nuevo), porque en realidad podemos declarar lo mismo sin la palabra clave <code>class</code> en absoluto:</p> <div id="dsb4gorwze" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>// reescribiendo la clase User puramente con funciones // 1. Crear la función constructor function User(name) { this.name = name; } // un prototipo de función tiene la propiedad &quot;constructor&quot; por defecto, // así que no necesitamos crearla // 2. Agregar el método al prototipo User.prototype.sayHi = function() { alert(this.name); }; // Uso: let user = new User(&quot;John&quot;); user.sayHi();</code></pre> </div> </div> </div><p>El resultado de esta definición es el mismo. Así, efectivamente hay razones para que <code>class</code> sea considerada azúcar sintáctica para definir un constructor junto con sus métodos de prototipo.</p> <p>Aún así hay diferencias importantes.</p> <ol> <li> <p>Primero, una función creada por <code>class</code> es etiquetada por una propiedad interna especial <code>[[IsClassConstructor]]:true</code>. Entones no es exactamente lo mismo que crearla manualmente.</p> <p>El lenguaje verifica esa propiedad en varios lugares. Por ejemplo, a diferencia de las funciones regulares, esta debe ser llamada con <code>new</code>:</p> <div id="u6wurf4k95" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class User { constructor() {} } alert(typeof User); // function User(); // Error: El constructor de clase User no puede ser invocado sin 'new'</code></pre> </div> </div> </div><p>Además una representación string de un constructor de clase en la mayoría de los motores JavaScript comienzan con “class…”</p> <div id="l67yl4qrfb" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class User { constructor() {} } alert(User); // class User { ... }</code></pre> </div> </div> </div><p>Hay otras diferencias que veremos pronto.</p> </li> <li> <p>Los métodos de clase no son enumerables. La definición de clase establece la bandera <code>enumerable</code> a <code>false</code> para todos los métodos en <code>&quot;prototype&quot;</code>.</p> <p>Esto es bueno porque si hacemos <code>for..in</code> a un objeto usualmente no queremos sus métodos de clase.</p> </li> <li> <p>Las clases siempre asumen <code>use strict</code>. Todo el código dentro del constructor de clase está automáticamente en modo estricto.</p> </li> </ol> <p>Además la sintaxis de <code>class</code> brinda muchas otras características que exploraremos luego.</p> <h2><a class="main__anchor" name="expresion-de-clases" href="#expresion-de-clases">Expresión de clases</a></h2><p>Al igual que las funciones, las clases pueden ser definidas dentro de otra expresión, pasadas, devueltas, asignadas, etc.</p> <p>Aquí hay un ejemplo de una expresión de clase:</p> <div id="6tsvs8dpbl" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let User = class { sayHi() { alert(&quot;Hello&quot;); } };</code></pre> </div> </div> </div><p>Al igual que las expresiones de función, las expresiones de clase pueden tener un nombre.</p> <p>Si una expresión de clase tiene un nombre, este es visible solamente dentro de la clase.</p> <div id="ln176nsr4r" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:2,&quot;cols&quot;:[{&quot;start&quot;:17,&quot;end&quot;:24}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>// Expresiones de clase con nombre // (&quot;Named Class Expression&quot; no figura así en la especificación, pero es equivalente a &quot;Named Function Expression&quot;) let User = class MyClass { sayHi() { alert(MyClass); // El nombre de MyClass solo es visible dentro de la clase } }; new User().sayHi(); // Funciona, muestra la definición de MyClass alert(MyClass); // error, el nombre de MyClass no es visible fuera de la clase</code></pre> </div> </div> </div><p>Podemos inclusive crear clases dinámicamente “a pedido”, como esto:</p> <div id="d5v0ujr1ps" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function makeClass(phrase) { // declara una clase y la devuelve return class { sayHi() { alert(phrase); } }; } // Crea una nueva clase let User = makeClass(&quot;Hello&quot;); new User().sayHi(); // Hello</code></pre> </div> </div> </div><h2><a class="main__anchor" name="getters-setters" href="#getters-setters">Getters/setters</a></h2><p>Al igual que los objetos literales, las clases pueden incluir getters/setters, propiedades calculadas, etc.</p> <p>Aquí hay un ejemplo de <code>user.name</code>, implementado usando <code>get/set</code>:</p> <div id="owo3z97wr7" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:11,&quot;end&quot;:11},{&quot;start&quot;:7,&quot;end&quot;:7}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class User { constructor(name) { // invoca el setter this.name = name; } get name() { return this._name; } set name(value) { if (value.length &lt; 4) { alert(&quot;Nombre demasiado corto.&quot;); return; } this._name = value; } } let user = new User(&quot;John&quot;); alert(user.name); // John user = new User(&quot;&quot;); // Nombre demasiado corto.</code></pre> </div> </div> </div><p>Técnicamente, la declaración de clase funciona creando getters y setters en <code>User.prototype</code>.</p> <h2><a class="main__anchor" name="nombres-calculados" href="#nombres-calculados">Nombres calculados […]</a></h2><p>Aquí hay un ejemplo con un nombre de método calculado usando corchetes <code>[...]</code>:</p> <div id="xmk0pgbxh5" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:2,&quot;end&quot;:2}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class User { ['say' + 'Hi']() { alert(&quot;Hello&quot;); } } new User().sayHi();</code></pre> </div> </div> </div><p>Es una característica fácil de recordar porque se asemeja a la de los objetos literales.</p> <h2><a class="main__anchor" name="campos-de-clase-class-fields" href="#campos-de-clase-class-fields">Campos de clase (Class fields)</a></h2><div class="important important_warn"> <div class="important__header"><span class="important__type">Los navegadores viejos pueden necesitar polyfill</span></div> <div class="important__content"><p>Los campos de clase son un agregado reciente al lenguaje.</p> </div></div> <p>Antes, nuestras clases tenían solamente métodos.</p> <p>“Campos de clase” es una sintaxis que nos permite agregar una propiedad cualquiera.</p> <p>Por ejemplo, agreguemos la propiedad <code>name</code> a la clase <code>User</code>:</p> <div id="xxk74l55po" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:1,&quot;end&quot;:1}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class User { name = &quot;John&quot;; sayHi() { alert(`Hello, ${this.name}!`); } } new User().sayHi(); // Hello, John!</code></pre> </div> </div> </div><p>Así, simplemente escribimos “<property name> = <value>” en la declaración, y eso es todo.</p> <p>La diferencia importante de las propiedades definidas como “campos de clase” es que estas son establecidas en los objetos individuales, no compartidas en <code>User.prototype</code>:</p> <div id="alnry7ujbo" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:1,&quot;end&quot;:1}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class User { name = &quot;John&quot;; } let user = new User(); alert(user.name); // John alert(User.prototype.name); // undefined</code></pre> </div> </div> </div><p>También podemos asignar valores usando expresiones más complejas y llamados a función:</p> <div id="zucyeqm571" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:1,&quot;end&quot;:1}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class User { name = prompt(&quot;Name, please?&quot;, &quot;John&quot;); } let user = new User(); alert(user.name); // John</code></pre> </div> </div> </div><h3><a class="main__anchor" name="vinculacion-de-metodos-binding-usando-campos-de-clase" href="#vinculacion-de-metodos-binding-usando-campos-de-clase">Vinculación de métodos (binding) usando campos de clase</a></h3><p>Como se demostró en el capítulo <a href="/bind">Función bind: vinculación de funciones</a>, las funciones en JavaScript tienen un <code>this</code> dinámico. Este depende del contexto del llamado.</p> <p>Entonces si un método de objeto es pasado y llamado en otro contexto, <code>this</code> ya no será una referencia a su objeto.</p> <p>Por ejemplo, este código mostrará <code>undefined</code>:</p> <div id="moz2es1mie" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:12,&quot;end&quot;:12}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class Button { constructor(value) { this.value = value; } click() { alert(this.value); } } let button = new Button(&quot;hello&quot;); setTimeout(button.click, 1000); // undefined</code></pre> </div> </div> </div><p>Este problema es denominado “pérdida de <code>this</code>”.</p> <p>Hay dos enfoques para solucionarlo, como se discute en el capítulo <a href="/bind">Función bind: vinculación de funciones</a>:</p> <ol> <li>Pasar un contenedor o wrapper-function como: <code>setTimeout(() =&gt; button.click(), 1000)</code>.</li> <li>Vincular el método al objeto, por ejemplo en el constructor.</li> </ol> <p>Los campos de clase brindan otra sintaxis, bastante elegante:</p> <div id="8flxo80t2u" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:4,&quot;end&quot;:6}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="ejecutar" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="abrir en entorno controlado" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class Button { constructor(value) { this.value = value; } click = () =&gt; { alert(this.value); } } let button = new Button(&quot;hello&quot;); setTimeout(button.click, 1000); // hello</code></pre> </div> </div> </div><p>Un campo de clase <code>click = () =&gt; {...}</code> es creado para cada objeto. Hay una función para cada objeto <code>Button</code>, con <code>this</code> dentro referenciando ese objeto. Podemos pasar <code>button.click</code> a cualquier lado y el valor de <code>this</code> siempre será el correcto.</p> <p>Esto es especialmente práctico, en el ambiente de los navegadores, para los “event listeners”.</p> <h2><a class="main__anchor" name="resumen" href="#resumen">Resumen</a></h2><p>La sintaxis básica de clase se ve así:</p> <div id="n62bf9vbve" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class MyClass { prop = value; // propiedad constructor(...) { // constructor // ... } method(...) {} // método get something(...) {} // método getter set something(...) {} // método setter [Symbol.iterator]() {} // método con nombre calculado (aquí, symbol) // ... }</code></pre> </div> </div> </div><p><code>MyClass</code> es técnicamente una función (la que proveemos como <code>constructor</code>), mientras que los métodos, getters y setters son escritos en <code>MyClass.prototype</code>.</p> <p>En los siguientes capítulos aprenderemos más acerca de clases, incluyendo herencia y otras características.</p> </div></article><div class="tasks formatted"><h2 class="tasks__title" id="tasks"><a class="tasks__title-anchor main__anchor main__anchor main__anchor_noicon" href="#tasks">Tareas</a></h2><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#reescribir-como-class" name="reescribir-como-class">Reescribir como class</a></h3><a class="task__open-link" href="/task/rewrite-to-class" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="Qué tan importante es la tarea, del 1 a 5">importancia: 5</span></div><div class="task__content"><div class="task__formatted"><p>La clase <code>Clock</code> (ver en el sandbox) está escrita en estilo funcional. Reescríbela en sintaxis de clase.</p> <p>P.D. El reloj anda en la consola, ábrela para verlo.</p> <p><a href="https://plnkr.co/edit/XLBhMQDHZiRov1mx?p=preview" target="_blank" data-plunk-id="XLBhMQDHZiRov1mx">Abrir un entorno controlado para la tarea.</a></p></div><button class="task__solution" type="button">solución</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="8myk9kqmdc" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>class Clock { constructor({ template }) { this.template = template; } render() { let date = new Date(); let hours = date.getHours(); if (hours &lt; 10) hours = '0' + hours; let mins = date.getMinutes(); if (mins &lt; 10) mins = '0' + mins; let secs = date.getSeconds(); if (secs &lt; 10) secs = '0' + secs; let output = this.template .replace('h', hours) .replace('m', mins) .replace('s', secs); console.log(output); } stop() { clearInterval(this.timer); } start() { this.render(); this.timer = setInterval(() =&gt; this.render(), 1000); } } let clock = new Clock({template: 'h:m:s'}); clock.start();</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/oNXQRJLbdmODNcr8?p=preview" target="_blank" data-plunk-id="oNXQRJLbdmODNcr8">Abrir la solución en un entorno controlado.</a></p></div></div><button class="close-button task__answer-close" type="button" title="cerrar"></button></div></div></div></div></div></div><div class="page__nav-wrap"><a class="page__nav page__nav_prev" href="/classes" data-tooltip="Clases"><span class="page__nav-text"><span class="page__nav-text-shortcut"></span></span><span class="page__nav-text-alternate">Lección anterior</span></a><a class="page__nav page__nav_next" href="/class-inheritance" data-tooltip="Herencia de clase"><span class="page__nav-text"><span class="page__nav-text-shortcut"></span></span><span class="page__nav-text-alternate">Próxima lección</span></a></div><div class="article-tablet-foot tablet-only"><div class="article-tablet-foot__layout"><div class="share-icons"><span class="share-icons__title">Compartir</span><a class="share share_tw" href="https://twitter.com/share?url=https%3A%2F%2Fes.javascript.info%2Fclass" rel="nofollow"></a><a class="share share_fb" href="https://www.facebook.com/sharer/sharer.php?s=100&amp;p%5Burl%5D=https%3A%2F%2Fes.javascript.info%2Fclass" rel="nofollow"></a></div><div class="article-tablet-foot__map"><a class="map" href="/tutorial/map" data-action="tutorial-map"><span class="map__text">Mapa del Tutorial</span></a></div></div></div><div class="comments formatted" id="comments"><div class="comments__header"><h2 class="comments__header-title"><a href="#comments" name="comments">Comentarios</a></h2><div class="comments__read-before"><span class="comments__read-before-link">lea esto antes de comentar…</span><div class="comments__read-before-popup"><div class="comments__read-before-popup-i"><ul><li>Si tiene sugerencias sobre qué mejorar, por favor <a href="https://github.com/javascript-tutorial/en.javascript.info/issues/new">enviar una propuesta de GitHub</a> o una solicitud de extracción en lugar de comentar.</li><li>Si no puede entender algo en el artículo, por favor explique.</li><li>Para insertar algunas palabras de código, use la etiqueta <code>&lt;code&gt;</code>, para varias líneas – envolverlas en la etiqueta <code>&lt;pre&gt;</code>, para más de 10 líneas – utilice una entorno controlado (sandbox) (<a href='https://plnkr.co/edit/?p=preview'>plnkr</a>, <a href='https://jsbin.com'>jsbin</a>, <a href='http://codepen.io'>codepen</a>…)</li></ul></div></div></div></div><div id="disqus_thread"></div><script>var disqus_config = function() { if (!this.page) this.page = {}; Object.assign(this.page, {"url":"https:\/\/es.javascript.info\/class","identifier":"\/class"}); };</script><script>var disqus_shortname = "es-javascript-info";</script><script>var disqus_enabled = true;</script></div></script></main></div><div class="sidebar page__sidebar sidebar sidebar_sticky-footer"><button class="sidebar__toggle" data-sidebar-toggle></button><a class="map" href="/tutorial/map" data-action="tutorial-map" data-tooltip="Mapa del Tutorial"></a><div class="sidebar__inner"><div class="sidebar__content"><div class="sidebar__section"><h4 class="sidebar__section-title">Capítulo</h4><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="/classes">Clases</a></li></ul></nav></div><div class="sidebar__section"><h4 class="sidebar__section-title">Navegación de lección</h4><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="#la-sintaxis-class">La sintaxis “class”</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#que-es-una-clase">¿Qué es una clase?</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#no-es-solamente-azucar-sintactica">No es solamente azúcar sintáctica</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#expresion-de-clases">Expresión de clases</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#getters-setters">Getters/setters</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#nombres-calculados">Nombres calculados […]</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#campos-de-clase-class-fields">Campos de clase (Class fields)</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#resumen">Resumen</a></li></ul></nav></div><div class="sidebar__section"><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="#tasks">Tareas (1)</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#comments">Comentarios</a></li></ul></nav></div><div class="sidebar__section"><div class="sidebar__section-title">Compartir</div><a class="share share_tw sidebar__share" href="https://twitter.com/share?url=https%3A%2F%2Fes.javascript.info%2Fclass" rel="nofollow"></a><a class="share share_fb sidebar__share" href="https://www.facebook.com/sharer/sharer.php?s=100&amp;p[url]=https%3A%2F%2Fes.javascript.info%2Fclass" rel="nofollow"></a></div><div class="sidebar__section"><a class="sidebar__link" href="https://github.com/javascript-tutorial/es.javascript.info/blob/master/1-js/09-classes/01-class" rel="nofollow">Editar en GitHub</a></div></div></div></div></div></div><div class="page-footer"><ul class="page-footer__list"><li class="page-footer__item page-footer__item_copy">©&nbsp;2007—2025&nbsp; Ilya Kantor</li><li class="page-footer__item page-footer__item_about"><a class="page-footer__link" href="/about">acerca del proyecto</a></li><li class="page-footer__item page-footer__item_contact"><a class="page-footer__link" href="/about#contact-us">contáctenos</a></li></ul></div></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10