__proto__ VS. prototyp w JavaScript


785

Ten rysunek ponownie pokazuje, że każdy obiekt ma prototyp. Funkcja konstruktora Foo ma również swoją własną__proto__ funkcję Function.prototype, która z kolei odwołuje się również poprzez swoją __proto__właściwość do Object.prototype. Zatem powtórzmy, Foo.prototype jest tylko jawną właściwością Foo, która odnosi się do prototypu obiektów b i c.

var b = new Foo(20);
var c = new Foo(30);

Jakie są różnice między __proto__ i prototype?

wprowadź opis zdjęcia tutaj

Liczba została zaczerpnięta z dmitrysoshnikov.com .



5
Myślę, że odgórne lub oddolne to kwestia preferencji. Właściwie wolę to w ten sposób, więc mogę prześledzić schemat, dopóki nie znajdę, skąd coś pochodzi.
Mike Lippert,

1
Podoba mi się, w jaki sposób JavaScript wykorzystuje dziedziczenie prototypowe do rozwiązania konstruktora y.constructor na y .__ proto __. Podoba mi się również to, jak Object.prototype znajduje się na szczycie prototypowego łańcucha dziedziczenia, a Object.prototype .__ proto__ jest ustawiony na null. Podoba mi się również, jak diagram tworzy trójkolumnową wizualizację pojęciową tego, jak programista myśli o obiektach jako 1. instancjach, 2. konstruktorach, 3. prototypach, które konstruktory kojarzą z tymi instancjami, gdy są tworzone za pomocą nowego słowa kluczowego.
John Sonderson

Schemat ma sens natychmiast po obejrzeniu czegoś takiego jak youtube.com/watch?v=_JJgSbuj5VI , btw
mlvljr

A teraz, gdy przeczytałem odpowiedzi, czuję się zobowiązany do naprawdę polecić powyższe wideo, ponieważ rzeczywiście ma krystalicznie czyste (i nie WTFy) wyjaśnienie tego, co się dzieje :)
mlvljr

Odpowiedzi:


765

__proto__jest rzeczywistym obiektem używanym w łańcuchu wyszukiwania do rozwiązywania metod itp. prototypejest obiektem używanym do budowania __proto__podczas tworzenia obiektu za pomocą new:

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

239
Ach! Dlatego prototypenie jest dostępny w samych instancjach (lub innych obiektach), ale tylko w funkcjach konstruktora.
rvighne

43
@rvighne: prototypejest dostępny tylko na funkcjach, ponieważ pochodzą one z Function, Functioni Object, ale w niczym innym nie. Jest jednak __proto__dostępny wszędzie.
Tarik

19
Tak samo __proto__jest rzeczywisty obiekt, który jest zapisywany i używany jako prototyp, podczas gdy Myconstructure.prototypejest tylko planem, dla __proto__którego, w rzeczywistości jest faktyczny obiekt zapisany i używany jako prototyp. Stąd myobject.prototypenie byłaby właściwością rzeczywistego obiektu, ponieważ jest to tylko tymczasowa rzecz używana przez funkcję konstruktora do nakreślenia, jak myobject.__proto__powinien wyglądać.
Alex_Nabu

9
Czy można uczciwie powiedzieć, że __proto__właściwość obiektu jest wskaźnikiem do właściwości funkcji konstruktora prototypeobiektu? tj. foo .__ proto__ === foo.constructor.prototype
Niko Bellic

10
@Alex_Nabu Niezupełnie. newCar.__proto__ IS Car.prototype , a nie przypadek Car.prototype. Chociaż Car.protoype jest instancją object. Car.prototypenie jest czymś, co daje newCarżadnych właściwości lub struktury, to po prostu JEST przyszłorocznego objectIN newCar„s łańcuch prototypów. Car.prototypenie jest tymczasowy object. Jest to wartość, objectktóra jest ustawiana jako wartość __proto__właściwości każdego nowego objects utworzonego przy użyciu Carjako constructor. Jeśli chcesz myśleć o czymś jako o planie object, pomyśl o tym Carjak o schemacie dla nowych samochodów object.
seangwright

335

prototypejest właściwością obiektu Function. Jest to prototyp obiektów skonstruowanych przez tę funkcję.

__proto__jest wewnętrzną własnością obiektu, wskazującą na jego prototyp. Obecne standardy zapewniają równoważną Object.getPrototypeOf(O)metodę, choć de facto standard __proto__jest szybszy.

Możesz znaleźć instanceofrelacje, porównując funkcję z łańcuchem prototypeobiektu __proto__, i możesz zerwać te relacje, zmieniając prototype.

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var myPoint = new Point();

// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;

Oto Pointfunkcja konstruktora, która konstruuje obiekt (strukturę danych) proceduralnie. myPointjest obiektem zbudowanym przez, Point()więc Point.prototypezostaje myPoint.__proto__w tym czasie zapisany .


2
Również zmiana __proto__właściwości obiektu powoduje zmianę obiektu, na którym wykonywane są wyszukiwania prototypów. Na przykład można dodać obiekt metod jako funkcję, __proto__aby uzyskać rodzaj obiektu instancji, który można wywołać.
kzh

myPoint .__ proto __. constructor.prototype == Point.prototype
Francisco

@kzh lol, który dał mi śmieszny wynik console.log(obj1.call) // [Function: call] obj1.call()// TypeError: obj1.call nie jest funkcją. Zrobiłemobj.__proto__ = Function.__proto__
abhisekp

myFn.__proto__ = {foo: 'bar'}
kzh

Myślę, że mam twój punkt.
ComicScrip,

120

Właściwość prototypowa jest tworzona, gdy funkcja jest deklarowana.

Na przykład:

 function Person(dob){
    this.dob = dob
 }; 

Person.prototypewłaściwość jest tworzona wewnętrznie po zadeklarowaniu powyższej funkcji. Do właściwości Person.prototype można dodać wiele właściwości, które są wspólne dla instancji Person utworzonych za pomocą nowej Person ().

// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob}; 

Warto zauważyć, że Person.prototypejest toObject dosłownie domyślnie (można go zmienić w razie potrzeby).

Każda instancja utworzona za pomocą new Person()ma __proto__właściwość, która wskazuje na Person.prototype. Jest to łańcuch używany do przechodzenia w celu znalezienia właściwości określonego obiektu.

var person1 = new Person(somedate);
var person2 = new Person(somedate);

tworzy 2 wystąpienia Person, te 2 obiekty mogą wywoływać agemetodę Person.prototypeas person1.age,person2.age .

Na powyższym obrazku z twojego pytania widać, że Foojest to Function Objecti dlatego ma __proto__link do tego, Function.prototypektóry z kolei jest instancją Objecti ma __proto__link do Object.prototype. Końce tutaj z linkiem proto __proto__w Object.prototypewskazującą null.

Każdy obiekt może mieć dostęp do wszystkich właściwości w swoim łańcuchu proto połączonych __proto__, tworząc w ten sposób podstawę dla dziedziczenia prototypowego.

__proto__nie jest standardowym sposobem uzyskiwania dostępu do łańcucha prototypów, należy zastosować standardowe, ale podobne podejście Object.getPrototypeOf(obj).

Poniższy kod dla instanceofoperatora daje lepsze zrozumienie:

instanceofOperator klasy obiektu zwraca, truegdy obiekt jest instancją klasy, a dokładniej, jeśli Class.prototypezostanie znaleziony w łańcuchu proto tego obiektu, wówczas obiekt jest instancją tej klasy.

function instanceOf(Func){
  var obj = this;
  while(obj !== null){
    if(Object.getPrototypeOf(obj) === Func.prototype)
      return true;
    obj = Object.getPrototypeOf(obj);
  }
  return false;
}      

Powyższą metodę można wywołać jako: instanceOf.call(object, Class)która zwraca true, jeśli obiekt jest instancją klasy.


2
Zastanawiałem się, dlaczego obiekt został prototypestworzony wewnętrznie? Czy można po prostu przypisać metody statyczne do samego obiektu funkcji. na przykład function f(a){this.a = a}; f.increment = function(){return ++this.a}? Dlaczego nie wybrano tej metody zamiast dodawania metod do prototypeobiektu? Działa to, jeśli f.__proto__ = gg jest klasą podstawową.
abhisekp

Być może prototypeobiekt został wybrany do współużytkowania, ponieważ tylko wyłączne właściwości konstruktora funkcji mogą być przechowywane w obiekcie konstruktora funkcji.
abhisekp

1
W rzeczywistości byłby to bałagan, ponieważ instanceofspowodowałby ({}) instanceof Function === truebrak możliwości rozróżnienia prototypów, jeśli prototypewłaściwość zostanie usunięta.
abhisekp

@abhisekp Co masz na myśli przez to: „To zadziała, jeśli f .__ proto__ = g, gdzie g jest klasą podstawową”. Nie wiem, czy to ma jakieś znaczenie, którego nie rozumiem, ale jeśli dodasz właściwości i metody w ten sposób, to gdy użyjesz newsłowa kluczowego do utworzenia instancji, właściwości i metody nie zostaną skopiowane nad.
doubleOrt,

66

Dobrym sposobem na myślenie o tym jest ...

prototypejest używany przez constructor()funkcje. To naprawdę powinno było się nazywać coś takiego,"prototypeToInstall" , ponieważ tak właśnie jest.

i __proto__jest to „zainstalowany prototyp” na obiekcie (który został utworzony / zainstalowany na obiekcie z tej constructor()funkcji)


2
Poparłem go, ale być może główną przyczyną było to, że zdanie „prototyp jest używany przez funkcje konstruktora ()” może brzmieć tak, jakby funkcje nie posiadające konstruktora nie miały, co nie jest prawdą, jednak poza tym nie skupiamy się teraz można zauważyć, że każda funkcja jest potencjalnie konstruktorem, jeśli zostanie wywołana z nowym ...
yoel halb

2
Zmień „ constructor()funkcje” na „funkcje konstruktora”, ponieważ może wystąpić pomyłka z „ __proto__.constructor()funkcjami”. Uważam to za ważne, ponieważ konstruktor __proto __ nie jest w rzeczywistości wywoływany, gdy newużywane jest słowo kluczowe.
Alexander Gonchiy,

1
Stwierdzenie, że „ prototyp jest używany przez funkcje konstruktora () ” mówi tylko o części ważnego faktu, ale powiedziało to w sposób, który prawdopodobnie skłania czytelników do myślenia, że ​​jest to cały fakt. prototyp jest tworzony wewnętrznie dla każdej deklaracji funkcji w Javascripcie, niezależnie od tego, jak ta funkcja będzie wywoływana w przyszłości - z nowym słowem kluczowym lub bez ; prototyp deklarowanej funkcji wskazuje na literał obiektu.
Yiling

62

Aby to wyjaśnić, stwórzmy funkcję

 function a (name) {
  this.name = name;
 }

Kiedy JavaScript wykonuje ten kod, dodaje prototypewłaściwość a, prototypewłaściwość jest obiektem z dwiema właściwościami:

  1. constructor
  2. __proto__

Więc kiedy to zrobimy

a.prototype powraca

     constructor: a  // function definition
    __proto__: Object

Teraz, jak widać, constructorjest tylko asama funkcja i __proto__wskazuje na główny poziom ObjectJavaScript.

Zobaczmy, co się stanie, gdy użyjemy afunkcji ze newsłowem kluczowym.

var b = new a ('JavaScript');

Kiedy JavaScript wykonuje ten kod, robi 4 rzeczy:

  1. Tworzy nowy obiekt, pusty obiekt // {}
  2. Tworzy __proto__on bi czyni to wskazywać a.prototypezarzutówb.__proto__ === a.prototype
  3. Wykonuje a.prototype.constructor(co jest definicją funkcji a) z nowo utworzonym obiektem (utworzonym w kroku 1) jako jego kontekst (ten), stąd namewłaściwość przekazana jako „JavaScript” (który jest dodawany this) zostaje dodana do nowo utworzonego obiektu.
  4. Zwraca nowo utworzony obiekt w (utworzony w kroku 1), więc var bzostaje przypisany do nowo utworzonego obiektu.

Teraz jeśli dodamy a.prototype.car = "BMW"i zrobimy b.car , pojawi się wyjście „BMW”.

dzieje się tak dlatego, że gdy JavaScript wykonał ten kod, w którym szukał carwłaściwości b, nie znalazł wtedy JavaScript używanego b.__proto__(który został stworzony, aby wskazywać na „a.prototyp” w kroku # 2) i znalazł carwłaściwość, więc zwróć „BMW”.


2
1. constructornie wraca a()! Powraca a. 2. __proto__zwraca Object.prototype, a nie obiekt główny w JavaScript.
doubleOrt,

1
To świetna odpowiedź!
john-raymon

+1 to najlepsza odpowiedź na wyjaśnienie, czym faktycznie jest prototyp (obiekt o dwóch właściwościach) i jak JavaScript wykonuje każdy fragment kodu. Te informacje są zaskakująco trudne do zdobycia.
java-addict301

53

Prototyp VS. __proto__ VS. [[Prototyp]]

Podczas tworzenia funkcji obiekt właściwości o nazwie prototyp jest tworzony automatycznie (sam go nie utworzyłeś) i jest dołączany do obiektu funkcji (the constructor).
Uwaga : Ten nowy prototypowy obiekt wskazuje również lub ma wewnętrzny-prywatny link do natywnego obiektu JavaScript.

Przykład:

function Foo () {
    this.name = 'John Doe';
}

// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true

// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
    return 'My name is ' + this.name;
}

Jeśli tworzysz nowy obiekt za Foopomocą newsłowa kluczowego, zasadniczo tworzysz (między innymi) nowy obiekt, który ma wewnętrzny lub prywatny link do Fooprototypu funkcji , o którym mówiliśmy wcześniej:

var b = new Foo();

b.[[Prototype]] === Foo.prototype  // true


Prywatny podnośnik do obiektu, który funkcję o nazwie podwójne wsporniki prototypów lub po prostu [[Prototype]]. Wiele przeglądarek zapewnia nam publiczny link do tego, który zadzwonił __proto__!

Mówiąc ściślej, __proto__to tak naprawdę funkcja pobierająca, która należy do natywnego obiektu JavaScript. Zwraca wewnętrzno-prywatne połączenie prototypowe dowolnego thispowiązania (zwraca [[Prototype]]z b):

b.__proto__ === Foo.prototype // true

Warto zauważyć, że od początku ECMAScript5można również użyć metody getPrototypeOf , aby uzyskać wewnętrzny prywatny link:

Object.getPrototypeOf(b) === b.__proto__ // true


UWAGA: ta odpowiedź nie zamierza obejmować cały proces tworzenia nowych obiektów lub nowych konstruktorów, lecz pomoc w lepszym zrozumieniu tego, co jest __proto__, prototypea [[Prototype]]i jak to działa.


2
@ Taurus, kliknij nagłówek, prowadzi to do specyfikacji specyfikacji ECMAScript. Sprawdź sekcję 9 (Zachowania obiektów zwykłych i egzotycznych), która wyjaśnia ją bardziej szczegółowo.
Lior Elrom

Myślę, że jest tu jakaś pomyłka: _ nowy obiekt, który ma wewnętrzny lub prywatny link do prototypu funkcji Foo_ Czy masz na myśli: nowy obiekt, który ma wewnętrzny lub prywatny link do prototypu funkcji Foo ?
Koray Tugay

1
Dzięki @KorayTugay! Tak,
popełniłem

30

Aby wyjaśnić to nieco powyżej powyższych świetnych odpowiedzi:

function Person(name){
    this.name = name
 }; 

var eve = new Person("Eve");

eve.__proto__ == Person.prototype //true

eve.prototype  //undefined

Instancje mają __proto__ , klasy mają prototyp .


12

W JavaScript funkcja może być używana jako konstruktor. Oznacza to, że możemy tworzyć z nich obiekty za pomocą nowego słowa kluczowego. Każda funkcja konstruktora ma wbudowany z nimi powiązany obiekt. Ten wbudowany obiekt nazywa się prototypem.Instances of a constructor function use __proto__ to access the prototype property of its constructor function.

schemat prototypowy

  1. Po pierwsze stworzyliśmy konstruktora: function Foo(){}. Żeby było jasne, Foo to kolejna funkcja. Ale możemy stworzyć z niego obiekt za pomocą nowego słowa kluczowego. Dlatego nazywamy to funkcją konstruktora

  2. Każda funkcja ma unikalną właściwość, która nazywa się właściwością prototypową. Tak więc funkcja konstruktora Fooma właściwość prototypu, która wskazuje na jej prototyp, którym jest Foo.prototype(patrz zdjęcie).

  3. Funkcje konstruktora same w sobie są funkcją, która jest instancją konstruktora systemu zwanego konstruktorem [[Funkcja]]. Możemy więc powiedzieć, że function Foojest konstruowany przez konstruktor [[Funkcja]]. Z __proto__naszej Foo functionstrony wskażemy prototyp jego konstruktora, którym jest Function.prototype.

  4. Function.prototypesam w sobie jest niczym innym jak obiektem zbudowanym z innego konstruktora systemowego o nazwie [[Object]]. Więc [[Object]]jest konstruktorem Function.prototype. Możemy więc powiedzieć, że Function.prototypejest to przypadek [[Object]]. Więc __proto__z Function.prototypepunktów Object.prototype.

  5. Object.prototypejest ostatnim człowiekiem stojącym w łańcuchu prototypów. Mam na myśli, że nie został zbudowany. Jest już w systemie. Więc to __proto__wskazuje na null.

  6. Teraz dochodzimy do przykładów Foo. Kiedy tworzymy instancję za pomocą new Foo(), tworzy nowy obiekt, który jest instancją Foo. Oznacza to, że Foojest konstruktorem tych instancji. Tutaj stworzyliśmy dwa wystąpienia (x i y). __proto__xiy wskazuje zatem na Foo.prototype.


Żeby było jasne: instancje nie mają właściwości .prototype? Tylko funkcja konstruktora, prawda? ... Więc różnica między instancją a jej funkcją konstruktora jest taka: funkcje konstruktora mają oba 1. proto 2. obiekt prototypowy, podczas gdy instancje mają tylko właściwość .__ proto__ ... prawda?
Shaz

@Shaz masz rację. instancje używają swojego proto, aby uzyskać dostęp do właściwości prototypu swojej funkcji konstruktora.
AL-zami

Ale dlaczego tak jest, kiedy piszesz: var car = Object.create (Vehicle); dostaniesz samochód .__ proto__ = Pojazd ALE masz również właściwość car.prototype, która wskazuje na Vehicle.prototype?
Shaz

@shaz czy możesz podać jsfiddle, dzięki czemu mogę wizualizować sytuację?
AL-zami

1
tutaj car.prototype jest odziedziczoną własnością. samochód dziedziczy właściwość „prototypu” po funkcji pojazdu. więc car.prototype === Vehicle.prototype. Właściwość „prototypowa” jest własnością pojazdu. samochód może uzyskać do niego dostęp poprzez prototypowy łańcuch. Mam nadzieję, że rozwiąże to twoje zamieszanie
AL-zami

8

Podsumowanie:

__proto__Właściwość obiektu jest właściwością, która mapuje do prototypefunkcji konstruktora obiektu. Innymi słowy:

instance.__proto__ === constructor.prototype // true

Służy to do tworzenia prototypełańcucha obiektu. prototypeŁańcucha odnośnika mechanizm właściwości dotyczących obiektu. W przypadku uzyskania dostępu do właściwości obiektu JavaScript najpierw sprawdzi obiekt. Jeśli nie ma tam nieruchomości, będzie się wspinać aż protochaindo jej znalezienia (lub nie)

Przykład:

function Person (name, city) {
  this.name = name;
}

Person.prototype.age = 25;

const willem = new Person('Willem');

console.log(willem.__proto__ === Person.prototype); // the __proto__ property on the instance refers to the prototype of the constructor

console.log(willem.age); // 25 doesn't find it at willem object but is present at prototype
console.log(willem.__proto__.age); // now we are directly accessing the prototype of the Person function 

Nasze pierwsze wyniki dziennika są true, ponieważ, jak wspomniano, __proto__właściwość instancji utworzonej przez konstruktor odnosi się doprototype właściwości konstruktora. Pamiętaj, że w JavaScript funkcje są również obiektami. Obiekty mogą mieć właściwości, a domyślną właściwością dowolnej funkcji jest jedna właściwość o nazwie prototyp.

Następnie, gdy funkcja ta zostanie wykorzystana jako funkcja konstruktora, utworzony z niej obiekt otrzyma właściwość o nazwie __proto__. Ta __proto__właściwość odnosi się do prototypewłaściwości funkcji konstruktora (która domyślnie ma każda funkcja).

Dlaczego to jest przydatne?

JavaScript ma mechanizm wyszukiwania właściwości, na Objectsktórym nazywa się „dziedziczenie prototypowe”. Oto, co robi w zasadzie:

  • Najpierw sprawdzane jest, czy właściwość znajduje się na samym obiekcie. Jeśli tak, ta właściwość jest zwracana.
  • Jeśli właściwość nie znajduje się na samym obiekcie, „wspina się po protochainie”. Zasadniczo patrzy na obiekt, do którego odnosi się __proto__właściwość. Tam sprawdza, czy właściwość jest dostępna dla obiektu, do którego odnosi się __proto__.
  • Jeśli właściwość nie znajduje się na __proto__obiekcie, będzie wspinać się po __proto__łańcuchu aż do Objectobiektu.
  • Jeśli nie może znaleźć właściwości nigdzie na obiekcie i jego prototypełańcuchu, zwróci undefined.

Na przykład:

function Person (name) {
  this.name = name;
}

let mySelf = new Person('Willem');

console.log(mySelf.__proto__ === Person.prototype);

console.log(mySelf.__proto__.__proto__ === Object.prototype);


7

Uczę się prototypu od You Don't Know JS: this & Object Prototypes , która jest wspaniałą książką do zrozumienia projektu poniżej i wyjaśnienia wielu nieporozumień (dlatego staram się unikać dziedziczenia i tym podobnych instanceof).

Ale mam takie samo pytanie, jak ludzie tutaj zadawali. Kilka odpowiedzi jest naprawdę pomocnych i pouczających. Chciałbym również podzielić się swoimi zrozumieniami.


Co to jest prototyp?

Obiekty w JavaScript mają wewnętrzną właściwość, oznaczoną w specyfikacji jako [[Prototype]], która jest po prostu odwołaniem do innego obiektu. Niemal wszystkie obiekty otrzymują nullw tej chwili wartość dla tej właściwości.

Jak zdobyć prototyp obiektu?

przez __proto__lubObject.getPrototypeOf

var a = { name: "wendi" };
a.__proto__ === Object.prototype // true
Object.getPrototypeOf(a) === Object.prototype // true

function Foo() {};
var b = new Foo();
b.__proto__ === Foo.prototype
b.__proto__.__proto__ === Object.prototype

Co to jest prototype?

prototypeto obiekt tworzony automatycznie jako specjalna właściwość funkcji , która służy do ustanowienia łańcucha delegowania (dziedziczenia), czyli łańcucha prototypów.

Kiedy tworzymy funkcję a, prototypejest ona automatycznie tworzona jako specjalna właściwość ai zapisuje kod funkcji jako constructorwłączony prototype.

function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true

Chciałbym rozważyć tę właściwość jako miejsce do przechowywania właściwości (w tym metod) obiektu funkcji. Z tego powodu funkcje narzędziowe w JS są zdefiniowane jako Array.prototype.forEach():Function.prototype.bind() ,Object.prototype.toString().

Dlaczego warto podkreślać właściwość funkcji ?

{}.prototype // undefined;
(function(){}).prototype // Object {constructor: function}

// The example above shows object does not have the prototype property.
// But we have Object.prototype, which implies an interesting fact that
typeof Object === "function"
var obj = new Object();

Więc Arary, Function, Objectsą wszystkie funkcje. Muszę przyznać, że to odświeża moje wrażenie na JS. Wiem, że funkcje są pierwszorzędnym obywatelem w JS, ale wydaje się, że jest on zbudowany na funkcjach.

Jaka jest różnica między __proto__i prototype?

__proto__referencja działa na każdym obiekcie i odnosi się do jego [[Prototype]]właściwości.

prototypeto obiekt tworzony automatycznie jako specjalna właściwość funkcji , która służy do przechowywania właściwości (w tym metod) obiektu funkcji.

Dzięki tym dwóm moglibyśmy mentalnie zmapować łańcuch prototypów. Jak to zdjęcie ilustruje:

function Foo() {}
var b = new Foo();

b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true

7

 Prototyp JavaScript vs __prototype__

'use strict'
function A() {}
var a = new A();
class B extends A {}
var b = new B();
console.log('====='); // =====
console.log(B.__proto__ === A); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(b.__proto__ === B.prototype); // true
console.log(a.__proto__ === A.prototype); // true
console.log(A.__proto__ === Function.__proto__); // true
console.log(Object.__proto__ === Function.__proto__); // true
console.log(Object.prototype === Function.__proto__.__proto__); // true
console.log(Object.prototype.__proto__ === null); // true

W JavaScript każdy obiekt (funkcja też jest obiektem!) Ma __proto__właściwość, właściwość odnosi się do jej prototypu.

Kiedy użyjemy newoperatora z konstruktorem do utworzenia nowego obiektu, właściwość nowego obiektu __proto__zostanie ustawiona za pomocą prototypewłaściwości konstruktora , następnie konstruktor zostanie wywołany przez nowy obiekt, w tym procesie „to” będzie odwołaniem do nowego obiektu w zakresie konstruktora zwróć nowy obiekt.

Prototyp Konstruktora jest __proto__własnością, własnością Konstruktora prototypejest praca z newoperatorem.

Konstruktor musi być funkcją, ale funkcja nie zawsze jest konstruktorem, nawet jeśli ma prototypewłaściwość.

Łańcuch prototypowy faktycznie jest __proto__właściwością obiektu, która odnosi się do jego prototypu, i właściwością prototypu, __proto__która odnosi się do prototypu prototypu i tak dalej, aż do odniesienia do __proto__właściwości prototypu Object, która jest wartością zerową.

Na przykład:

console.log(a.constructor === A); // true
// "a" don't have constructor,
// so it reference to A.prototype by its ``__proto__`` property,
// and found constructor is reference to A

[[Prototype]]a __proto__własność to właściwie to samo.

Możemy użyć metody getPrototypeOf Objecta, aby uzyskać coś prototypu.

console.log(Object.getPrototypeOf(a) === a.__proto__); // true

Każda napisana przez nas funkcja może być użyta do stworzenia obiektu za pomocą newoperatora, więc każda z tych funkcji może być konstruktorem.


6

Kolejny dobry sposób, aby to zrozumieć:

var foo = {}

/* 
foo.constructor is Object, so foo.constructor.prototype is actually 
Object.prototype; Object.prototype in return is what foo.__proto__ links to. 
*/
console.log(foo.constructor.prototype === foo.__proto__);
// this proves what the above comment proclaims: Both statements evaluate to true.
console.log(foo.__proto__ === Object.prototype);
console.log(foo.constructor.prototype === Object.prototype);

Dopiero po __proto__obsługiwaniu IE11 . Przed tą wersją, takich jak IE9, można użyć constructor, aby uzyskać __proto__.


Tyle że napisałbym to na odwrót: foo .__ proto__ === foo.constructor.prototype
epeleg

6

prototyp

prototyp jest własnością funkcji. Jest to schemat tworzenia obiektów za pomocą tej funkcji (konstruktora) z nowym słowem kluczowym.

__proto__jest używany w łańcuchu wyszukiwania do rozpoznawania metod i właściwości. gdy obiekt jest tworzony (przy użyciu funkcji konstruktora z nowym słowem kluczowym), __proto__jest ustawiany na (Constructor) Function.prototype

function Robot(name) {
    this.name = name;
}
var robot = new Robot();

// the following are true   
robot.__proto__ == Robot.prototype
robot.__proto__.__proto__ == Object.prototype

Oto moje (wyobrażone) wyjaśnienie, aby usunąć zamieszanie:

Wyobraź sobie, że istnieje wyimaginowana klasa (plan / kuter coockie) związana z funkcją. Ta wyobrażona klasa służy do tworzenia obiektów. prototypejest mechanizmem rozszerzenia (metoda rozszerzenia w C # lub Swift Extension) w celu dodania rzeczy do tej wyimaginowanej klasy.

function Robot(name) {
    this.name = name;
}

Powyższe można sobie wyobrazić jako:

// imaginary class
class Robot extends Object{

    static prototype = Robot.class  
    // Robot.prototype is the way to add things to Robot class
    // since Robot extends Object, therefore Robot.prototype.__proto__ == Object.prototype

    var __proto__;

    var name = "";

    // constructor
    function Robot(name) {

        this.__proto__ = prototype;
        prototype = undefined;

        this.name = name;
    }

} 

Więc,

var robot = new Robot();

robot.__proto__ == Robot.prototype
robot.prototype == undefined
robot.__proto__.__proto__ == Object.prototype

Teraz dodajemy metodę do prototyperobota:

Robot.prototype.move(x, y) = function(x, y){ Robot.position.x = x; Robot.position.y = y};
// Robot.prototype.move(x, y) ===(imagining)===> Robot.class.move(x, y)

Powyższe można sobie wyobrazić jako rozszerzenie klasy Robot:

// Swift way of extention
extension Robot{
    function move(x, y){    
        Robot.position.x = x; Robot.position.y = y
    }
}

Co z kolei

// imaginary class
class Robot{

    static prototype = Robot.class // Robot.prototype way to extend Robot class
    var __proto__;

    var name = "";

    // constructor
    function Robot(name) {

        this.__proto__ = prototype;
        prototype = undefined;

        this.name = name;
    }

    // added by prototype (as like C# extension method)
    function move(x, y){ 
        Robot.position.x = x; Robot.position.y = y
    };
}

wciąż myślę o bardziej spójnych nazwach __proto__i prototypach. może prototyp i dziedzictwo?
Dmitry

Powiedziałbym, prototypei __proto__należy unikać obu. Mamy teraz zajęcia i lubię OOP.
Hassan Tareq

problem polega na tym, że klasa jest stosunkowo nowa i nie jest obsługiwana przez naprawdę wygodne silniki, takie jak Microsoft JScript (miło mieć go podczas pracy na C i potrzebować szybkiego i brudnego silnika skryptowego, który zawsze tam jest) oraz javascript nashorn (który jest dostarczany ze wszystkimi nowe instalacje Java pod jjs i jest to dobry sposób na przeniesienie Javy do czysto dynamicznego środowiska, w którym nie trzeba ciągle rekompilować rzeczy). Chodzi o to, że jeśli klasa była cukrem, nie byłoby problemu, ale tak nie jest, oferuje rzeczy, które są niemożliwe bez nich w starszych wersjach js. Jak rozszerzenie „Funkcji”.
Dmitry

W końcu otrzymamy wsparcie. Jestem programistą backendowym, więc nie mam problemów, rzadko koduję js.
Hassan Tareq

i dziedziczenie elementów statycznych w taki sposób, że dodawanie nowych / usuwanie elementów statycznych z elementu nadrzędnego jest zauważane przez dziecko (czego nie mogę wymyślić w JScript, który nie oferuje Object.assign / __ proto __ / getPrototypeOf, więc możesz majstrować przy głównym prototypie Object.prototype, aby go zasymulować)
Dmitry

4

Krótko mówiąc:

> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true

Pozwala to na dołączanie właściwości do X.prototypu PO utworzeniu instancji obiektów typu X i nadal będą one uzyskiwać dostęp do tych nowych właściwości za pomocą odwołania __proto__, którego silnik JavaScript używa do przejścia do łańcucha prototypów.


4

Prototyp lub Object.prototype jest właściwością literału obiektu. Reprezentuje obiekt prototypowy Object, który można przesłonić, aby dodać więcej właściwości lub metod dalej w łańcuchu prototypów.

__proto__ to właściwość akcesorium (funkcja get and set), która udostępnia wewnętrzny prototyp obiektu, do którego jest on dostępny.

Bibliografia:

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
  2. http://www.w3schools.com/js/js_object_prototypes.asp

  3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto


Object.prototypenie jest własnością literału obiektu, próbującego wydrukować {}.prototypeniezdefiniowane zwroty; można jednak uzyskać do niego dostęp za pośrednictwem {}.__proto__, który zwraca Object.prototype.
doubleOrt,

3

Wiem, że się spóźniam, ale pozwól mi to uprościć.

Powiedzmy, że jest funkcja

    function Foo(message){

         this.message = message ; 
     };

     console.log(Foo.prototype);

Funkcja Foo będzie połączona z obiektem prototypowym. Tak więc, ilekroć tworzymy funkcję w JavaScript, zawsze łączy się z nią obiekt prototypowy.

Przejdźmy teraz do stworzenia dwóch obiektów za pomocą funkcji Foo.

    var a = new Foo("a");
    var b = new Foo("b");
    console.log(a.message);
    console.log(b.message);
  1. Teraz mamy dwa obiekty, obiekt a i obiekt b. Oba są tworzone za pomocą konstruktora Foo. Pamiętaj, że konstruktor to tylko jedno słowo.
  2. Oba obiekty a i b mają kopię właściwości wiadomości.
  3. Te dwa obiekty a i b są połączone z prototypowym obiektem konstruktora Foo.
  4. Na obiektach aib możemy uzyskać dostęp do prototypu Foo za pomocą właściwości proto we wszystkich przeglądarkach, aw IE można użyć Object.getPrototypeOf (a) lub Object.getPrototypeOf (b)

Teraz Foo.prototype, a. proto , i b. proto all oznacza ten sam obiekt.

    b.__proto__ === Object.getPrototypeOf(a);
    a.__proto__ ===  Foo.prototype;
    a.constructor.prototype  === a.__proto__;

wszystkie powyższe zwróciłyby prawdę.

Jak wiemy, właściwości JavaScript można dodawać dynamicznie. Możemy dodać właściwość do obiektu

    Foo.prototype.Greet = function(){

         console.log(this.message);
    }
    a.Greet();//a
    b.Greet();//b
    a.constructor.prototype.Greet();//undefined 

Jak widać dodaliśmy metodę Greet () w Foo.prototype, ale jest ona dostępna w aib lub w dowolnym innym obiekcie zbudowanym przy użyciu Foo.

Podczas wykonywania funkcji a.Greet () JavaScript najpierw przeszuka Pozdrowienie w obiekcie a na liście właściwości. Nie znajdując, przejdzie w górę w łańcuchu proto . Ponieważ. proto i Foo.prototype to ten sam obiekt, JavaScript znajdzie metodę Greet () i wykona ją.

Mam nadzieję, że teraz prototyp i proto są nieco uproszczone.


3

Przykład wyjaśniający:

function Dog(){}
Dog.prototype.bark = "woof"

let myPuppie = new Dog()

teraz myPupppie ma __proto__właściwość, która wskazuje na Dog.prototype.

> myPuppie.__proto__
>> {bark: "woof", constructor: ƒ}

ale myPuppie NIE ma właściwości prototypowej.

> myPuppie.prototype
>> undefined

Tak więc, __proto__mypuppie to odwołanie do właściwości .prototype funkcji konstruktora, która została użyta do utworzenia tego obiektu (a bieżący obiekt myPuppie ma relację „deleguje się” do tego __proto__obiektu), podczas gdy właściwość .prototype myPuppie jest po prostu nieobecna (ponieważ nie ustawiliśmy tego).

Dobre wyjaśnienie MPJ tutaj: proto vs prototyp - Tworzenie obiektów w JavaScript


3

Zrobiłem dla siebie mały rysunek przedstawiający następujący fragment kodu:

var Cat = function() {}
var tom = new Cat()

Zrozumienie __proto__ i prototypu

Mam klasyczne tło OO, więc pomocne było reprezentowanie hierarchii w ten sposób. Aby pomóc Ci przeczytać ten diagram, traktuj prostokąty na obrazie jako obiekty JavaScript. I tak, funkcje są również obiektami. ;)

Obiekty w JavaScript mają właściwości i __proto__jest tylko jednym z nich.

Ideą tej właściwości jest wskazanie obiektu przodka w hierarchii (dziedziczenia).

Obiektem głównym w JavaScript jest Object.prototypei wszystkie inne obiekty są potomkami tego obiektu. __proto__Właściwości obiektu głównego jest null, co oznacza zakończenie łańcucha spadku.

Zauważysz, że prototypejest to właściwość funkcji. Catjest funkcją, ale także Functioni Objectsą funkcjami (natywnymi). tomnie jest funkcją, dlatego nie ma tej właściwości.

Ideą tej właściwości jest wskazanie obiektu, który zostanie użyty w konstrukcji, tj. Kiedy wywołasz newoperatora dla tej funkcji.

Zauważ, że obiekty prototypowe (żółte prostokąty) mają inną właściwość o nazwie, constructorktóra wskazuje na odpowiedni obiekt funkcji. Ze względów zwięzłości nie zostało to przedstawione.

Rzeczywiście, kiedy tworzymy tomobiekt za pomocą new Cat(), utworzony obiekt będzie miał __proto__właściwość ustawioną na prototypeobiekt funkcji konstruktora.

Na koniec zagrajmy trochę z tym diagramem. Następujące stwierdzenia są prawdziwe:

  • tom.__proto__właściwość wskazuje na ten sam obiekt co Cat.prototype.

  • Cat.__proto__wskazuje na Function.prototypeobiekt, podobnie jak Function.__proto__i Object.__proto__zrobić.

  • Cat.prototype.__proto__i tom.__proto__.__proto__wskaż ten sam obiekt i to znaczy Object.prototype.

Twoje zdrowie!


Bardzo dobrze wyjaśnione!
StackOverflow UI

@theshinylight, tom.__proto__i Cat.prototypesą ściśle równe, więc tom.__proto__ === Cat.prototype i Cat.prototype === tom.__proto__są prawdziwe. Co masz na myśli przez strzałkę na obrazku?
aXuser264

Czarna strzałka (jeśli się do niej odwołujesz) nie ma żadnego szczególnego znaczenia poza właściwością obiektu. Podobnie jak prototypewłasność Catobiektu (z twojego pytania).
theshinylight

2

DEFINICJE

(liczba w nawiasie () to „link” do kodu napisanego poniżej)

prototype- obiekt, który składa się z:
=> funkcje (3) tego konkretnego ConstructorFunction.prototype(5), które są dostępne dla każdego obiektu (4) utworzonego lub utworzonego za pomocą tej funkcji konstruktora (1)
=> samą funkcję konstruktora (1) )
=>__proto__ tego konkretnego obiektu (obiekt prototypowy)

__proto__ (dandor proto?) - łącze MIĘDZY dowolnym obiektem (2) utworzonym za pomocą określonej funkcji konstruktora (1) ORAZ właściwościami obiektu prototypu (5) tego konstruktora, KTÓRE umożliwiają każdemu utworzonemu obiektowi (2) dostęp do funkcji prototypu i metody (4) (__proto__ domyślnie są zawarte w każdym obiekcie w JS)

WYJAŚNIENIE KODU

1.

    function Person (name, age) {
        this.name = name;
        this.age = age;} 

2)

    var John = new Person(‘John’, 37);
    // John is an object

3)

    Person.prototype.getOlder = function() {
        this.age++;
    }
    // getOlder is a key that has a value of the function

4

    John.getOlder();

5

    Person.prototype;

1

Spróbuję wyjaśnienia czwartej klasy:

Rzeczy są bardzo proste. A prototypejest przykładem tego, jak należy coś zbudować. Więc:

  • Jestem functioni buduję nowe obiekty podobne do moichprototype

  • Jestem objecti zostałem zbudowany na moim __proto__przykładzie

dowód :

function Foo() { }

var bar = new Foo()

// `bar` is constructed from how Foo knows to construct objects
bar.__proto__ === Foo.prototype // => true

// bar is an instance - it does not know how to create objects
bar.prototype // => undefined

1
Nie, ani prototypeani nie __proto__są używane w dowolnym momencie jako plan do stworzenia dowolnego obiektu. To mit wprowadzony przez rozmytą classskładnię i jej poprzedników. Jak mówi post z odpowiedzią, jest on po prostu używany w łańcuchu wyszukiwania iw przypadku prototypeidentyfikacji constructorużywany new(który jest częścią tego mechanizmu udawania, że ​​ma klasę, co dezorientuje wielu użytkowników, w tym mnie).
Christof Kälin

Pierwszym punktem powinno być: „Jestem funkcją i buduję nowe obiekty, które będą delegować na mój prototyp”
Nitin Jadhav,

1

Każda tworzona funkcja ma właściwość o nazwie prototypei zaczyna życie jako pusty obiekt. Ta właściwość nie ma zastosowania, dopóki nie użyjesz tej funkcji jako funkcji konstruktora, tj. Ze słowem kluczowym „new”.

Jest to często mylone z __proto__właściwością obiektu. Niektórzy mogą się pomylić i poza tym, że prototypewłaściwość obiektu może uzyskać proto obiektu. Ale tak nie jest. prototypesłuży do uzyskania __proto__obiektu utworzonego z konstruktora funkcji.

W powyższym przykładzie:

function Person(name){
    this.name = name
}; 

var eve = new Person("Eve");

console.log(eve.__proto__ == Person.prototype) // true
// this is exactly what prototype does, made Person.prototype equal to eve.__proto__

Mam nadzieję, że to ma sens.


1
prototypenie jest używany do tworzenia __proto__obiektu. __proto__, po uzyskaniu dostępu, stanowi jedynie odniesienie do prototypeobiektu.
doubleOrt

1

Co z użyciem __proto__metod statycznych?

function Foo(name){
  this.name = name
  Foo.__proto__.collection.push(this)
  Foo.__proto__.count++

}

Foo.__proto__.count=0
Foo.__proto__.collection=[]

var bar = new Foo('bar')
var baz = new Foo('baz')

Foo.count;//2
Foo.collection // [{...}, {...}]
bar.count // undefined

Właśnie dlatego odpowiedź na __proto__VS. prototypew JavaScript” ?
Andreas

czy to dobrze, a co z Foo.collection.push (this) Foo.count ++
Selva Ganapathi

1

(function(){ 
      let a = function(){console.log(this.b)};
      a.prototype.b = 1;
      a.__proto__.b = 2;
      let q = new a();
      console.log(a.b);
      console.log(q.b) 
    })()

Wypróbuj ten kod, aby zrozumieć


1

Jest tylko jeden obiekt, który jest używany do łączenia łańcuchowego. Ten obiekt ma oczywiście nazwę i wartość: __proto__jest jego nazwą i prototypewartością. To wszystko.

aby jeszcze łatwiej zrozumieć, spójrz na diagram na górze tego postu (Diagram autorstwa Dmitrija Soshnikova), nigdy nie znajdziesz __proto__punktów do czegoś innego niż prototypejako jego wartość.

Istota jest taka: __proto__to nazwa, która odwołuje się do obiektu prototypowego i prototypejest rzeczywistym obiektem prototypowym.

To tak, jakby powiedzieć:

let x = {name: 'john'};

xjest nazwą obiektu (wskaźnikiem) i {name: 'john'}jest rzeczywistym obiektem (wartością danych).

UWAGA: to tylko ogromnie uproszczona wskazówka, w jaki sposób są one powiązane na wysokim poziomie.

Aktualizacja: Oto prosty konkretny przykład javascript dla lepszej ilustracji:

let x = new String("testing") // Or any other javascript object you want to create

Object.getPrototypeOf(x) === x.__proto__; // true

Oznacza to, że gdy Object.getPrototypeOf(x)dostaje nam rzeczywistą wartość x(co jest jego prototyp) jest dokładnie to, co __proto__od xwskazuje. Dlatego __proto__rzeczywiście wskazuje na prototyp x. Zatem __proto__referencje x(wskaźnik x) i prototypejest wartościąx (jego prototypu).

Mam nadzieję, że teraz jest to trochę jasne.


1

To bardzo ważne pytanie istotne dla każdego, kto chce zrozumieć dziedzictwo prototypowe. Z tego, co rozumiem, prototyp jest domyślnie przypisywany, gdy obiekt jest tworzony przy użyciu nowego z funkcji, ponieważ funkcja ma obiekt prototypowy z definicji:

function protofoo(){
}
var protofoo1 = new protofoo();
console.log(protofoo.prototype.toString()); //[object Object]

Kiedy tworzymy zwykły obiekt bez nowego, tzn. Jawnie z funkcji, nie ma on prototypu, ale ma pusty proto, któremu można przypisać prototyp.

var foo={
  check: 10
};
console.log(foo.__proto__); // empty
console.log(bar.prototype); //  TypeError
foo.__proto__ = protofoo1; // assigned
console.log(foo.__proto__); //protofoo

Możemy użyć Object.create do jawnego połączenia obiektu.

// we can create `bar` and link it to `foo`
var bar = Object.create( foo );
bar.fooprops= "We checking prototypes";
console.log(bar.__proto__); // "foo"
console.log(bar.fooprops); // "We checking prototypes"
console.log(bar.check); // 10 is delegated to `foo`

0

__proto__jest podstawą do skonstruowania prototypei funkcją konstruktora, np .: function human(){}has, prototypektóra jest współdzielona __proto__w nowej instancji funkcji konstruktora. Bardziej szczegółowe przeczytaj tutaj


@Derick Daniel: nie jestem pewien, dlaczego głosowałeś w tej sprawie, ale dokonana przez ciebie edycja nie była tym, co próbowałem przekazać. Zmodyfikowałem to dalej, aby uzyskać więcej odprawy :).
Jyoti Duhan

Jyoti, nie poddałem się głosowaniu na twoją odpowiedź, ktoś inny, właśnie ją zredagowałem :)
Freelancer

0

Jak to słusznie stwierdzono

__proto__jest rzeczywistym obiektem używanym w łańcuchu wyszukiwania do rozwiązywania metod itp. prototyp to obiekt używany do budowania __proto__podczas tworzenia obiektu z nowym:

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

Możemy ponadto zauważyć, że __proto__właściwość obiektu utworzonego za pomocą konstruktora funkcji wskazuje na lokalizację pamięci wskazywaną przez prototyp właściwość tego odpowiedniego konstruktora.

Jeśli zmienimy lokalizację pamięci prototypu funkcji konstruktora, __proto__obiekt pochodny będzie nadal wskazywał na pierwotną przestrzeń adresową. Dlatego, aby udostępnić wspólną właściwość w łańcuchu dziedziczenia, zawsze dołączaj właściwość do prototypu funkcji konstruktora , zamiast go ponownie inicjować (co zmieniłoby jego adres pamięci).

Rozważ następujący przykład:

function Human(){
    this.speed = 25;
}

var himansh = new Human();

Human.prototype.showSpeed = function(){
    return this.speed;
}

himansh.__proto__ === Human.prototype;  //true
himansh.showSpeed();    //25

//now re-initialzing the Human.prototype aka changing its memory location
Human.prototype = {lhs: 2, rhs:3}

//himansh.__proto__ will still continue to point towards the same original memory location. 

himansh.__proto__ === Human.prototype;  //false
himansh.showSpeed();    //25

-1

rozumiem: __proto__ i prototyp są obsługiwane dla techniki łańcucha prototypów. różnica polega na tym, że funkcje o nazwie z podkreśleniem (jak __proto__) nie są przeznaczone dla programistów wywoływanych w ogóle. innymi słowy, są one tylko dla niektórych mechanizmów, takich jak dziedziczenie itp., są „zapleczem”. ale funkcje nazwane bez podkreślenia są zaprojektowane do jawnego wywoływania, są one „front-end”.


3
Są bardziej __proto__i prototype, niż tylko konwencji nazewnictwa. Mogą, ale nie muszą, wskazywać na ten sam obiekt. Zobacz odpowiedź @zyklus.
demisx

1
@ demisx oczywiście powiedziałeś, że ma rację, ale moim zdaniem różnica nazw ujawniła kontrast funkcjonalności.
Beicai

Nie wystarczy tylko
napisać

-3

!!! TO NAJLEPSZE WYJAŚNIENIE NA ŚWIECIE !!!!!

var q = {}
var prototype = {prop: 11}

q.prop // undefined
q.__proto__ = prototype
q.prop // 11

w konstruktorach funkcji silnik javascript wywołuje to q.__proto__ = prototypeautomatycznie podczas pisania new Class, a także do __proto__zestawu propClass.prototype

function Class(){}
Class.prototype = {prop: 999} // set prototype as we need, before call new

var q = new Class() // q.__proto__ = Class.prototype
q.prop // 999

Cieszyć się %)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.