So che ogni object JavaScript ha una proprietà interna chiamata [[Prototype]]
. Alcune implementazioni consentono di accedervi tramite una proprietà chiamata __proto__
mentre altre no. C’è qualche significato speciale delle parentesi che circondano questa proprietà?
È una ” proprietà interna ” dell’object. Da ECMAScript 8.6.2 :
Questa specifica utilizza varie proprietà interne per definire la semantica dei valori dell’object. Queste proprietà interne non fanno parte del linguaggio ECMAScript. Sono definiti da questa specifica puramente a fini espositivi. Un’implementazione di ECMAScript deve comportarsi come se producesse e operasse su proprietà interne nel modo descritto qui. I nomi delle proprietà interne sono racchiusi tra parentesi quadre [[]].
L’istruzione “Queste proprietà interne non fanno parte del linguaggio ECMAScript” indica che le proprietà interne non sono identificatori che possono essere utilizzati nel codice effettivo: le proprietà interne non sono accessibili come membri degli oggetti che le contengono. Tuttavia, possono essere resi accessibili da particolari funzioni o proprietà (ad esempio, alcuni browser sono abbastanza gentili consentono di impostare e ottenere [[Prototype]]
attraverso la proprietà __proto__
, e la specifica ES5 consente l’accesso in sola lettura tramite Object.getPrototypeOf
).
L’uso di doppie parentesi su parentesi singole probabilmente è per evitare ogni ansible confusione con la notazione della parentesi effettiva (cioè, l’accesso alla proprietà).
La doppia parentesi [[Prototype]]
è un collegamento interno che stringe un object a un altro.
Quando si crea una funzione, viene creato un object proprietà chiamato prototype che viene aggiunto alla variabile nome della funzione (che chiamiamo constructor
). Questo object punta, o ha un collegamento interno-privato, all’object JavaScript nativo).
Esempio:
function Foo () { this.name = 'John Doe'; } // Foo has an object 'property' called prototype // prototype was created automatically when we declared the function Foo. // Now, we can assign properties to it without declaring the prototype object first. Foo.prototype.myName = function () { return 'My name is ' + this.name; }
Ora, se creeremo un nuovo object fuori da Foo
usando la new
parola chiave, fondamentalmente creiamo (tra le altre cose) un nuovo object che ha un collegamento interno al prototipo della funzione ( Foo
) di cui abbiamo discusso in precedenza:
var obj = new Foo(); obj.[[Prototype]] === Foo.prototype // true
Poiché [[Prototype]]
è un collegamento privato all’object di quella funzione, molti browser ci forniscono invece un collegamento pubblico. Questo è il __proto__
(pronunciato come proto dunder).
__proto__
è in realtà una funzione getter che appartiene all’object JavaScript nativo e restituisce il collegamento prototipo interno-privato di qualunque sia il legame (restituisce [[Prototype]]
di obj
):
obj.__proto__ === Foo.prototype // true
A proposito, partendo da ES5
, possiamo usare il metodo getPrototypeOf
per ottenere il collegamento privato interno:
obj.__proto__ === Object.getPrototypeOf(obj) // true
NOTA: questa risposta non intende coprire l’intero processo di creazione di nuovi oggetti o nuovi costruttori, ma per aiutare a capire meglio che cos’è [[Prototype]]
e come funziona.
Il motivo per cui è tra parentesi è quello di indicare che si tratta di una proprietà privata. Le parentesi non sono mai usate nel codice ovunque.
Come hai sottolineato, alcune implementazioni forniscono l’accesso a tale proprietà privata sotto __proto__
, ma non è standard.