2015-11-23 32 views
6

Według this funkcje dziedziczą Function i Function z Function.prototype kolejno:Różnica między funkcją i Function.prototype

Światowy Function obiekt nie ma metody lub właściwości własnych, jednak, ponieważ jest to sama funkcja dziedziczy niektóre metody i właściwości za pośrednictwem łańcucha prototypów z Function.prototype.

Jaki jest sens Function.prototype? Dlaczego nie przenieść jego właściwości do Function i pozwolić Function.prototype być undefined? Zamiast tego funkcje będą pochodzić z Function.

samo dotyczy Object itp

+3

Wyobrażam sobie, że tak jest, ponieważ właściwości prototypu są współużytkowane przez wszystkie instancje, w przeciwieństwie do właściwości instancji, które są lokalne dla każdej instancji. –

+0

> "Funkcje wywodzą się z funkcji". Wierz, że to jest twoje źródło nieporozumień. Nie wiesz, gdzie dokładnie to przeczytałeś, ale Funkcje nie mogą być wyprowadzone z Funkcji w sensie prototypowym. –

+0

@ nikc.org W porządku, ale dlaczego z 'Function.prototype'? Czy nie są to właściwości naprawdę odziedziczone, jeśli wykonamy 'f.prototype = Function', gdzie' f' jest funkcją? Chodzi mi o to, że jeśli chcesz dziedziczyć z funkcji, wykonaj 'f.prototype = super_f', a nie' f.prototype = super_f.prototype', prawda? – Downvoter

Odpowiedz

6

funkcje dziedziczą Function

Jesteś cytując MDN luźno. Co to właściwie mówi się: obiekty

funkcyjne dziedziczą Function.prototype

Należy zauważyć, że na stronie MDN, początkowe słowo „funkcja” w zdaniu są kapitalizowane, ale tylko dlatego, że jest u początek zdania, nie dlatego, że odnosi się do obiektu JS Function. Odnosi się to do zwykłych starych funkcji zadeklarowanych jako function() { }.

Pamiętaj, że MDN jest napisany przez zwykłych śmiertelników. Wolałbym, żeby nie używali słów "dziedziczenie" i "dziedziczenie", nie wspominając już o "pochodnych". JS nie ma koncepcji dziedziczenia w ścisłym znaczeniu tego słowa. Jeśli użyjesz tej terminologii, w końcu się pomylisz. To, co ma JS, to prototypy związane z obiektami. Podczas uzyskiwania dostępu do właściwości obiektu, jeśli nie zostanie znaleziony, konsultowany jest prototyp. Jeśli go tam nie odnajdziemy, ponieważ prototyp jest również obiektem z prototypem, konsultowany jest prototyp prototypu i tak dalej w łańcuchu.

Dlatego powyższe zdanie powinno być lepiej napisane jako "obiekty funkcji mają jako swój prototypFunction.prototype".

Przedmiotem JS Function nie jest bezpośrednio związany z Function.prototype, poza faktem, że Function.prototype jest własnością Function, a ponieważ obiekt Function jest sama funkcja, sama ma Function.prototype jak jego pierwowzór. Jakiekolwiek właściwości mogą, ale nie muszą być obecne na Twoim komputerze, nie mają nic wspólnego z łańcuchem prototypów i nie są przez nikogo dziedziczone.

Po wykonaniu (function() { }).call(), właściwość/metoda call jest najpierw sprawdzana na obiekcie funkcji; jeśli tam nie istnieje, tak jak normalnie by nie było, to jest podnoszone na prototypie przypisanym wewnętrznie, gdy funkcja została zadeklarowana, czyli Function.prototype. Gdzie jeszcze można umieścić metody takie jak call lub apply, jeśli nie na Function.prototype? Co jeszcze nazwałbyś prototypem automatycznie przypisanym do funkcji innych niż Function.prototype?

Na marginesie zwróć uwagę, że Function.call rozwiąże poprawnie wewnętrzną funkcję call. Czemu? Nie dlatego, że tam jest miejsce zamieszkania call lub ponieważ pochodzi to z funkcji, w których "dziedziczą" zwykłe funkcje "call", ale ponieważ, jak wspomniałem wcześniej, Function sam jest funkcją, a zatem ma prototyp na jej prototypie: call prototypowy łańcuch.

Jaki jest sens Function.prototype? Dlaczego nie przenieść jego właściwości do Function i pozostawić niezdefiniowaną Function.prototype? Zamiast tego funkcje będą pochodzić z Function.

to właściwość na X stosowana jako prototyp dla obiektów utworzonych za pomocą X jako konstruktora. Dlatego, aby przypisać poprawny prototyp do obiektów utworzonych przy użyciu Function jako konstruktora (który obejmuje funkcje zadeklarowane jako function x() { }), prototyp musi być obecny jako właściwość prototype na Function.

+0

Crap, całkowicie zapomniałem 'Function.prototype' jest po prostu właściwością, a nie oddzielnym obiektem. W każdym razie, dlaczego nie przenieść własności obiektu przywoływanego przez 'Function.prototype' do' Function'? Jeśli masz dwie funkcje, 'f' i' g', to powiesz 'f.prototype = g', a nie' f.prototype = g.prototype', prawda? A jeśli chodzi o "on sam ma Function.prototype jako swój prototyp" - czyżby to nie zakończyło się nieskończoną pętlą rekurencyjną? I opierając się na tym, kiedy kompilator przestaje wspinać się na prototypowy łańcuch? – Downvoter

+0

Nie, ponieważ prototypem 'Function.prototype' jest' Object.prototype'. Silnik zatrzymuje się na prototypowym łańcuchu, gdy napotka obiekt bez prototypu. 'Object.getPrototypeOf (Object.prototype) == null'. –

+0

A więc "Function.prototype.prototype === Object.prototype"? I nie "sam w sobie ma Function.prototype jako swój prototyp". oznacza, że ​​'Function.prototype === Function.prototype'? Tak, to oczywiście prawda, ale i tak tego nie rozumiem. :( – Downvoter

2

funkcji na prototypie są tworzone tylko raz i dzielonych między każdej instancji. Funkcje utworzone w konstruktorze są tworzone jako nowe obiekty dla każdego nowego obiektu utworzonego za pomocą konstruktora.

Zasadniczo funkcje powinny znajdować się na prototypie, ponieważ zazwyczaj nie będą modyfikowane dla różnych obiektów tego samego typu, a to ma niewielką pamięć/wydajność. Inne właściwości, takie jak obiekty i tablice, powinny być zdefiniowane w konstruktorze, chyba że chcesz utworzyć wspólną, statyczną właściwość, w takim przypadku powinieneś użyć prototypu.

jej łatwiej zobaczyć wyróżnienia z normalnych obiektów lub tablic zamiast funkcji

function Foo(){ 
    this.bar = []; 
} 
var fooObj1 = new Foo(); 
var fooObj2 = new Foo(); 

fooObj1.bar.push("x"); 
alert(fooObj2.bar) //[] 
as opposed to: 

function Foo(){ 
} 

Foo.prototype.bar = [] 
var fooObj1 = new Foo(); 
var fooObj2 = new Foo(); 

fooObj1.bar.push("x"); 
alert(fooObj2.bar) //["x"] 
+1

To wszystko prawda, ale nie tak naprawdę, o czym mówił OP, który jest strukturą dziedziczenia dla samych funkcji. –

0

Trzeba Function.prototype bo jeśli chcesz rozszerzyć funkcje, rozważ to:

Function.prototype.moo = 5; 
function x() { }; 
console.log(x.moo); // 5 

wszystkie funkcje, które sprawiają, teraz ma właściwość moo, kontra:

Function.quack = 6; 
function b() {}; 
console.log(b.quack); // undefined 

To nie jest prawdziwe, jeśli wystarczy uderzyć w obiekt na Function. Każda funkcja NIE dziedziczy właściwości przypisanych do Function, dlatego potrzebna jest Function.prototype.

+0

"Nie jest to prawdą, jeśli po prostu uderzysz właściwość w" Funkcję "- dlaczego nie? Mam zamiar wznowić czytanie mojej schludnej książki teraz, może moje pytanie jest po prostu oparte na mojej "niewiedzy". – Downvoter