Heim > Artikel > Web-Frontend > JS-Attributmerkmale (Eigenschaftsdeskriptor)
JS-Attributmerkmale (Eigenschaftsdeskriptor)
ECMAScript 5 definiert ein Objekt namens „Eigenschaftsdeskriptor“, das zur Beschreibung verschiedener Merkmale verwendet wird. „Property Descriptor“-Objekte können nur in Object.defineProperty oder Object.defineProperties verwendet werden.
Konzept
ECMAScript 5 definiert ein Objekt namens „Property Descriptor“, das zur Beschreibung verschiedener Merkmale verwendet wird. Das Attributdeskriptorobjekt verfügt über 4 Attribute:
konfigurierbar: Konfigurierbarkeit, die die Änderung der von ihm beschriebenen Attribute steuert und angibt, ob die Eigenschaften des Attributs geändert werden können, ob das Attribut in ein Zugriffsattribut geändert werden kann, oder ob das Attribut durch Löschen gelöscht werden soll, um das Attribut neu zu definieren. Der Standardwert ist wahr.
aufzählbar: Aufzählbarkeit, die angibt, ob Attribute durch For-In-Traversierung erhalten werden können. Der Standardwert ist wahr.
beschreibbar: Beschreibbarkeit, die angibt, ob der Wert des Attributs geändert werden kann. Der Standardwert ist wahr.
Wert: Datenattribut, das den Wert des Attributs angibt. Der Standardwert ist undefiniert.
Zusätzlich zu den oben genannten Attributen gibt es zwei Zugriffsattribute, nämlich get und set, die value und beschreibbar ersetzen können.
get: Funktion, die beim Lesen von Attributen aufgerufen wird. Wenn Sie nur „get“ angeben, ist das Attribut schreibgeschützt. Der Standardwert ist undefiniert.
set: Funktion, die beim Schreiben von Attributen aufgerufen wird. Wenn Sie nur „set“ angeben, bedeutet dies, dass es sich bei dem Attribut um ein schreibgeschütztes Attribut handelt. Der Standardwert ist undefiniert.
Mit
„Property Descriptor“-Objekten können nur in Object.defineProperty oder Object.defineProperties verwendet werden.
API-Nutzung
Object.defineProperty: https://developer.mozilla.org...
Object.defineProperties: https://developer.mozilla.org. ..
var hello = {} Object.defineProperty(hello, 'girl', { configurable: false, enumberable: false, writable: true, value: 'sexy' }) // 存取器 Object.defineProperty(hello, 'woman', { configurable: false, enumberable: false, get: function() { return this.girl }, set: function(val) { this.girl = val } }) // 定义多个属性 Object.defineProperties(hello, { boy: { configurable: false, enumberable: false, writable: false, value: 'handsome' }, man: { configurable: false, enumberable: false, writable: true, get: function() { return this.boy } } })
Wenn Object.defineProperty oder Object.defineProperties zum Betreiben (Erstellen oder Ändern) von Eigenschaften verwendet werden, die nicht erstellt oder geändert werden dürfen, wird eine Typfehlerausnahme ausgelöst.
// 此例子运行在前面的例子的基础上 Object.defineProperty(hello, 'boy', { writable: true }) // Uncaught TypeError: Cannot redefine property: boy
Da das Jungenattribut zuvor auf „nicht konfigurierbar“ gesetzt wurde, wird beim Ändern des beschreibbaren Werts hier eine Typfehlerausnahme ausgelöst.
Eigenschaftsdeskriptoren können über Object.getOwnPropertyDescriptor oder Object.getOwnPropertyDescriptors abgerufen werden.
API-Nutzung
Object.getOwnPropertyDscriptor: https://developer.mozilla.org...
Object.getOwnPropertyDescriptors: https://developer.mozilla.org. ..
Regeln
var rules = { common: 'test' }
Wenn eine Eigenschaft nicht konfigurierbar ist, kann ihre Konfigurierbarkeit und Aufzählbarkeit nicht geändert werden.
Object.defineProperty(rules, 'rule1', { configurable: false, enumberable: false }) // 修改configurable会抛出类型错误异常 Object.defineProperty(rules, 'rule1', { configurable: true }) // Uncaught TypeError: Cannot redefine property: rule1 // 修改enumberable不会抛出异常,但enmuberable没有被修改 Object.defineProperty(rules, 'rule1', { enumberable: true }) Object.getOwnPropertyDescriptor(rules, 'rule1') // Object {value: undefined, writable: false, enumerable: false, configurable: false}
Wenn die Accessor-Eigenschaft nicht konfigurierbar ist, können die Get- und Set-Methoden weder geändert noch in eine Dateneigenschaft konvertiert werden.
Object.defineProperty(rules, 'rule2', { configurable: false, enumberable: false, get: function() { return this.common }, set: function(val) { this.common = val } }) // 修改get或者set方法会抛出类型错误异常 Object.defineProperty(rules, 'rule2', { get: function() { return this.common + 'rule2' } }) // Uncaught TypeError: Cannot redefine property: rule2 Object.defineProperty(rules, 'rule2', { set: function(val) { this.common = 'rule2' } }) // Uncaught TypeError: Cannot redefine property: rule2 // 将它转换为数据属性同样会抛出类型错误异常 Object.defineProperty(rules, 'rule2', { value: 'rule2' }) // Uncaught TypeError: Cannot redefine property: rule2
Wenn ein Datenattribut nicht konfigurierbar ist, kann es nicht gleichzeitig in ein Zugriffsattribut umgewandelt werden. Seine Beschreibbarkeit kann nicht von „falsch“ auf „wahr“ geändert werden, aber es kann von „wahr“ auf „wahr“ geändert werden FALSCH.
Object.defineProperty(rules, 'rule3', { configurable: false, writable: false, value: 'rule3' }) // 修改writable为true会抛出类型错误异常 Object.defineProperty(rules, 'rule3', { writable: true }) Object.defineProperty(rules, 'rule4', { configurable: false, writable: true, value: 'rule4' }) // 可以修改writable为false Object.defineProperty(rules, 'rule4', { writable: false }) Object.getOwnPropertyDescriptor(rules, 'rule4') // Object {value: "rule4", writable: false, enumerable: false, configurable: false}
Wenn das Datenattribut nicht konfigurierbar und nicht beschreibbar ist, kann sein Wert nicht geändert werden. Wenn es konfigurierbar, aber nicht beschreibbar ist, kann sein Wert geändert werden (tatsächlich ist es als beschreibbar markiert). , ändern Sie dann seinen Wert und markieren Sie ihn schließlich wieder als nicht beschreibbar).
Tatsächlich wird der hier erwähnte geänderte Wert durch die Methode Object.defineProperty oder Object.defineProperties geändert. Wenn das Datenattribut nicht konfigurierbar ist, kann der Attributwert nicht durch direkte Zuweisung geändert werden.
Object.defineProperty(rules, 'rule5', { configurable: false, writable: false, value: 'rule5' }) // 修改属性值会抛出类型错误异常 Object.defineProperty(rules, 'rule5', { value: 'rule55' }) // Uncaught TypeError: Cannot redefine property: rule5 rules.rule5 = 'rule55' // 值没有被修改,也不会抛出异常 rules.rule5 // 'rule5' Object.defineProperty(rules, 'rule6', { configurable: true, writable: false, value: 'rule6' }) // 修改属性值 Object.defineProperty(rules, 'rule6', { value: 'rule66' }) rules.rule6 // 'rule66' rules.rule6 = 'rule6' // 值没有被修改,也不会修改 rules.rule6 // 'rule6'
Nur der angegebene Satz kann nicht gelesen werden. Wenn Sie versuchen, den Attributwert zu lesen, wird undefiniert zurückgegeben. (Im Red Book heißt es, dass Ausnahmen nur im strikten Modus ausgelöst werden, aber das ist nicht der Fall)
Object.defineProperty(rules, 'rule7', { get: function() { return this.common } }) rules.rule7 = 'rule7' // Uncaught TypeError: Cannot redefine property: rule7
Wenn das Objekt nicht erweiterbar ist, können Sie vorhandene eigene Eigenschaften bearbeiten, aber keine neuen hinzufügen es. Eigentum.
Es gibt drei APIs zur Bedienung der Objekterweiterbarkeit: Object.preventExtensions, Object.seal und Object.freeze.
API-Nutzung
Object.preventExtensions: https://developer.mozilla.org...
Object.seal: https://developer.mozilla.org. ..
Object.freeze: https://developer.mozilla.org...
Object.isExtensions: https://developer.mozilla.org...
Object.isSealed: https://developer.mozilla.org...
Object.isFrozen: https://developer.mozilla.org...
Verwenden Sie Object.preventExtensions Objekte können in nicht erweiterbare Objekte konvertiert werden.
Verwenden Sie Object.isExtensions, um zu bestimmen, ob ein Objekt erweiterbar ist.
var ex = {} Object.defineProperty(ex, 'ex1', { configurable: true, writable: true, value: 'ex1' }) Object.isExtensible(ex) // true Object.preventExtensions(ex) Object.isExtensible(ex) // false // 可以修改已有的属性 Object.defineProperty(ex, 'ex1', { writable: false, value: 'ex11' }) Object.getOwnPropertyDescriptor(ex, 'ex1') // Object {value: "ex11", writable: false, enumerable: false, configurable: true} // 添加属性会抛出类型错误异常 Object.defineProperty(ex, 'ex2', { value: 'ex2' }) // Uncaught TypeError: Cannot define property:ex2, object is not extensible.
Zusätzlich zur Konvertierung des Objekts in nicht erweiterbar kann die Verwendung von Object.seal auch alle eigenen Eigenschaften des Objekts in nicht konfigurierbar konvertieren. Das heißt, dem Objekt können keine neuen Attribute hinzugefügt werden und seine vorhandenen Attribute können nicht gelöscht oder konfiguriert werden (hier gelten die gleichen Regeln wie zuvor).
Verwenden Sie Object.isSealed, um zu bestimmen, ob das Objekt versiegelt ist.
var se = {} Object.defineProperty(se, 'se1', { configurable: true, writable: false, value: 'se1' }) Object.isSealed(se) // false Object.seal(se) Object.isSealed(se) // true // 修改已有的属性会抛出类型错误异常 Object.defineProperty(se, 'se1', { writable: true, value: 'se11' }) // Uncaught TypeError: Cannot redefine property: se1 // 添加属性会抛出类型错误异常 Object.defineProperty(se, 'se2', { value: 'se2' }) // Uncaught TypeError: Cannot define property:se2, object is not extensible.
Mit Object.freeze können Sie nicht nur ein Objekt in nicht erweiterbar und seine Eigenschaften in nicht konfigurierbar konvertieren, sondern auch Ihre eigenen Eigenschaften in schreibgeschützt umwandeln. (Wenn das Objekt festgelegt ist, werden die Accessor-Eigenschaften nicht beeinflusst, und die Set-Methode kann weiterhin aufgerufen werden und es wird keine Ausnahme ausgelöst. Wenn die Set-Methode jedoch die Eigenschaften des Objekts ändert, kann sie nicht erfolgreich geändert werden.)
Verwenden Sie Object.isFrozen, um zu erkennen, ob ein Objekt eingefroren ist.
var fr = {} Object.defineProperty(fr, 'fr1', { configurable: true, writable: false, value: 'fr1' }) Object.isFrozen(fr) // false Object.freeze(fr) Object.isFrozen(fr) // true // 修改已有的属性会抛出类型错误异常 Object.defineProperty(fr, 'fr1', { writable: true, value: 'fr11' }) // Uncaught TypeError: Cannot redefine property: fr1 // 添加属性会抛出类型错误异常 Object.defineProperty(fr, 'fr2', { value: 'fr2' }) // Uncaught TypeError: Cannot define property:fr2, object is not extensible. fr.fr1 = 'fr11' // 不能修fr1属性 fr.fr1 // 'fr1' var set = {} Object.defineProperty(set, 'set1', { configurable: true, value: 'set1' }) Object.defineProperty(set, 'set2', { configurable: true, set: function(val) { this.set1 = val } }) Object.isFrozen(set) // false Object.freeze(set) Object.isFrozen(set) // true set.set2 = 'set2' set.set1 // 'set1'
Fazit
Ich bin mit Attributdeskriptoren sehr unbekannt, hauptsächlich weil ich sie selten verwende. Vor kurzem begann ich jedoch zu lernen, einige kleine Bibliotheken zu schreiben (obwohl es sehr frustrierend war), und ich hatte das Gefühl, dass es Szenarien für die Verwendung von Attributdeskriptoren gibt. Was mir vorerst einfällt, ist, einige Eigenschaften des Bibliotheksobjekts auf schreibgeschützt zu setzen, um zu verhindern, dass einige Eigenschaften des Objekts von Benutzern überschrieben werden. Es gibt eine weitere Verwendung, die ich gelernt habe, als ich Vue auf Zhihu lernte, nämlich Getter und Setter zu verwenden, um die Datenaktualisierungen von Objekteigenschaften zu „überwachen“