2015-09-03 21 views
6

Pierwsze pytanie, które zostało zadane w wywiadzie, i szczerze mówiąc widziałem ja naprawdę mylić i pokazano drzwiinstancją w przypadku funkcji w JavaScript

Rozważmy fragmenty:

Przypadek A :

var sayHello = new Function("alert('Hello there');"); 
    alert(sayHello instanceof Function);   // true 
    alert(sayHello instanceof Object);    // true, since every 
                // object inherits from Object 

Przypadek b:

var myFunction = function(){ 

    } 

    var ins = new myFunction();    
    alert(ins instanceof myFunction);  // ofcourse, true 
    alert(myFunction instanceof Function); // true 

    alert(ins instanceof Function);   // false, Why is this not true? 

Według mojego rozeznania, Funkcja musi być w prototypowego łańcucha z ins?

ins <-- myFunction <-- Function <-- Object 
+0

Cóż, 'ins' nie jest nawet funkcją – zerkms

+1

' ins' jest obiektem, a nie funkcją, nie możesz wywołać 'ins()' tutaj :) –

+0

@Wouter: Ale w tym celu każda funkcja musi dziedzicz z Object. –

Odpowiedz

10

Wydaje się, że błędnie interpretujesz new tutaj w JavaScript.

The

new myFunction() 

nie tworzy nową instancję funkcji. Raczej tworzy nowy obiekt, który dziedziczy po myFunction.prototype i wywołuje myFunction, przekazując obiekt do tej funkcji jako this.

Tak więc, tak naprawdę nie utworzyłeś nowej instancji funkcji, Twoja ins nie jest funkcją.Można go łatwo sprawdzić, próbując udawać, że jest:

var myFunction = function(){ 

} 

var ins = new myFunction(); 

ins(); <-- error, ins is not a function 

Ponieważ nie jest to funkcja, dlaczego mielibyśmy oczekiwać Function być w łańcuchu prototypów?

+0

To zapewniło mi poczucie ulgi. –

1

ins nie jest instanceof Function bo zadeklarować je jak instancji (new myFunction). Tak więc jest to instance funkcji myFunction.

Wystarczy odwołać myFunction:

var myFunction = function(){}; 
 
var res = document.querySelector('#result'); 
 
var ins = myFunction;    
 
res.textContent = ['ins instanceof myFunction: ',ins instanceof myFunction, 
 
        '\nmyFunction instanceof Function: ', myFunction instanceof Function, 
 
        '\nins instanceof Function: ', ins instanceof Function].join('');
<pre id="result"></pre>

3

Tak, masz to blisko, ale nie całkiem. Prototypal łańcuch jest faktycznie następująco:

ins <-- myFunction.prototype <-- Object 

Jak widać, INS obiekt dziedziczy z danego prototypu funkcji, a nie z funkcji bezpośrednio.

Tak więc, w istocie ins nie jest instancją funkcji myFunction, a nawet instancją myFunction.prototype.

Można to wyraźnie pokazać, ponieważ po dodaniu funkcji do myFunction.prototype są one dołączane do wystąpienia obiektu po jego utworzeniu.

Aby uzyskać doskonałe źródło informacji o tym, co dokładnie się dzieje, należy zapoznać się z https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new. Objaśnia to zachowanie w pełni.

+0

@ major-major: Nie zgadzam się z linią, że "Tak, ins nie jest instancją funkcji myFunction". To oczywiste. –

+0

@ShirgillAnsari Po prostu próbuję wskazać, że 'myFunction.prototype' jest tym, co kończy się łańcuchem prototypów, a nie' myFunction' bezpośrednio –

+0

: mann: w porządku. –

0

Pułapka, na którą tu wpadłeś, polega na tym, że zakładasz, że operator instanceof jest przechodni. Piszesz

ins <-- myFunction <-- Function <-- Object 

i stwierdzić, że również utrzymuje, że

ins <-- Function 

Zdarza się prawdą, że

myFunction <-- Object 

ale nie jest to spowodowane przechodnich instanceof.

W rzeczywistości zasada instanceof jest, że jeśli a instanceof b i b.prototype instanceof c wynika, że ​​a instanceof c ale nie jest to konieczne, że b instanceof c. Spójrz na ten przykład:

function func() {} 
function superFunc() {} 
func.prototype = new superFunc(); 

var x = new func(); 

Teraz x jest instancją func i superFunc, ale func nie jest instancją superFunc. W innych językach wolałbyś powiedzieć, że func jest podklasą z z superFunc.

Powiązane problemy