• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[JavaScript] Problem z typem obiektu zwracanym przez konstruktor.

VPS Starter Arubacloud
+1 głos
516 wizyt
pytanie zadane 15 kwietnia 2016 w JavaScript przez iwan9449 Pasjonat (20,810 p.)

Witam, problem wygląda następująco. Tworzę prosty konstruktor Person, następnie za pomocą tego konstruktora tworzę sobie obiekt person1. Z tego co jest mi wiadome konstruktor powinien sam niejawnie zwrócić obiekt typu Person, niestety obiekt stworzony za pomocą tego konstruktora jest typu Object.

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

Person.prototype.sayHello = function() {
    return this.fName + " " + this.lName;
};

var person1 = new Person("Jan", "Kowalski");

 

 

 

 

 


 

Bardzo proszę o pomoc.

Pozdrawiam!

2 odpowiedzi

+1 głos
odpowiedź 15 kwietnia 2016 przez Comandeer Guru (599,730 p.)

Hmm…

Ale przecież obiekt person1 jest instancją stworzoną przez konstruktor Person:

person1 instanceof Person; // true

Trudno, żeby obiekt… nie był typu object ;) Natomiast widzę, że interesujesz się własnością _proto_, która określa nic innego jak obecnie wykorzystywany prototyp danego obiektu. To, co Cię niepokoi, to po prostu stwierdzenie faktu, że… prototyp Twojego obiektu jest obiektem. Tyle. Nic nadzwyczajnego – wręcz bym się martwił, gdyby było tam co innego niż Object ;)

 

komentarz 15 kwietnia 2016 przez iwan9449 Pasjonat (20,810 p.)
Rozumiem, że prototyp jet obiektem, ale zastanawia mnie fakt dlaczego nie jest obiektem "klasy" Person. Ogólnie mój problem miał podłoże nieco wyżej, otóż próbowałem stworzyć coś w stylu dziedziczenia wielopoziomowego na przykładzie figur (Shape, Rectangle, Square, Triangle) i ku mojemu zdziwieniu np.: klasa Rectangle jako proto miała obiekt Object (w moim domyśle powinna mieć Shape), a klasa Shape jako prototyp miała obiekt Rectangle. Chwilowo nie mam możliwości wrzucić kodu, później postaram się go dodać. W każdym razie dzięki za odpowiedź :)

Pozdrawiam!
komentarz 15 kwietnia 2016 przez Comandeer Guru (599,730 p.)

Podejrzewam, że masz tam coś typu:

Shape.prototype = new Rectangle();

Czyli klasyczny sposób dziedziczenia w JS ;) W tym wypadku owszem, __proto__ będzie wskazywać na Rectangle. Chrome pokazuje konstruktor użyty do stworzenia prototypu. W tym wypadku użyłeś konstruktora Rectangle. Przy "normalnym" prototypie mamy do czynienia z normalnym obiektem, stąd jest Object.

komentarz 15 kwietnia 2016 przez iwan9449 Pasjonat (20,810 p.)

Mój kod wygląda w ten sposób: 

function Shape(sideLengths) {
    this._name = "";
    this._sideLengths = sideLengths;
}

Shape.prototype.getPerimeter = function() {
    return this._sideLengths.reduce(function(preVal, val) {
        return preVal + val;    
    });
};

Shape.prototype.getArea = function() {
    return this._sideLengths[0] * this._sideLengths[1];  
};

function Rectangle(sideLengths) {
    Shape.call(this, [sideLengths[0], sideLengths[1], sideLengths[0], sideLengths[1]]);
    this._name = "Prostokąt";
}

Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

function Square(sideLength) {
    Rectangle.call(this, [sideLength, sideLength]);
    this._name = "Kwadrat";
}

Shape.prototype = Object.create(Rectangle.prototype);
Shape.prototype.constructor = Shape;

Na mój rozum powino to wyglądać mniej więcej tak: 

Obiekt klasy Rectangle powinien dziedziczyć z prototypu Rectangle, natopmiast prototyp rectangle powinien dziedziczyć z prototypu Shape i na końcu łańcucha Shape powninien dziedziczyć z Object. Lecz wbrew moim przewidywaniom struktura wygląda zupełnie inaczej. Jak dla mnie dość niezrozumiale.

Pozdrawiam!

komentarz 15 kwietnia 2016 przez Comandeer Guru (599,730 p.)

No jest dokładnie tak, jak wspominałem w poprzednim komentarzu (z tym, że zamiast new Shape masz Object.create( Shape )). Stąd tam się pojawia Shape zamiast Object.

komentarz 15 kwietnia 2016 przez iwan9449 Pasjonat (20,810 p.)
Ok, tylko problem jest taki, że de facto dziedziczenie u mnie nie działa, Stworzyłem sobie taraz instancję klasy Square (var square1 = new Square(10);) i nie jestem w stanie wywołać na tym obiekcie metod znajdujących się w prototypie Shape (getPerimeter i getArea). Poza tym korzystając z instanceof wynika, że mój obiekt square1 jest instancją klasy Square, ale nie jest instancją klasy Rectangle i Shape (a teoretycznie powinien być). Chciałbym po prostu wiedzieć jak stworzyć taką hierarchię dziedziczenia w JS.

Pozdrawiam!
komentarz 15 kwietnia 2016 przez Comandeer Guru (599,730 p.)
Shape.prototype = Object.create(Rectangle.prototype);
Shape.prototype.constructor = Shape;

Bo tutaj to chyba powinno być Square, a nie Shape ;)

komentarz 15 kwietnia 2016 przez iwan9449 Pasjonat (20,810 p.)
Konkretna odpowiedź, dzięki wielkie, drobne przeoczenie, a problem na cały dzień :D Teraz wszystko działa jak należy. Jeszcze raz dzięki wielkie za pomoc :)
0 głosów
odpowiedź 15 kwietnia 2016 przez ScriptyChris Mędrzec (190,190 p.)
edycja 15 kwietnia 2016 przez ScriptyChris

Polecam zapoznać się z dokumentacją polecenia typeof w JavaScript

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof

oraz typami danych:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures

W JS obiekty są typu "object". Nie ma tutaj klasycznie rozumianej obiektowości, jak np. w Java/C++/C#. W JS obiekt, to tzw. zbiór danych "klucz - wartość", w którym możesz umieszczać tablice, funkcje, obiekty - możesz to również zagnieżdżać.

Jeśli już przy obiektowości jesteśmy, to zwróć uwagę, że w JS natywnie nie masz dziedziczenia wg Klas (jak w innych językach obiektowych), ale masz dziedziczenie poprzez łańcuch prototype. Każdy obiekt JS ma globalny __proto__ (widać go zresztą u Ciebie na screenie), którego nie zaleca się zmieniać, gdyż wtedy możesz zaburzyć łańcuch dziedziczenia. Natomiast własność prototype możesz jak najbardziej zmieniać, a raczej dopisywać do niej (bo jest to obiekt) wartości takie jak np. funkcje, które mają być dostępne dla innych obiektów dziedziczących z tego obiektu.

W prostym sposób wyjaśnione dziedziczenie prototypowe znajdziesz np. tu (autor filmu także ma w playliście tutoriale m.in. o obiektach i ich tworzeniu w JS - więc możesz się zapoznać):

https://www.youtube.com/watch?v=pjsSPDJPUAI&index=15&list=PLGC-hHIh7l5vs0uDGlQEXQGQR2hW8Gcwl

Dokumentacja:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

W każdym razie obiekty i obiektowość w JavaScript jest trochę inna od tej klasycznej. Nie jestem pewien, ale bodajże w TypeScript (odmiana JavaScript) ta obiektowość jest bardziej klasyczna niż w "zwykłym" JavaScript.

komentarz 15 kwietnia 2016 przez iwan9449 Pasjonat (20,810 p.)

Dzięki za kanał, całkiem przystępnie przedstawiona wiedza :) Nie do końca dokładnie określiłem z czym mam problem, oczywiście typeof wywołany obiektu zawsze zwróci obiekt (mój błąd), chodziło mi raczej o nazwę prototypu mojej "klasy" person. W moim przypadku jest to prototyp "Object", natomiast w kursie, który przerabiam nazwa prototypu jest taka jak nazwa "klasy" czyli Person.

Tak to wygląda w moim kursie:

A tak wygląda to u mnie:

Nie wiem dlaczego tak się dzieje i proszę o jakieś wyjaśnienie :)

Pozdrawiam!

komentarz 15 kwietnia 2016 przez ScriptyChris Mędrzec (190,190 p.)

Hmm... bo jest coś takiego jak Function.prototype i Object.prototype. Możliwe, że w tym kursie jest omawiany Function.prototype

http://stackoverflow.com/a/11249437/4983840

Nie znam różnicy, bo przed chwilą się o tym dowiedziałem :) Choć wiedziałem że funkcje są obiektami w JS.

Comandeer - mógłbyś to wyjaśnić :)?

 

komentarz 15 kwietnia 2016 przez Comandeer Guru (599,730 p.)

Podałem wyjaśnienie wyżej. Na _proto_ zazwyczaj się nie zwraca uwagi, bo to tak naprawdę wewnętrzna własność w JS-ie.

Podobne pytania

0 głosów
1 odpowiedź 1,049 wizyt
pytanie zadane 22 lutego 2018 w JavaScript przez sosick Nowicjusz (160 p.)
0 głosów
1 odpowiedź 170 wizyt
0 głosów
1 odpowiedź 420 wizyt
pytanie zadane 28 kwietnia 2018 w C i C++ przez konu33 Nowicjusz (210 p.)

92,454 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...