w JavaScript Są faktycznie dwa różnego rodzaju „prototyp”:
- Jednym z nich jest „ukryty” link każdy obiekt ma (użyjmy
[[Prototype]]
reprezentować ten ukryty odnośnik). literały obiektowe domyślnie mają swoje ukryte odnośniki wskazujące na Object.prototype
, obiekty funkcji mają ukryty odnośnik wskazujący na Function.prototype
, a tablice wskazują na Array.prototype
. Te ukryte prototypowe łącza nie są powiązane z właściwościami o nazwie "prototyp". Nie możesz zmienić tych ukrytych linków, dodając lub modyfikując o.prototype
.
- Po drugie, wszystkie obiekty funkcji mają automatycznie specjalną właściwość o nazwie "
prototype
". Dotyczy to głównie użycia wzorca wywołania konstruktora.
[[Prototype]]
jest używany do poszukiwania właściwości (np rodzica w klasycznych hierarchii), gdy własność nie można znaleźć w obiekcie, jego [[Prototype]]
jest przeszukiwana w zamian.Jeden scenariusz użycia: powiedzmy, że chcesz dodać właściwość do wszystkich obiektów, możesz po prostu dodać ją do Object.prototype
, która automatycznie zastosuje się do wszystkich obiektów, ponieważ wszystkie obiekty mają w jakiś sposób Object.prototype
swój rdzeń łańcucha [[Prototype]]
.
Powróćmy do właściwości funkcji obiektu "" prototype
". Jest to użyteczne tylko w połączeniu z operatorem new
. Weźmy następujący fragment kodu jako przykład:
function F() {} // function declaration
// F now has a property named "prototype"
var f = new F(); // use "new" operator to create a new function object based on F
Co new F()
robi powyżej jest najpierw utworzyć nowy obiekt funkcji, ustaw [[Prototype]]
(ukryty link) tego nowo utworzonego obiektu funkcyjnego być F.prototype
, a następnie zawróci nowy obiekt funkcji. Prawdopodobnie to już wiesz, że działa dla obiektów funkcji.
Pamiętaj, że powiedziałem, że nie możemy zmienić obiektu [[Prototype]]
? Cóż, przynajmniej nie bezpośrednio. Funkcja Crockforda Object.create
właśnie to robi, wykorzystując fakt, że operator new
może pomóc nam ustawić [[Prototype]]
dla nas. Tak więc, używając Object.create
, celowo wskazujesz, gdzie powinien wskazywać ukryty link twojego nowego obiektu. (nieco ochotę wskazać, kto jest twoją rodzicielską klasą)
W twoim przykładzie, conf
jest literałem obiektu, a conf.prototype
nie jest zbyt użyteczny. Oto kolejna wersja wykorzystując klasyczny styl:
function ConfBase() {}
ConfBase.prototype.d = 16;
var conf = new ConfBase();
conf.a = 2;
conf.b = 4;
document.writeln(conf.a);
document.writeln(conf.b);
document.writeln(conf.d);
porównaniu odpowiedzią @CMS, ja wolę korzystania Object.create
. Ale zasadniczo 2 style używają tego samego podstawowego mechanizmu, tylko że Object.create
pomaga uporządkować to.
Czy osoba dokonująca wstrząsu może dodać komentarz? Zawsze staram się poprawić moje odpowiedzi :) – CMS