Perché Object.defineProperty () piuttosto che this.defineProperty () (per oggetti)?

Sto lavorando su un progetto JavaScript e mi stavo chiedendo perché un’istanza dell’object non eredita la defineProperty() e altri metodi, piuttosto che dover chiamare il metodo Object superclass (superobject?).

Ho esaminato i documenti MDN e ci sono in effetti metodi di proprietà “non standard”.

Ma quelli sono deprecati. Perché il passaggio dovrebbe essere ai metodi Object ?

Mi sembra che qualcosa come instance.defineProperty(...) sia migliore di Object.defineProperty(instance, ...) . Direi lo stesso anche su alcuni degli altri metodi Object.

È per evitare collisioni – in generale, problemi con oggetti che non hanno la proprietà con il valore che ti aspetti.
Gli oggetti in JS vengono spesso utilizzati come mappe valore-chiave e le chiavi possono essere stringhe arbitrarie, ad esempio __defineGetter__ , hasOwnProperty o qualcosa di meno speciale. Ora quando vuoi invocare una funzione di questo tipo su un object sconosciuto – come hasOwnProperty viene spesso usata nelle funzioni di enumerazione generica, dove può essere passato qualsiasi JSON – non puoi mai essere sicuro se hai una proprietà sovrascritta (che potrebbe anche non essere una funzione) o l’originale che si desidera, o se l’object eredita la proprietà. Per evitare questo problema (o anche questo bug di IE ), dovresti usare Object.prototype.hasOwnProperty.call – che è brutto.

Quindi, il namespace di tutte quelle funzioni su Object è utile solo, è un’API più pulita che separa i metodi di riflessione dall’interfaccia dell’applicazione dell’object. Ciò aiuta anche l’ottimizzazione (semplificando l’analisi statica) e semplifica la limitazione dell’accesso all’API di riflessione nelle sandbox: almeno questa era l’ idea progettuale .

Potresti essere felice di avere una defineProperty nel prototipo, ma puoi utilizzarla in sicurezza solo quando lavori con oggetti conosciuti. Se lo vuoi ancora (come sai quando usarlo e quando no), puoi usare

 Object.defineProperty(Object.prototype, "defineProperty", { writable: true, enumberable: false, value: function(prop, descr) { return Object.defineProperty(this, prop, descr); } }); 

Interessante. L’unica ragione per cui sono arrivato finora è che alla gente piace riscrivere i prototipi e avere questo metodo “nascosto” come questo potrebbe aiutarti a evitare alcuni bug. Soprattutto a causa del buon nome del metodo poiché è più probabile che venga riscritto rispetto, ad esempio, a __defineGetter__ .

Sembra che molte funzionalità dipendano da questa funzionalità ( collegamento ), quindi ha senso renderlo più globale e sicuro in questo contesto.

È fatto così per evitare collisioni – ricorda, ogni metodo su Object.prototype è anche un metodo in ogni singolo object definito dall’utente.

Immagina un object in cui desideri un metodo personalizzato defineProperty , che romperebbe completamente le cose quando Object.defineProperty era invece sul suo prototipo.