Crea una cuenta o inicia sesión

¡Continúa aprendiendo sin ningún costo! Únete y comienza a potenciar tu carrera

Object.defineProperty

4/19
Recursos

Aportes 26

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Object.defineProperty

Con esta propiedad se pueden definir nuevas propiedades a nuestro objeto. Así mismo, se puede configurar ciertas características de la propiedad tales como:

  • Configurable: Esta indica si la propiedad puede ser borrada o eliminada
  • Enumerable: Indica si la propiedad puede ser mostrada en la enumeración de las mismas. Existen ciertos métodos que toman como referencia este valor para mostrar la propiedad
  • Writable: Esta indica si la propiedad puede ser modificada con el operador de asignación (=)
const person = {
  userName: 'zajithcorro',
  age: 26,
  approvedCourses: ['Curso Profesional de Git y Github'],
  addApprovedCourse (course) {
    console.log(this)
    this.approvedCourses.push(course);
  }
}
Object.defineProperty(person, "mail", {
    value: "[email protected]",
    writable: false,
    enumerable: true,
    configurable: true
})

Object.defineProperty(person, "twitter", {
    value: "zajithcorro",
    writable: true,
    enumerable: false,
    configurable: true
})

Object.defineProperty(person, "platziPoints", {
    value: 7500,
    writable: true,
    enumerable: true,
    configurable: false
})

Object.defineProperty(person, "gender", {
    value: "male",
    writable: false,
    enumerable: false,
    configurable: false
})

Si queremos modificar un propiedad que tienen writable: false no permitirá que su valor sea modificado

person.mail // '[email protected]'
person.mail = '[email protected]' // '[email protected]'
person.mail // // '[email protected]'

Object.keys solo muestra las propiedades que tienen enumerable: true. A diferencia de Object.getOwnPropertyNames que muestra todas las propiedades

Object.keys(person) // [ 'userName', 'age', 'approvedCourses', 'addApprovedCourse', 'mail', 'platziPoints' ]
Object.getOwnPropertyNames(person) // [ 'userName', 'age', 'approvedCourses', 'addApprovedCourse', 'mail', 'twitter', 'platziPoints', 'gender' ]

Si queremos eliminar propiedad que tienen configurable: false no permitirá que sea borrada del objeto.

delete person.platziPoints // false
delete person.userName // true

Object.freeze()

Este método congela un objeto que sea pasado. Es decir:

  • Impide que se le agreguen nuevas propiedades
  • Impide que sean eliminas propiedades ya existentes
  • Impide que sus las propiedades internas (writable, enumerable y configurable) sean modificadas
const person = {
  userName: 'zajithcorro',
  age: 26,
  approvedCourses: ['Curso Profesional de Git y Github'],
  addApprovedCourse (course) {
    console.log(this)
    this.approvedCourses.push(course);
  }
}

Object.freeze(person)

person.mail = '[email protected]'
Object.keys(person) // [ 'userName', 'age', 'approvedCourses', 'addApprovedCourse' ]

person.age = 27
person.age // 26

delete person.userName // false

Object.seal()

Este método sella un objeto que sea pasada. Es decir:

  • Impide que nuevas propiedades sean agregadas
  • Cambia en todas las propiedades configurable: false, con lo que impide que sean borradas
  • Las propiedades aún puede ser modificadas, ya que writable esta true
const person = {
  userName: 'zajithcorro',
  age: 26,
  approvedCourses: ['Curso Profesional de Git y Github'],
  addApprovedCourse (course) {
    console.log(this)
    this.approvedCourses.push(course);
  }
}

Object.seal(person)

person.mail = '[email protected]'
Object.keys(person) // [ 'userName', 'age', 'approvedCourses', 'addApprovedCourse' ]

delete person.userName // false

person.age = 27
person.age // 27

A no ser que hagas librerías, no es recomendable usar defineProperty ni getOwnPropertyNames
Why is extending native objects a bad practice?
Lo mejor para ti y tu equipo es usar los objetos de la forma más simple.
Si quieres tener información que no cambie nunca probablemente lo que necesitas son Symbols

Solo para complementar, al usar Object.freeze() y/o Object.seal(), aparte de no poder borrar propiedades, tampoco se podrán agregar nuevas. Además, al usar alguno de esos 2 métodos, no habrá forma de volver atrás; es decir, si haces freeze o seal sobre un objeto, no podrás unfreeze o unseal luego 😅 (tendrías que crear una copia que permita volverle a hacer cambios o algo así).

RESUMEN

Object.defineProperty y enumerable, writable y configurable

Con Object.defineProperty() podemos crear nuevas propiedades con la posibilidad de ver y editar enumerable, writable y configurable, que son opciones que podemos activar (o no) en las propiedades que creamos.

1. Enumerable (por defecto false)

  • true: Lista las propiedades con Object.keys
  • false: NO lista las propiedades con Object.keys (pero sí en getOwnPropertyNames())

2. Writable (por defecto false)

  • true: Permite modificar el valor con el operador de asignación.
  • false: NO permite modificar el valor con el operador de asignación.

3. Configurable (por defecto false)

  • true: Permite eliminar la propiedad.
  • false: NO permite eliminar la propiedad.

Más métodos estáticos

Object.seal()

Pone todas las propiedades en configurable: false
Ej: Object.seal(juan);

Object.freeze()

Pone todas las propiedades en writable: false
Ej: Object.freeze(juan);

¡Espero que sea útil! 😄

Cuando en typescript uso public o private esta usando estas propiedades por detras?

Esto si esta bien interesante 😮

.
La verdad en aplicaciones no tan complejas del día a día me cuesta encontrarle utilidad, (mejor uso TS xd) 💙
Sin embargo si que es muy bonito conocer como hace las cosas el lenguaje internamente. 💛

Object.defineProperty(Miguel, "prueba-NASA", {
  value: "👽",
  enumerable: true,
  //* Solo se muestra con getOwnPropertyDescriptors, pero no con Keys si tiene valor false
  writable: true,
  //* Lo podemos editar si tiene true, pero no si tiene false
  configurable: true
  //* Lo podemos borrar si tiene true, pero no si tiene false
});

console.table(Object.getOwnPropertyDescriptors(Miguel));

//* Object.seal(Miguel); //* Prevents the modification of attributes of existing properties, and prevents the addition of new properties.
//* Object.freeze(Miguel); //* Prevents the modification of existing property attributes and values, and prevents the addition of new properties.

Este tema puede llegar a ser un poco difícil de entender a la primera, recomiendo revisar la documentación de MDN

Object.defineProperty()

El método estático Object.defineProperty() define una nueva propiedad sobre un objeto, o modifica una ya existente, y devuelve el objeto modificado.

syntaxis

Object.defineProperty(obj,prop,descriptor)

parametros

  • obj: Objeto sobre el cual se define la propiedad
  • prop: El nombre de la propiedad a ser definida o modificada.
  • descriptor: el descriptor de la propiedad que está siendo definida o modificada.

Este método nos permite modificar el comportamiento por defecto de nuestro objeto.

Existen dos tipos de descriptores:

  1. Data descriptors

    • value: El valor de la propiedad
    • writable: Si la propiedad es escribible o no
    • enumerable: Si la propiedad es enumerable o no
    • configurable: Si la propiedad es configurable o no
      Un descriptor de satos define una propiedad que tiene un valor, el cuál puede ser modificado o no
  2. Accessor descriptors
    además de usar el value, writable,enumerable, configurable de los descriptores de datos, también pueden definirse los siguientes atributos:

    • get: Una función cuyo valor retornado será el que se use como valor de la propiedad
    • set: Una función que recibe como único argumento el nuevo valor que se desea asignar a la propiedad y devuelve el valor que se almacenará finalmente en el objeto.

nota un descriptor debe ser uno de estos dos tipos, no pueden ser ambos.

Estas opciones también pueden heredarse; es decir, las opciones de una propiedad han podido establecer en el prototipo de una clase de la que hereda el objeto.
Podemos fijar estos vaores con el Object.prototype() y object.feeze()

Object.defineProperty(object,'key',{
    __proto__:null,
    value:'static'
    //no aceptar propiedades heredadas
    //no enumerable
    //no configurable
    //no modificable
    //Como opciones por defecto
});

///definiendo todo explícitamente
Object.defineProperty(obj,'key',{
    enumerable:false,
    configurable:false,
    writable:false,
    value:'static'
})
//Reciclando el mismo objeto.
function withValue(value) {
  var d = withValue.d || (
    withValue.d = {
      enumerable: false,
      writable: false,
      configurable: false,
      value: null
    }
  );
  d.value = value;
  return d;
}
//..y..
Object.defineProperty(obj,'key',withValue('static'));

Object.freeze || Object(Object.prototype);
  • Object.freeze previene el añadir o eliminar del prototipo de objeto las propiedades (value,get,set,enuemerable,writable, configurable)
  • Object.seal() Evita que las propiedades se puedan borrar o modificar, pero permite que se puedan añadir nuevas propiedades
  • Encapsilamiento: Es la limitación, acceso y módificación de nuestros métodos y atributos en nuestras clases y prototipos

Object.defineProperty(object, newProp, Properties)

El método estático Object.defineProperty() define una nueva propiedad sobre un objeto, o modificar una ya existente, y devuelve el objeto modificado.
·
Object.seal() - JavaScript | MDN Configura todas las propiedades para que sea imposible borrarlas.
Object.freeze() - JavaScript | MDN Configura todas las propiedades para que sea imposible borrarlas y editarlas ó sobreescribirlas.
·

  • Estas son propiedades para mejorar el encapsulamiento de nuestros métodos y atributos en nuestros objetos. Limitar el acceso y modificación a nuestras clases y prototipos, y así se evitan muchos inconvenientes.

Con estos nuevos métodos estáticos del superprototipo .Object aprendidos a mejorar uno de los pilares de la Programación Orientada a Objetos “Encapsulamieto” para volverlas un poco más seguras.

Encapsulamiento mamalón

Yo lo usaria para que no cambiaran mi codigo xD

creo que hubo un cambio reciente en este metodo porque estuve rato tratando de ver porque me decia undefined y consegui esta documentacion

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor

el metodo recibe 2 argumentos, el objeto y la propiedad de la cual quiero saber la descripcion.

si solo le doy el objeto, me retorna “Undefined”

Object.defineProperty

Código Clase

const carlos = {
    name: 'carlito',
    age: 20,
    approvedCourses: ["Curso 1"],
    
    addCourse(newCourse) {
        console.log("This", this);
        console.log("This.approvedCourses", this.approvedCourses);
        this.approvedCourses.push(newCourse); // this hace referencia al objeto carlos
    },
};

// parte 1
// Object.defineProperty(juan, "navigator", {
//     value: "Chrome",
//     enumerable: false,
//     writable: true,
//     configurable: true,
// });

// Object.defineProperty(juan, "editor", {
//     value: "VSCode",
//     enumerable: true,
//     writable: false,
//     configurable: true
// });

// Object.defineProperty(juan, "terminal", {
//     value: "WSL",
//     enumerable: true,
//     writable: true,
//     configurable: false,
// });

// Object.defineProperty(juan, "pruebNasa", {
//     value: "marcianito",
//     enumerable: false,
//     writable: false,
//     configurable: false,
// });

// parte 2
Object.seal(carlos) // configurable se vuelve false
// Object.freeze(juan) // configurable y writable se vuelven false

console.log(Object.getOwnPropertyDescriptors(carlos));

Object.defineProperty()

Este método nos permite modificar el comportamiento por defecto de las propiedades. Es decir, nos permite definir una propiedad como no enumerable, no modificable o incluso evitar que pueda ser eliminada del objeto.

value

El valor asociado a la propiedad. Puede ser cualquier tipo valido de JavaScript  (number, object, function, etc).Por defecto es undefined.

enumerable

true si y solo si dicha propiedad se muestra durante la enumeración de las propiedades del objeto correspondiente.Por defecto es false.

writable

true Indica si el valor de la propiedad puede modificarse con el  operador de asignación (en-US).Defaults to false.

configurable

true si y solo si el tipo de descriptor de propiedad puede modificarse y si la propiedad puede ser eliminada del correspondiente objeto.Por defecto es false.

Object.seal()

El método Object.freeze() impide que se puedan eliminar las propiedades

Object.freeze()

El método Object.freeze() impide que se le agreguen nuevas propiedades e impide que se puedan eliminar las propiedades ya existentes

Encapsular es para mejorar seguridad, así que quizas estos temas vengan mejor cuando se haga un curso de seguridad de software talvez.

Yo creo que los métodos son principalmente para la seguridad de la página porque yo intente usar el Object.defineProperty en la consola del navegador para cambiar los valores y el de configurable no me dejo. Siempre tuve esa duda de como proteger datos en JS porque es código abierto, por eso me gusto esta clase

Object.defineProperty()

El método estático Object.defineProperty() define una nueva propiedad sobre un objeto, o modifica una ya existente, y devuelve el objeto modificado.

syntaxis

Object.defineProperty(obj,prop,descriptor)

parametros

  • obj: Objeto sobre el cual se define la propiedad
  • prop: El nombre de la propiedad a ser definida o modificada.
  • descriptor: el descriptor de la propiedad que está siendo definida o modificada.

Este método nos permite modificar el comportamiento por defecto de nuestro objeto.

Existen dos tipos de descriptores:

  1. Data descriptors

    • value: El valor de la propiedad
    • writable: Si la propiedad es escribible o no
    • enumerable: Si la propiedad es enumerable o no
    • configurable: Si la propiedad es configurable o no
      Un descriptor de satos define una propiedad que tiene un valor, el cuál puede ser modificado o no
  2. Accessor descriptors
    además de usar el value, writable,enumerable, configurable de los descriptores de datos, también pueden definirse los siguientes atributos:

    • get: Una función cuyo valor retornado será el que se use como valor de la propiedad
    • set: Una función que recibe como único argumento el nuevo valor que se desea asignar a la propiedad y devuelve el valor que se almacenará finalmente en el objeto.

nota un descriptor debe ser uno de estos dos tipos, no pueden ser ambos.

Estas opciones también pueden heredarse; es decir, las opciones de una propiedad han podido establecer en el prototipo de una clase de la que hereda el objeto.
Podemos fijar estos vaores con el Object.prototype() y object.feeze()

Object.defineProperty(object,'key',{
    __proto__:null,
    value:'static'
    //no aceptar propiedades heredadas
    //no enumerable
    //no configurable
    //no modificable
    //Como opciones por defecto
});

///definiendo todo explícitamente
Object.defineProperty(obj,'key',{
    enumerable:false,
    configurable:false,
    writable:false,
    value:'static'
})
//Reciclando el mismo objeto.
function withValue(value) {
  var d = withValue.d || (
    withValue.d = {
      enumerable: false,
      writable: false,
      configurable: false,
      value: null
    }
  );
  d.value = value;
  return d;
}
//..y..
Object.defineProperty(obj,'key',withValue('static'));

Object.freeze || Object(Object.prototype);
  • Object.freeze previene el añadir o eliminar del prototipo de objeto las propiedades (value,get,set,enuemerable,writable, configurable)
  • Object.seal() Evita que las propiedades se puedan borrar o modificar, pero permite que se puedan añadir nuevas propiedades

El Prototipo Object es la vida…😎

empezamos a analizar las propiedades definidas con Object.defineProperty(miObjeto , "nameOfMiPropiedad1" ,{ ...} )

📝 Object.defineProperty

Ideas/conceptos claves

Object.defineProperty() define una nueva propiedad sobre un objeto, o modifica una ya existente, y devuelve el objeto modificado.

Recursos

Object.defineProperty() - JavaScript | MDN

Object.seal() - JavaScript | MDN

https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze

Apuntes

  • Para agregar una nueva propiedad a un objeto comúnmente se realiza mediante obj.nuevPropiedad = “valor”
  • Object.defineProperty nos permite definir propiedades de un objeto pero no solo con alcance con el valor, sino que con otras propiedades importantes para el objeto
{
	...,
	propName: {
		configurable: true,
		enumerable: true,
		value: "holita",
		writable: true,
	}
}
  • Mediante Object.getOwnPropertyDescriptors(obj) podemos ver dichas propiedades
  • Cuando creamos una nueva propiedad con obj.nuevPropiedad = “valor” todas estas se marcan con true
  • En caso de querer modificar alguna de estas se pueden definir de la siguiente manera:
Object.defineProperty(obj, "newPropName", {
  value: "Foo", // valor de la propiedad
  writable: true, // true o false
  enumerable: false, // true o false
  configurable: true, // true o false
});

enumerable: false

  • La propiedad no aparecerá cuando listamos con el método Object.keys
    • Mediante Object.getOwnPropertyNames aparece dicha propiedad aunque esté marcada en false

writable: false

  • El valor de la propiedad no podrá ser modificada, pero si eliminada mediante **delete**obj.prop

configurable: false

  • El valor de la propiedad no podrá ser eliminada, pero si modificada

🧊 Object.seal y Object.freeze

Object.seal

  • Hace que todas las propiedades de un objeto tengan como valor configurable: false
    • Es decir que ninguna propiedad se pueda borrar

Object.freeze

  • Hace que todas las propiedades de un objeto tengan como valor writable: false
    • Es decir que ninguna propiedad se pueda cambiar de valor
📌 **RESUMEN:** Al momento de crear una nueva propiedad de un objeto en JavaScript es posible configurar acciones sobre dicha propiedad, mediante `Object.defineProperty` si deseas que ninguna propiedad se pueda borrar utiliza `Object.seal`, y si deseas que ninguna propiedad se pueda modificar utilizar `Object.freeze`

Desde el primer video presiento que este curso será asombroso!

Uno de los usos que se me ocurre, es tener atributos privados de los objetos ( no se si esté mal). Otro uso podría ser modificar con seal y freeze en masa los atributos. Configurar nuevos atributos de los objetos.
Esto por ejemplo para construcción de una calculadora sería muy bueno para no dejar modificar los valores que ya han sido setteados anteriormente.

Aqui mis apuntes con código
…
<
Object.defineProperty(juan, “prueba-nasa” , {
value : “extraterrestre” ,
writable : false ,
enumerable : false ,
configurable : false
})
Object.defineProperty(juan, “Navigator” , {
value : “Chrome” ,
writable : true ,
enumerable : true ,
configurable : true
})
Object.defineProperty(juan, “Favorite Food” , {
value : “Spaguetti” ,
writable : true ,
enumerable : false ,
configurable : true
})
Object.defineProperty(juan, “Editor” , {
value : “Visual Studio Code” ,
writable : false ,
enumerable : true ,
configurable : true
})
Object.defineProperty(juan, “terminal” , {
value : “WSL” ,
writable : true,
enumerable : true ,
configurable : false
})

// las que están en enumerable aparecen subrayada
// las que salen con enumerable hacen que no aparezcan cuando los listamos con Object.keys

// En cambio cuando se muestran con getOwnPropertiesNames si aparecen todos

// Cuando se usa el configurable en false, aunque reciba el cambio del objeto en realidad no va a cambiar la estructura del valor del objeto, esto se da porque le dijimos que no se podía escribir

// Cuando se usa en el configurable, inclusive no se podrá mostrar pero, sin embargo se puede notar que sigue apareciendo dentro de getOwnPropertieNames, sigue apareciendo el Objeto

// con configurable no nos permite borrar las propiedades de los objetos.

// “delete juan.navigator” => podemos borrarlo con eso>

Me da mucha curiosidad como se puede aplicar esto en un sistema del mundo laboral!

Object.defineProperty(objeto, “clave”, {valor, writeable, enumerable y configurable}

Writable permite editar el valor de nuestro atributo, si lo dejamos en false, ya no se podrá editar instanciandolo.

Enumerable permite poder listar nuestro atributo cuando llamamos el método Object.keys(objeto), si lo dejamos en false, este atributo no saldrá cuando llamememos método Object.keys(objeto).

Configurable nos permite eliminar nuestro atributo con la palabra reservada delete, si lo dejamos en false este no podrá ser eliminado.

Object.seal(objeto) hace que todos los atributos de nuestro objeto tengan los siguientes valores es los descriptor:

(No permite ser borrada)

writeable : true,

enumerable: true,

configurable : false

Object.freeze(objeto) hace que todos los atributos de nuestro objeto tengan los siguientes valores es los descriptor:

(No permite ser editada ni borrada)

writeable : false,

enumerable: true,

configurable : false