Object.defineProperty () compréhension personnelle
Object.defineProperty () permet de définir les propriétés des propriétés de l'objet. Ces propriétés appartiennent à la valeur interne de l'objet, elles ne sont donc pas accessibles directement dans JS.
Dans ES5, il existe deux attributs, dontAttributs de donnéesavecPropriétés de l'accesseur
Attributs de données
L'attribut data contient unValeur des donnéesLa position où vous pouvez lire et écrire des valeurs, l'attribut de données a 4 caractéristiques utilisées pour décrire son comportement
- [[Configurable]] indique si vous pouvez supprimer l'attribut, si vous pouvez modifier les caractéristiques de l'attribut, si vous pouvez changer l'attribut en attribut d'accesseur, lorsque vous définissez l'attribut directement sur l'objet, la valeur par défaut est true
- [[Enumerable]] Est-il possible de renvoyer l'attribut via une boucle? Attribut défini directement sur l'objet, cet attribut prend la valeur par défaut true
- [[Ecriture]] Est-il possible de modifier la valeur de l'attribut. L'attribut défini directement sur l'objet, la valeur par défaut de cet attribut est true
- [[Value]] La valeur de données de l'attribut. Lors de la lecture d'une valeur d'attribut, lisez à partir de cet emplacement et lors de l'écriture d'un nouvel attribut, enregistrez la nouvelle valeur à cet emplacement. La valeur par défaut n'est pas définie
Utilisez Object.defineProperty () pour modifier les propriétés par défaut de la propriété, en acceptant trois paramètres: l'objet dans lequel se trouve la propriété, le nom de la propriété et un objet descripteur. La propriété de l'objet descripteur doit être les quatre propriétés ci-dessus et ne peut pas ont d'autres propriétés. Définissez une ou plusieurs valeurs, vous pouvez modifier la valeur de caractéristique correspondante
Exemple:
let obj = {
name: "lalala",
age: 15,
idol: 'CR7'
};
Object.defineProperty(obj , 'name' , {
writable: false, //不可被修改
enumerable: false, //不可被遍历
value: "Well"
})
console.log(obj.name) //Well
obj.name = 'Nigo' //严格模式下会报错,非严格模式没事
console.log(obj.name) //Well
Object.keys(obj).forEach(key => {
console.log(key); //age , idol 不包含name属性
})
La méthode object.defineProperty () peut être appelée plusieurs fois pour modifier la même propriété, mais si le configurable est défini sur false pour la première modification, il ne peut pas être modifié à nouveau et une erreur sera signalée
let obj = {
name: "lalala",
age: 15,
idol: 'CR7'
};
Object.defineProperty(obj , 'name' , {
//没有设置configurable:false是可以再次修改的
writable: false, //不可被修改
enumerable: false, //不可被遍历
value: "Well"
})
console.log(obj.name) //Well
obj.name = 'Nigo' //严格模式下会报错,非严格模式没事
console.log(obj.name) //Well
Object.keys(obj).forEach(key => {
console.log(key); //age , idol 不包含name属性
})
Object.defineProperty(obj , 'name' , {
writable: true, //该为true
enumerable: false, //不可被遍历
value: "Well"
})
obj.name = 'Nigo' //可以修改属性了
console.log(obj.name) //Nigo
let obj = {
name: "lalala",
age: 15,
idol: 'CR7'
};
Object.defineProperty(obj , 'name' , {
//没有设置configurable:false是可以再次修改的
configurable:false, //不可再次修改该属性的特性
writable: false, //不可被修改
enumerable: false, //不可被遍历
value: "Well"
})
console.log(obj.name) //Well
obj.name = 'Nigo' //严格模式下会报错,非严格模式没事
console.log(obj.name) //Well
Object.keys(obj).forEach(key => {
console.log(key); //age , idol 不包含name属性
})
Object.defineProperty(obj , 'name' , {
//这里直接报错
writable: true,
enumerable: false,
value: "Well"
})
Propriétés de l'accesseur
La propriété accesseur ne contient pas de valeurs de données, mais contient une paire de fonctions getter et setter (non obligatoire)
De plus, lorsqu'une propriété a des méthodes get et set, il s'agit d'une propriété d'accesseur
fonction getter
Fonction appelée lors de la lecture des propriétés de l'accesseur
fonction setter
Lors de l'écriture des propriétés de l'accesseur, appelez la fonction setter et transmettez la nouvelle valeur, la fonction setter détermine comment traiter les données
Les propriétés de l'accesseur ne peuvent pas être définies directement, elles doivent également être définies par Object.defineProperty ()
const obj = {
name: 'Well',
_age: 22, //表示只有通过对象方法能访问到的属性
}
Object.defineProperty(obj , 'age' , {
configurable:true, //表示能否delete删除属性,能否修改属性的特性,能否将属性改为数据属性,默认false
enumerable: true, //能否被遍历到,默认false
get() {
console.log("获取age的值");
return this._age;
},
set(newV) {
console.log("写入新值");
this._age = newV; //可以通过setter函数改变对象中的其他属性值
}
});
obj.age = 24; //写入新值
console.log(obj.age); //获取age的值 24
obj.age = 26; //写入新值
console.log(obj.age); //获取age的值 26
console.log(obj._age) //26
Le nom d'attribut de l'accesseur ne peut pas être le même que le nom d'attribut d'origine de l'objet, sinon la pile débordera en raison de la boucle sans fin
Modifications des données dans l'objet de surveillance:
const obj = {
a: 1,
b: 2,
c: 3
}
Object.keys(obj).forEach(key=>{
let value = obj[key]
Object.defineProperty(obj,key,{
get(){
console.log(`获取${
key}的行为被我劫持了`)
return value
},
set(v){
console.log(`${
key}的改变被我劫持了`);
value = v;
}
})
})
console.log(obj.b); //获取b的行为被我劫持了 2
obj.c = 5; //c的改变被我劫持了
Il n'est pas nécessaire de définir en même temps getter et setter
Seule la définition du setter signifie qu'il ne peut être écrit, pas lu. Lors de la lecture d'une propriété sans getter, le mode strict signalera une erreur et le mode non strict retournera undefined
Définir uniquement le getter signifie que vous ne pouvez lire, pas écrire, essayer d'écrire, une erreur sera signalée en mode strict et elle sera ignorée en mode non strict
Définir plusieurs attributs
Object.defineProperties (), cette méthode reçoit deux paramètres, qui sont tous deux deux objets, le premier est l'objet à ajouter et modifier les propriétés
Les attributs du deuxième objet doivent correspondre aux attributs ajoutés ou modifiés dans le premier objet
Exemple:
const people = {
_name: 'Nigo',
_age: 28
};
Object.defineProperties(people , {
_name: {
value: 'HaHa',
//可修改其他特性
},
name: {
//定义一个访问器属性
get() {
return this._name;
}
},
age: {
set(newV) {
this._age = newV
}
}
})
Lire les propriétés des attributs
Object.getOwnPropertyDescriptor ()
L'objet où se trouvent les attributs des deux paramètres et le nom de l'attribut à lire, la valeur de retour de cette méthode est un objet
S'il s'agit d'un attribut de données, l'objet renvoyé contient configurable, énumérable, writabele, valeur
S'il s'agit d'un attribut d'accesseur, l'objet retourné contient configurable, énumérable, get et set
Dans JS, vous pouvez utiliser la méthode Object.getOwnPropertyDescriptor () sur n'importe quel objet