Propiedades y métodos de objetos en JavaScript | Nicolás Garzón
Las propiedades guardan información dentro de un objeto. Los métodos son propiedades cuyo valor es una función y representan comportamiento.
JavaScript
Copiar const account = {
owner : "Nicolás" ,
balance : 100 ,
deposit ( amount ) {
this . balance += amount;
} ,
} ; JavaScript
Copiar const product = {
price : 120 ,
} ;
price es la clave.
120 es el valor.
La unión de ambos forma una propiedad.
Una propiedad no crea una variable independiente.
JavaScript
Copiar console. log ( product. price) ;
console. log ( price) ; Son las que pertenecen directamente al objeto.
JavaScript
Copiar const user = {
name : "Nicolás" ,
} ;
Object. hasOwn ( user, "name" ) ;
Object. hasOwn ( user, "toString" ) ; Para código moderno, Object.hasOwn suele ser más seguro que llamar directamente:
JavaScript
Copiar user. hasOwnProperty ( "name" ) ; Un objeto puede sobrescribir hasOwnProperty o no heredarlo.
JavaScript
Copiar const baseUser = {
role : "viewer" ,
} ;
const user = Object. create ( baseUser) ;
user. name = "Nicolás" ; JavaScript
Copiar user. name;
user. role; JavaScript
Copiar "role" in user;
Object. hasOwn ( user, "role" ) ; El operador in revisa toda la cadena de prototipos. Object.hasOwn revisa solo el objeto.
JavaScript
Copiar Object. keys ( user) ;
Object. values ( user) ;
Object. entries ( user) ; Estos métodos incluyen propiedades:
Propias.
Enumerables.
Con clave string.
JavaScript
Copiar Reflect. ownKeys ( user) ; Reflect.ownKeys devuelve todas las claves propias: strings y symbols, enumerables o no.
JavaScript define un orden para las claves propias:
Claves que parecen índices enteros, en orden ascendente.
Otras claves string, según su inserción.
Symbols, según su inserción.
JavaScript
Copiar const example = {
20 : "twenty" ,
3 : "three" ,
name : "example" ,
} ;
Object. keys ( example) ; Aunque existe este orden, no uses un objeto cuando necesitas una secuencia con semántica de lista.
JavaScript
Copiar const calculator = {
add ( first, second ) {
return first + second;
} ,
} ; JavaScript
Copiar function add ( first, second ) {
return first + second;
}
const calculator = {
add,
} ; JavaScript
Copiar const calculator = {
add : function ( first, second ) {
return first + second;
} ,
} ; Las tres guardan una función. Pueden existir diferencias pequeñas en nombres internos y comportamiento sintáctico, pero para este caso representan un método callable.
JavaScript
Copiar const user = {
name : "Nicolás" ,
greet : ( ) => {
return ` Hello, ${ this . name} ` ;
} ,
} ; Una arrow function no obtiene this del objeto. Captura el this exterior, por lo que no suele ser adecuada cuando el método necesita al receptor.
JavaScript
Copiar const user = {
name : "Nicolás" ,
greet ( ) {
return ` Hello, ${ this . name} ` ;
} ,
} ; La nota this explicará la regla completa.
JavaScript
Copiar const user = {
name : "Nicolás" ,
greet ( ) {
return ` Hello, ${ this . name} ` ;
} ,
} ;
const greet = user. greet;
greet ( ) ; Extraer el método cambia la forma de invocación. Ya no se llama como user.greet(), así que puede perder su receptor.
Esto no ocurre porque la función haya olvidado dónde estaba guardada; ocurre porque this se decide al llamar una función tradicional.
Un getter parece una propiedad al leerlo, pero ejecuta una función.
JavaScript
Copiar const rectangle = {
width : 10 ,
height : 5 ,
get area ( ) {
return this . width * this . height;
} ,
} ;
rectangle. area; Un setter se ejecuta al asignar.
JavaScript
Copiar const user = {
firstName : "Nicolás" ,
lastName : "Garzón" ,
set fullName ( value ) {
const [ firstName, lastName] = value. split ( " " ) ;
this . firstName = firstName;
this . lastName = lastName;
} ,
} ;
user. fullName = "Ana López" ; Los accessors pueden ser útiles, pero también ocultan trabajo detrás de una lectura o asignación aparentemente simple. Evita operaciones costosas o efectos inesperados dentro de ellos.
Una propiedad tiene atributos internos además de su valor.
JavaScript
Copiar Object. getOwnPropertyDescriptor ( product, "price" ) ; Para una propiedad de datos, los atributos principales son:
value: valor actual.
writable: si puede cambiarse mediante asignación.
enumerable: si aparece en enumeraciones comunes.
configurable: si puede eliminarse o redefinirse.
JavaScript
Copiar const configuration = { } ;
Object. defineProperty ( configuration, "version" , {
value : "1.0.0" ,
writable : false ,
enumerable : true ,
configurable : false ,
} ) ; En modo estricto, intentar reasignarla produce un error. Fuera de modo estricto puede fallar silenciosamente.
Una propiedad creada normalmente suele ser:
Texto
Copiar writable: true
enumerable: true
configurable: trueUna propiedad creada con Object.defineProperty utiliza false como valor por defecto para esos flags cuando se omiten.
JavaScript
Copiar Object. defineProperty ( configuration, "internal" , {
value : true ,
} ) ; internal no será writable, enumerable ni configurable.
Los getters y setters utilizan descriptores con get y set, no con value y writable.
JavaScript
Copiar Object. getOwnPropertyDescriptor ( rectangle, "area" ) ; No puedes definir en el mismo descriptor value y get, porque representan tipos distintos de propiedad.
JavaScript
Copiar const copy = {
... source,
} ; Spread lee valores enumerables y crea propiedades normales nuevas. No conserva necesariamente getters, setters ni atributos especiales.
Para copiar descriptores:
JavaScript
Copiar const copy = Object. defineProperties (
{ } ,
Object. getOwnPropertyDescriptors ( source) ,
) ; Aun así, la copia continúa siendo superficial respecto a objetos anidados.
JavaScript
Copiar const inspect = Symbol ( "inspect" ) ;
const service = {
name : "orders" ,
[ inspect] ( ) {
return ` Service: ${ this . name} ` ;
} ,
} ; Los symbols son útiles para protocolos y metadatos que no deberían chocar con claves string normales.
JavaScript
Copiar const order = {
items : [
{ price : 20 , quantity : 2 } ,
{ price : 10 , quantity : 1 } ,
] ,
get total ( ) {
return this . items. reduce (
( sum, item ) => sum + item. price * item. quantity,
0 ,
) ;
} ,
} ; total siempre se calcula desde items, por lo que no puede quedar desactualizado como una propiedad duplicada.
Si la operación fuera costosa o pudiera fallar, un método como calculateTotal() comunicaría mejor que ocurre trabajo.
Confundir una propiedad con una variable del scope.
Usar in cuando solo interesan propiedades propias.
Suponer que Object.keys incluye symbols o propiedades no enumerables.
Usar una arrow function como método que necesita this.
Extraer un método y esperar que conserve automáticamente su receptor.
Ocultar efectos costosos dentro de getters.
Pensar que spread conserva descriptores completos.
Omitir flags en Object.defineProperty esperando que sean true.
Modificar prototipos nativos para agregar métodos personales.
Los métodos son propiedades cuyo valor es una función.
Object.hasOwn distingue propiedades propias de heredadas.
in revisa también la cadena de prototipos.
Object.keys, values y entries trabajan con propiedades propias enumerables con clave string.
Los getters y setters son propiedades de acceso.
Los descriptores controlan escritura, enumeración y configuración.
Spread copia valores enumerables, no la identidad completa de los descriptores.
La forma de invocar un método afecta su this.
¿Qué resultados producen las comprobaciones?
JavaScript
Copiar const base = { role : "viewer" } ;
const user = Object. create ( base) ;
user. name = "Nicolás" ;
console. log ( "role" in user) ;
console. log ( Object. hasOwn ( user, "role" ) ) ;
console. log ( Object. keys ( user) ) ; Respuesta Imprime true, false y ["name"]. role es accesible, pero pertenece al prototipo y no al objeto directamente.
Destructuring de objetos muestra cómo extraer propiedades y crear bindings locales con nombres, valores por defecto y patrones anidados.