2012-03-16 26 views
6

Po uruchomieniu następującego kodu otrzymuję informację, że rozmowa nie jest funkcją. Dlaczego?Nie jest funkcją?

function cat(name) { 
    talk = function() { 
     alert(" say meeow!") 
    } 
} 

cat("felix"); 
cat.talk() 
+0

Czy próbowałeś stworzyć klasę 'cat', czy zdefiniowałeś obiekt, który miał funkcję talk? –

Odpowiedz

9

Próbujesz utworzyć obiekt, dla którego funkcja jest konstruktorem, ale to, co faktycznie robi kod, to ustawienie zmiennej talk na funkcję. Chcesz:

function cat(name) { 
    this.talk = function() { 
     alert(" say meeow!") 
    } 
} 

var myCat = new cat("felix"); 
myCat.talk() 

edit:

Stosowna javascript tech talk: http://www.youtube.com/watch?v=ljNi8nS5TtQ

Opowiada o budowie obiektów o funkcjach na około 30 minut w kodzie he stanowisk jest.

function Circle(radius){ 
    this.radius = radius; 
    this.area = function(){ 
     return this.radius * this.radius * Math.PI; 
    }; 
} 
var instance = {}; 
Circle.call(instance, 5); 
instance.area(); // ==> 78.5398 
var instance2 = new Circle(5); 
instance2.area() // ==> 78.5398 
instance instanceof Circle // ==> false 
instance2 instanceof Circle // ==> true 

I odpowiedni cytat:

Nowe słowo kluczowe jest tylko skrótem, który mówi „zrobić nowy obiekt i wywołać konstruktora na nim ... nowy Hasło nie ma innego czyli”

Innymi słowy, on mówi, że kiedy używając słowa kluczowego new, definiujesz zmienną jako obiekt i wywołujesz funkcję w kontekście tego obiektu (this punktów do twojego obiektu).

Dodatkową rzeczą, którą robi słowo kluczowe new, jest ustawienie prototypu nowo utworzonego obiektu na prototyp konstruktora. Jeśli więc to zrobimy:

function Circle(radius){ 
    this.radius = radius; 
    this.area = function(){ 
     return this.radius * this.radius * Math.PI; 
    }; 
} 
var instance = {}; 
Circle.call(instance, 5); 
instance.__proto__ = Circle.prototype; // we set the prototype of the new object to that of the constructor 
instance.area(); // ==> 78.5398 
var instance2 = new Circle(5); 
instance2.area() // ==> 78.5398 
instance instanceof Circle // ==> true // this is now true 
instance2 instanceof Circle // ==> true 

instance instanceof Circle jest teraz prawdziwy.

+2

+1, bicie mnie do tego, chociaż prawdopodobnie powinieneś wyjaśnić, dlaczego to działa, a wersja OP nie. – RMorrisey

+0

+1 ode mnie, a przykładowy kod, który miałem zamiar opublikować, był identyczny :) (char dla char). – pete

+0

@RMorrisey, tak, to prawda. Szukałem tej technologicznej rozmowy, którą właśnie napisałem, aby zweryfikować wszystko, co zamierzam powiedzieć. Wciąż pewnie nie zrobię wiele sprawiedliwości, ale opublikuję to w sekundę. – mowwwalker

0

kot nie jest przedmiotem. Jest to funkcja i nie sądzę, że JavaScript obsługuje to.

+4

Cóż, funkcje są również obiektami, więc można faktycznie dodać właściwości do funkcji. – Guffa

+0

Wow, nie wiedziałem, że: D – PhpXp

2

Aby kontynuować pracę kodu dowolnie trzeba by napisać:

function Cat(name) { 
    this.talk = function() { 
     alert(" say meeow!") 
    } 
}; 

var c = new Cat("felix"); 
c.talk() 

Funkcja Cat jest wtedy konstruktor funkcja i zwrócony obiekt ma właściwość (talk), która to funkcja możesz zadzwonić.

Twój oryginalny kod faktycznie ogłosił globalny funkcję talk który nie był częścią funkcji cat w ogóle, ponieważ brakowało słowa kluczowego var.

1

Po prostu dlatego, że tak nie jest.

Utworzono funkcję i przypisano ją do zmiennej w funkcji cat, ale ta zmienna nie należy do funkcji. Ponieważ nie deklarujesz zmiennej w dowolnym miejscu, staje się ona niejawnie globalna, więc jest faktycznie dostępna poza funkcją, ale nie w sposób, w jaki próbujesz jej użyć.

Trzeba by dodać funkcję jako właściwość do obiektu cat funkcji, w celu, aby móc nazwać w ten sposób:

function cat(name) { 
    cat.talk = function() { 
    alert(" say meeow!") 
    } 
} 

cat("felix"); 
cat.talk() 

Jednakże, może być patrząc na obiekt, który ma metodę, a nie funkcję, która ma właściwość, która jest metodą:

function Cat(name) { 
    this.name = name; 
} 

Cat.prototype.talk = function() { 
    alert(this.name + " says meeow!"); 
} 

var felix = new Cat("Felix"); 
felix.talk(); 
+0

właściwie jego funkcja 'talk' jest globalna, nie lokalna – Alnitak

+0

@Guffa, sprawdź, czy wszystko jest w porządku z moją edycją. BTW, twoja próbka osiąga coś, czego większość ludzi nie oczekuje - właściwość add na danej funkcji, w przeciwieństwie do właściwości nowego obiektu stworzonego przez konstruktora "cat". –

+0

Tak, masz rację, jest to zmienna globalna. Sam wykonałem obszerną edycję, ale uwzględniłem twój punkt widzenia. – Guffa