
A következő négy sor elegendő a legtöbb JavaScript-fejlesztő megzavarásához:
Object instanceof Function//true
Object instanceof Object//true
Function instanceof Object//true
Function instanceof Function//true
A JavaScript prototípusa az egyik leggondolkodtatóbb fogalom, de nem kerülheti el. Nem számít, mennyire figyelmen kívül hagyja, a prototípus puzzle-val a JavaScript élete során találkozhat.
Szóval nézzünk szembe azzal.
Az alapoktól kezdve a következő adattípusok vannak a JavaScript-ben:
- meghatározatlan
- nulla
- szám
- húr
- logikai érték
- tárgy
Az első öt primitív adattípus. Ezek tárolnak egy típusú értéket, például logikai értéket, és lehetnek igazak vagy hamisak .
Az utolsó „objektum” egy referencia típus, amelyet kulcs-érték párok gyűjteményeként írhatunk le (de sokkal több).
A JavaScript-ben új objektumok készülnek az Object constructor függvény (vagy objektum literál {}
) használatával, amely olyan általános módszereket biztosít, mint a toString()
és valueOf()
.
A JavaScript funkciói olyan speciális objektumok, amelyek „ meghívhatók” . Ezeket a Function constructor függvény (vagy a literal függvény) használatával készítjük el. Az a tény, hogy ezek a konstruktorok objektumok, valamint funkciók, mindig megzavart engem, ugyanúgy, ahogy a csirke-tojás rejtvény is összezavar mindenkit.
Mielőtt a prototípusokkal kezdem, szeretném tisztázni, hogy a JavaScript-ben két prototípus létezik:
- prototípus : Ez egy speciális objektum, amelyet a JavaScript bármely funkciójának tulajdonságaként rendelünk hozzá. Tisztázzuk itt, hogy ez már létezik minden ön által készített funkciónál, de nem kötelező a JavaScript által biztosított belső funkciókhoz (és a függvények által visszaadott
bind
). Ezprototype
ugyanaz az objektum, amelyre a[[Prototype]]
(lásd alább) az adott funkcióból újonnan létrehozott objektumot (new
kulcsszó használatával ). - [[Prototípus]]: Ez egy valahogy elrejtett tulajdonság minden objektumon, amelyhez a futó kontextus hozzáfér, ha valamilyen tulajdonság, amely az objektumon olvasható, nem érhető el. Ez a tulajdonság egyszerűen a
prototype
annak a függvénynek, amelyből az objektum készült. Ez szkriptben érhető el speciális getter-setter (egy másik nap témája) néven__proto__
. Vannak más új módszerek is a prototípus elérésére, de a rövidség kedvéért utaltam rá[[Prototype]]
felhasználásával__proto__
.
var obj = {}var obj1 = new Object()
A fenti két állítás egyenlő állítás, ha új objektum létrehozására használják, de sok minden történik, ha végrehajtjuk ezen állítások bármelyikét.
Amikor új tárgyat készítek, az üres. Valójában nem üres, mert aObject
konstruktor, és eredendően kap referenciát prototype
nak,-nek Object,
amelyre a __proto__
az újonnan létrehozott objektum.

Ha megnézzük a prototype
A Object
konstruktor függvényt, úgy néz ki, ugyanaz, mint a __proto__
A obj.
Sőt, ők két pointert hivatkozva ugyanazt a tárgyat.

obj.__proto__ === Object.prototype//true
Minden prototype
függvényvan egy benne rejlő tulajdonsága, constructor
amely maga a függvény mutatója. Abban az esetben, Object
funkció , a prototype
márconstructor
amely vissza mutat Object
.
Object.prototype.constructor === Object//true

A fenti képen a bal oldal a Object
kivitelező kibővített nézete . Biztosan kíváncsi arra, hogy mi ez a többi funkció rajta. Nos, a függvények objektumok , tehát tulajdonságaik lehetnek felettük, mint más objektumok.
Ha alaposan megnézed, maga a Object
(bal oldalon) rendelkezik a__proto__
ami azt jelenti Object
valamilyen más konstruktorról kellett készülnie, amelynek prototype.
As-ja vanObject
függvényobjektum, használatával kell elkészíteni Function
konstruktőr.

__proto__
nak,-nek Object
ugyanúgy néz ki, mint prototype
a Function
. Amikor ellenőrzem mindkettő egyenlőségét, kiderül, hogy ugyanazok a tárgyak.
Object.__proto__ === Function.prototype//true
Ha alaposan megnézi, látni fogja a Function
önmagában van egy __proto__
ami azt jelenti Function
konstruktor funkcióvalamilyen konstruktor függvényből kellett készülnie, amelynek a prototype
. MintFunction
maga egy függvény , felhasználásával kell elkészíteniFunction
kivitelező, vagyis maga. Tudom, hogy ez furcsán hangzik, de ha megnézed, kiderül, hogy igaz.

A __proto__
a Function
ésprototype
nak,-nek Function
vannakvalójában két mutató utal ugyanarra az objektumra.
Function.prototype === Function.__proto__\\true
Mint korábban említettük, a constructor
bármelyikprototype
mutatnia kell annak a funkciónak, amely ezt birtokolja prototype.
A constructor
nak,-nek prototype
nak,-nek Function
mutat vissza Function
önmagára.
Function.prototype.constructor === Function\\true

Ismét a prototype
nak,-nek Function
van egy __proto__
. Nos, ez nem meglepő ... prototype
egy tárgy, lehet. De vegye észre azt is, hogy aprototype
of Object
.
Function.prototype.__proto__ == Object.prototype\\true
Tehát itt van egy főtérképünk:

instanceof Operatora instanceof b
Ainstanceof
operátor megkeresi az objektumot b
- mutatott rábármelyik constructor
(ek) a szénláncú__proto__
tovább a
. Olvassa el újra! Ha talál ilyen hivatkozást, visszatértrue
más false
.
Most visszatérünk az első négyünkhöz instanceof
nyilatkozatok. Megfelelő nyilatkozatokat írtaminstanceof
Visszatérés true
a következőnek:
Object instanceof FunctionObject.__proto__.constructor === Function
Object instanceof ObjectObject.__proto__.__proto__.constructor === Object
Function instanceof FunctionFunction.__proto__.constructor === Function
Function instanceof ObjectFunction.__proto__.__proto__.constructor === Object
Phew !! Még a spagetti is kevésbé kusza, de remélem, hogy most már egyértelműbbek a dolgok.
Itt van valami, amit nem korábban jelezte, hogy prototype
aObject
nincs a __proto__
.
Valójában van egy __proto__
de ez egyenlő null
. A láncnak valahol véget kellett vetnie, és itt ér véget.
Object.prototype.__proto__\\null
A Object
, Function
,Object.prototype
ésFunction.prototype
tulajdonságokkal is rendelkeznek, amelyek funkciók, mint például Object.assign
,Object.prototype.hasOwnProperty
ésFunction.prototype.call
. Ezek olyan belső függvények, amelyek nem rendelkeznek, prototype
és azok Function
a__proto__
ami mutató Function.prototype
.

Object.create.__proto__ === Function.prototype\\true
Megvizsgálhatja a konstruktor egyéb funkcióit, például a Array
ésDate
, vagy vegye el tárgyaikat és keresse meg a prototype
és__proto__
. Biztos vagyok benne, hogy meg tudja tudni, hogyan kapcsolódik minden.
Extra lekérdezések:
Van még egy kérdés, hogy a poloska nekem egy darabig: Miért van az, hogy prototype
az Object
a tárgy , és prototype
az Function
is függvény objektum ?
Ittjó magyarázat rá, ha ugyanúgy gondoltál.
Egy másik kérdés, amely eddig rejtélyt jelenthet számodra: Hogyan kapják meg a primitív adattípusok a hasonló funkciókat toString()
,substr()
és toFixed()
?Ez jól magyarázza itt .
Használatával prototype
az öröklést működtethetjük egyedi objektumainkkal JavaScript-ben. De ez egy másik nap témája.
Köszönöm, hogy elolvasta!