2013-05-30 13 views
8

Czytałem projekt gry z HTML5 i JavaScriptem i wprowadziłem mnie do obiektów. Po przeczytaniu książki i pracy nad projektami postanowiłem wykorzystać tę nowo odkrytą wiedzę i zintegrować obiekty w moich własnych projektach. Więc oto moje pytanie może, czy też powinno, czy obiekty nazywają swoje własne funkcje? Na przykład:Funkcja wywoływania obiektów JavaScript od siebie

var someObject = { 
    start: function() { 
     check(); 
    }, 
    check: function() { 
     console.log("Check!"); 
    } 
}; 

someObject.start(); 

książka nie przedstawiają przykład z zegarem, który to robi:

var timer = { 
    start: function() { 
     var self = this; 
     window.setInterval(function(){self.tick();}, 1000); 
    }, 
    tick: function() { 
     console.log('tick!'); 
    } 
}; 

W przykładzie z obiektu timera to sprawia, że ​​odniesienie do siebie, aby wywołać funkcję wewnętrzną, Czy oznacza to, że powinienem użyć self do wywoływania funkcji wewnętrznych, czy też jest to właściwy sposób na zrobienie tego z obiektami? Lub najlepsze praktyki? Z góry dziękuję.

var someObject = { 
    start: function() { 
     var self = this; 
     self.check(); 
    }, 
    check: function() { 
     console.log("Check!"); 
    } 
}; 

someObject.start(); 
+3

Powodem używają go w 'setTimeout' przykład, ponieważ jego wywołania zwrotnego jest wykonywany w zakresie globalnym, a więc wartości' this' w 'setTimeout' callback to 'window'. Aby zachować odniesienie do oryginalnego obiektu, musisz użyć tej metody (przechowywania go w 'self') lub jakiejś formy użycia' Function.bind() ' – Ian

Odpowiedz

5

Nazwy JavaScript to lexically scoped, więc za każdym razem, gdy w skrypcie napotkana jest nazwa (zmienna), środowisko wykonawcze JavaScript musi wyszukać zakresy, od których została zdefiniowana.

W punkcie definicji, ta funkcja:

start: function() { 
    check(); 
} 

nie ma dostępu do żadnego check funkcję w swojej zewnętrznej zakresie. Deklaracja self i powiązanie go z this jest techniką używaną do radzenia sobie z (nieco interesującym) intricacies of referring to the current object in JavaScript (ponieważ przykładowy kod używa window.setInterval).

Aby odwołać się do funkcji w bieżącym obiekcie, wystarczy użyć this.

var someObject = { 
    start: function() { 
     this.check(); 
    }, 
    check: function() { 
     console.log("Check!"); 
    } 
}; 
0

Oczywiście obiekt może i powinien wywoływać własne funkcje, jest to jedyny sposób emulacji OOP w javascript. Powiedziałbym, że praktyka, której używa książka, self = this jest szkodliwa, ponieważ this może być użyta sama, jednak w pierwszym przykładzie jest używana do zachowania wartości tej, która w innym wypadku byłaby sama w sobie funkcją, a nie klasa zewnętrzna

+0

" emulować "; po prostu powtarzaj sobie, że może klikaj pięty razem, kiedy to mówisz ... – dandavis

+0

Istnieje wiele powodów, dla których warto wykonać 'var self = this'; całkowicie niezwiązanym powodem jest zwiększenie wydajności kompresji skryptów. – voithos

+0

@voithos odczytać całą odpowiedź Powiedziałem tylko, że drugie użycie było złe – aaronman

1

Punkt zadeklarowania i zainicjowania zmiennej takiej jak "self" polega na tym, że wartość this jest ustalana od nowa po każdym wywołaniu funkcji. Jeśli masz funkcję zagnieżdżoną w innej funkcji i ta wewnętrzna funkcja potrzebuje dostępu do wartości this z zewnętrznego kontekstu, to this musi zostać zachowany w innej zmiennej "self" w twoim przypadku. (Nazwa tej zmiennej jest nieważna oczywiście).

W kodzie przykładowym:

var timer = { 
    start: function() { 
     var self = this; 
     window.setInterval(function(){self.tick();}, 1000); 
    }, 
    tick: function() { 
     console.log('tick!'); 
    } 
}; 

że czynność podjęta w celu setInterval() musi użyć wartości this z funkcji „start”. Kiedy wywoływana jest funkcja interwału czasowego, jednak this jest ustawione na coś innego (kontekst globalny lub null w trybie "ścisłym"). W ten sposób, zapisując wartość this w kontekście, w którym ta funkcja timera interwałowego jest tworzona, jej kod może użyć jej do uzyskania dostępu do obiektu timera.

W twoim drugim przykładzie deklarowanie i inicjowanie zmiennej "ja" niczego nie boli, ale jest niepotrzebne. Czasami jednak przydaje się tylko wyjaśnienie kodu, choć oczywiście bardziej wymowna nazwa niż "ja" byłaby dobrym pomysłem.

+0

To nie jest to, co robi się w drugim przykładzie, choć tak, – aaronman

+0

@aaronman tak, to prawda. – Pointy

1

Jest to kontekst funkcji javascript, za każdym razem, gdy tworzysz funkcję, tworzysz nowy kontekst (zakres).

W setInterval() funkcji tworzenia nowego zakresu, tak this odnoszą się już nie jako ten sam this powyżej:

var self = this; 
setInterval(function() { 
    self.tick(); 
}, 1000); 

Można również ręcznie powiązać właściwego kontekstu swojej funkcji z bind() (więc nie zrobić potrzebują self już):

setInterval(function() { 
    this.tick(); 
}.bind(this), 1000); 

Więcej informacji:

Powiązane problemy