2009-09-03 14 views
12

Właśnie zacząłem czytać o Douglasie Crockford's "Javascript The Good parts" gdzie wyjaśnia o rozszerzeniu podstawowych typów.JavaScript Rozszerzanie podstawowych typów (dziedziczenie prototypów) wątpliwości

Function.prototype.addMethod=function(name,func) { 
    this.prototype[name]=func; 
    return this; 
}; 

Moment po zrobieniu tego, addMethod staje się dostępny dla wszystkich podstawowych przedmiotów, takich jak String, Ilość itd. To pozostawia mnie zastanawiało

[1] Dlaczego tak się dzieje kiedy nie dodałem go do Object.prototype?

[2] Dlaczego dodanie metody Function.prototype zostanie odzwierciedlone we wszystkich podstawowych przedmiotów?

Jestem całkiem nową dziedziną javascript i prototypowego dziedziczenia. Tak naprawdę nie wiem, czy moje pytania są głupie?

+0

Nie, to implementacja dziedziczenia prototypów w języku JavaScript jest niemądra. Jego dziwny styl "funkcja-jak-konstruktor" nie daje żadnej z potencjalnych zalet prototypów, a jednocześnie jest darmowy od klasowego dziedziczenia, które większość programistów rozumie. Miło jest dokładnie zrozumieć, co robią prototypy JavaScript, ale nie oczekuj epifanii, która wyjaśnia, dlaczego ten model ma sens. Ponieważ tak nie jest. – bobince

Odpowiedz

16

Prawdopodobnie oznaczało chwilę po zrobieniu tego, addMethod staje się dostępny dla wszystkich podstawowych obiektów typy obiektów jak String, liczba itp To dlatego, że obiekt String jest funkcją (ale obiekty utworzone przez ciąg nie są).

Np podane

var s = ''; 

Można zrobić

String.addMethod(...); 

ale nie

s.addMethod(...); 

Krótkie wyjaśnienie systemu typu JavaScript przychodzi tutaj:

JavaScript robi nie mieć normalną koncepcję zajęć. Zamiast tego możesz osiągnąć nieco to samo, zamieniając dowolną funkcję w konstruktor, umieszczając przed wywołaniem nowe słowo kluczowe przed nim.

Np: podany

function MyFunction(x) { this.myX = x; } 

jeśli odwołać się go jak

var myObj = new MyFunction(10); 

będzie utworzyć obiekt o nazwie myObj. Ten obiekt będzie miał pojedynczą zmienną składową o nazwie myX. Funkcja MyFunction jest uznawana za konstruktora obiektu (i jest przechowywana we właściwości "constructor").

(Pytanie dodatkowe: co się stanie, jeśli wywołasz powyższą funkcję bez nowego słowa kluczowego, np. var x = MyFunction(10). Odpowiedź prawdopodobnie zaskoczyć każdą rozsądną osobę.)

Widzieliście już, jak dowolna funkcja może zostać przekształcona w konstruktor, wbudowane obiekty są dokładnie takie same, obiekty łańcuchowe są tworzone przez funkcję String, liczby są tworzone przez funkcję Numer itp.

Tak jak te wbudowane obiekty są tworzone przez funkcje, każda z tych funkcji jest również tworzona przez funkcję "Funkcja" (yikes!).

Teraz do prototypów.

w powyższym przykładzie, jeśli gdzieś napisać

MyFunction.prototype.someNewMethod = function() {} 

wszystkie obiekty stworzone przez konstruktora MyFunction/funkcja pojawi się mieć dodatkową funkcję składową o nazwie someNewMethod. Możesz robić wiele innych funky z prototypami, np. Zastępując prototyp lub zastępując prototypowy prototyp, ale nie jestem w tym ekspertem.

+0

Sądząc po "this.prototype [name]", myślę, że masz całkowitą rację. –

+1

Czy możesz wyjaśnić to nieco więcej? Trudno znaleźć pojęcie. –

+0

@erikkallen Jak jest typ obiektu String (lub jakikolwiek inny podstawowy typ obiektu)? Czy jest tak, że obiekt String ma konstruktor będący obiektem Function? Proszę wyjaśnić to nieco więcej! – sriramptr

1

W javascript zorientowanym obiektowo funkcja może służyć jako konstruktor klasy &. Więc jeśli klasa została nazwana MyObject, można wykonać następujące czynności:

// create a class/constructor 
function MyObject() { 
    // ... 
} 

// add a static method to the MyObject class 
MyObject.someFunction = function() { 
    // ... 
} 

// add an instance method to the MyObject Class 
MyObject.prototype.someFunction = function() { 
    // ... 
} 

W swoim przykładzie addMethod został dodany jako metody instancji do klasy funkcji, co oznacza, że ​​jest ona dostępna dla wszystkich wystąpień funkcję. Funkcja/klasa/konstruktor MyObject jest instancją funkcji, dzięki czemu można wywołać na niej metodę addMethod. Działa to z większością typów obiektów, ale nie z HTMLElements w IE i niektórych innych przeglądarkach.

1
  1. Funkcje JavaScript to obiekty. Wszystkie obiekty mają ukryty link do Object.prototype. Tak więc w przypadku pierwszej deklaracji:

    > `Function.prototype.addMethod=function(name,func) {} 
    

    Użytkownik zadeklarował funkcję powiązaną z Function.prototype, która sama jest połączona z Object.prototype.

  2. Dla drugiej części jest to po prostu przypisanie, w którym ustawiasz parę wartości nazwy na Object.prototype i zwróci metodę dodawania do wszystkich obiektów String, Number, ponieważ wszystkie one są zadeklarowane w prototypie.
Powiązane problemy