2013-03-07 12 views
6

W JavaScript, mówi się, że literały obiektów mają połączenie prototypowe, ale obiekty funkcji mają zarówno łączenie prototypowe, jak i właściwość prototypu.JavaScript Dziedziczenie i obiekt Literalny

Czy na podstawie powyższego można stwierdzić, że dziedziczenie (które wykorzystuje własność prototypu) jest możliwe tylko z obiektami funkcyjnymi (wersja konstruktorska), a nie z literałami obiektów?

Ponadto, aby dodać właściwość __proto__ nie jest dostępna we wszystkich przeglądarkach ...

+1

Nie można zmienić prototyp istniejącego obiektu lub podaj prototyp przy użyciu obiekt dosłowne, więc, jeśli dobrze rozumiem pytanie, powiedziałbym tak. –

+0

Tak więc odnosi się to do większości zachowań przeglądarki (z wyjątkiem kilku takich jak Firefox, które pozwalają ustawić link "__proto__") ... Więc można powiedzieć Dziedziczenie może być zaimplementowane za pomocą literału Object (ale tylko w przeglądarkach, które pozwalają na ustawienie __proto__ link, np. Firefox)? – testndtv

+0

Literały obiektów dziedziczą po prostu od 'Object.prototype', więc nadal dostajesz dziedziczenie, ale obecnie nie możesz ustawić dłuższego łańcucha prototypów, niż przy użyciu składni literalnej, jak to możliwe z konstruktorami. A konstruktorzy nie są jedyną drogą. Zamiast tego możesz użyć 'Object.create'. –

Odpowiedz

2

Krótka wersja:

Tak: łańcuch prototypów nie można skonfigurować lub zmodyfikowany poprzez przypisanie do właściwość obiektu prototype. Nie można ustawić dziedziczenia, tworząc obiekt z literałem obiektu, a następnie nadając mu właściwość o nazwie prototype. Taka właściwość będzie nosiła nazwę prototype, ale nie będzie brana pod uwagę w przypadku prototypowego dziedziczenia.

Longer:

Jeśli dostęp do nieruchomości, która jest undefined, sprawdzana jest łańcuch dziedziczenia danego obiektu. Tak więc, jeśli obj['prop'] jest undefined, to zostanie zaznaczone obj.prototype['prop']. W wielu przeglądarkach właściwość prototype jest implementowana wewnętrznie jako właściwość __proto__, ale to poza tym. Chodzi raczej o to, że jeśli jakaś właściwość to undefined, prototyp obiektu jest sprawdzany pod kątem tej właściwości.

Jak powiedzieli ludzie w komentarzach, możliwe jest nadanie obiektowi tylko prototypu, który zapewnia opisane powyżej dziedziczenie poprzez przypisanie tego obiektu do właściwości funkcji prototype, a następnie użycie tej funkcji jako konstruktora.

Jednak właściwość prototype obiektu utworzonego przez wywołanie konstruktora nie jest object.hasOwnProperty('prototype'). Z drugiej strony, jeśli przypiszesz obiektowi właściwość prototype, to obiekt ten będzie object.hasOwnProperty('prototype'), ale wtedy object.prototype nie będzie miał nic wspólnego z łańcuchem prototypów - będzie to zwykła właściwość i będzie się nazywać prototype .

Aby to wykazać:

var foo = {}; 
foo.prototype = {bar: 'hello'}; 
console.log(foo.bar); // undefined 
console.log(foo.prototype); // Object {bar: "hello"} 
console.log(foo.hasOwnProperty('prototype')); // true 

var Foo = function() {}; 
Foo.prototype = {bar: 'hello'}; 
var f = new Foo; 
console.log(f.bar); // 'hello'; 
console.log(f.hasOwnProperty('bar')); // false 
console.log(f.prototype); // undefined 
console.log(f.hasOwnProperty('prototype')); // false