2013-10-23 16 views
5

W poniższym kodzie, gdy somethingUseful.thisUsefulThing jest wywoływana z , czy może on odwoływać się do somethingUseful.thatUsefulThing?JavaScript: Słownik funkcji: Czy funkcja odwołuje się do funkcji ze swojego słownika?

var somethingUseful = { 
    thisUsefulThing: function() { 
    this.thatUsefulThing(); 
    }, 

    thatUsefulThing: function() { 
    console.log("I am useful!"); 
    } 
} 

setTimeout(somethingUseful.thisUsefulThing, 1000); 

Teraz ja dostaję ten błąd:

Uncaught TypeError: Object [object global] has no method 'thatUsefulThing' 
+6

Co to znaczy "zakres globalny" a "zakres przedmiotu"? Twój kod, jak napisano, działa. – user2736012

+1

Należy pamiętać, że po wywołaniu 'object.method()', wartość 'this' w' method' staje się odniesieniem do 'object'. Nie ma znaczenia, gdzie i kiedy obiekt i metoda zostały stworzone. Liczy się tylko to, jak * nazywasz metodę. Umieść tę samą metodę na innym obiekcie, wywołaj ją z tego obiektu, a wartość "this" odniesie się do nowego obiektu. 'var o = {thatUsefulThing: function() {console.log (" Ja też jestem użyteczny! ");}}; o.foo = somethingUseful.thisUsefulThing; o.foo(); // Ja też jestem przydatna " – user2736012

+0

Tam edytowałem go tak, aby bezpośrednio odzwierciedlał błąd, który napotykam w pigułce. – Synthead

Odpowiedz

3

po prostu odpowiedzieć na pytanie, YES, thisUsefulThing mogą uzyskać dostęp thatUsefulThing

Ale jak Twój kod aktualnie pracuje 'to' jest nie w rzeczywistości globalny, jest odniesieniem do czegoś Użyteczne dla wszystkich bezpośrednich potomków.

Kiedy pracuję z dosłownych obiektów, zwykle odwoływać się do nich po imieniu, a nie z „tego”, tak w przypadku chciałbym zastąpić 'this.thatUsefulThing()() z somethingUseful.thatUsefulThing

Dlaczego ? Ponieważ i tak działa na całym świecie!

EDIT:

Jak plalx podkreślił w swoim komentarzu do mojej odpowiedzi, najlepsze praktyki w zakresie realizacji tej klasy (z członem klasy przykład) użyłby funkcjonalnych klas/prototypy i wyglądać tak:

function SomethingUseful() { 
    this.member = 'I am a member'; 
} 
SomethingUseful.prototype.thisUsefulThing = function() { 
    this.thatUsefulThing(); 
} 
SomethingUseful.prototype.thatUsefulThing = function() { 
    console.log('I am useful, and ' + this.member); 
} 
usefulObject = new SomethingUseful(); 

usefulObject.thisUsefulThing(); // logs fine with access to this.member 
setInterval(usefulObject.thisUsefulThing.bind(usefulObject), 1000); // has access to this.member through bind() 
+1

Tak, to też myślałem ... zwłaszcza, gdy napisany przeze mnie kod zadziałał, hahaha. Poświęć chwilę, aby przejrzeć moje zredagowane pytanie, jeśli chcesz. I tak, JavaScript jest (znacznie spóźniony) nowym moim liście. – Synthead

+1

Aby rozwiązać twoje pytanie, nadal zmienię "this.thatUsefulThing()" na "somethingUseful.thatUsefulThing() ' – Miles

1

Po prostu połącz wartość this z somethingUseful.

setTimeout(somethingUseful.thisUsefulThing.bind(somethingUseful), 1000); 
+0

Prawdopodobnie lepiej po prostu naprawić złe odniesienie do" tego "niż wiązania. – Miles

+0

@ I-live-in-a-storm-drain Właściwie to jest całkiem odwrotnie. Opieranie się na nazwie zmiennej jest dość nieelastyczne, podatne na błędy i daleka od suszy. – plalx

+0

Pomyśl o tym w następujący sposób: Jeśli jesteś wiążący, już wpisujesz nazwę zmiennej jeszcze raz, a także metody i nawiasy. Brzmi bardzo DOBRZE dla mnie. – Miles