2009-06-16 21 views
10

Pochodzę z tła Java, z modelem dziedziczenia opartym na klasach, próbując zrozumieć problem oparty na prototypowym modelu dziedziczenia JavaScript. Część tego, co mnie wyrzuca, wydaje mi się, że mam na myśli znaczenie słowa "to" napisane przez Javę - a "to" w JavaScript jest zupełnie inną bestią. Rozumiem, że "to" w JavaScript zawsze odnosi się do funkcji wywołującej, a nie do zakresu, w którym funkcja została zdefiniowana - mam na myśli, że czytałem i rozumiem powierzchownie, co to znaczy. Ale chciałbym mieć głębsze zrozumienie i myślę, że pomogłoby mi to mieć inną nazwę. Jak myślisz o JS "to"? Czy wymieniasz się mentalnie za każdym razem, gdy go przejedziesz? Jeśli tak, jakie słowo lub frazę używasz?Jaka byłaby lepsza nazwa dla "tego" Javascriptu?

+0

Na początku pytanie wydawało się głupie, ale po przeczytaniu jakiejś odpowiedzi, jest to całkiem interesujące ;-) +1 –

Odpowiedz

17

this może być racjonalnie zmieniona na context w JavaScript.

To naprawdę odnosząc się do kontekstu wykonania w bieżącym zakresie, a jednocześnie tym kontekście może być instancją klasy, to z pewnością nie musi być — może to być dowolny obiekt w ogóle, a może być modyfikowane w czasie wykonywania.

Dowód, że nie ma gwarancji, cokolwiek, że „metoda” w JavaScript działa na przykład w „klasy”, w którym jest zdefiniowana:

function Cat(){ 

    this.texture = 'fluffy'; 

    this.greet = function(){ 
     alert("Pet me, I'm " + this.texture); 
    } 
} 

var cat = new Cat(); 

// Default to using the cat instance as the this pointer 
cat.greet(); // Alerts "Pet me, I'm fluffy" 

// Manually set the value of the this pointer! 
cat.greet.call({texture: 'scaly'}); // Alerts "Pet me, I'm scaly" 

ważne jest, aby nie zauważyć, że wartość obiektu this jest całkowicie niezależny od miejsca zdefiniowania funkcji zawierającej.

+0

Czy to słuszne powiedzieć, że słowo kluczowe "this" pozwala na emulowanie dynamicznego zakresu w javascript ?. (Ogólnie rzecz biorąc, wszystkie funkcje mają zakres leksykalny/statyczny) – techzen

5

Myślę, że JavaScript this jest znacznie bliższy Java this niż myślisz. W kontekście OOP, this oznacza "to wystąpienie". Myślę, że to, co może być mylące w przypadku słowa kluczowego JavaScript this, to że może mieć inne znaczenie w zależności od kontekstu.

+0

"to" nie zawsze oznacza "tę instancję". Na przykład można ręcznie ustawić wartość "this" dla dowolnej funkcji za pomocą Function.call lub Function.apply. – Triptych

+0

Dobrze, więc "to" oznacza "tę instancję", dopóki jej nie zmienisz. To nie zmienia początkowego znaczenia "tego".Czy mogę bezpiecznie założyć, że zgadzasz się ze mną, że "to" jest wysoce kontekstualne? –

+1

Naprawdę musisz ufać, że "to" jest prawidłowo ustawione przez dzwoniącego. Podobnie jak w przypadku-c, ufam, że "ja" jest naprawdę obecną instancją. W Javie nie można zmienić "this", aby wskazywać na coś innego. – Kekoa

1

Co powiesz na "JavaScript to"? Dzięki niemu będziesz bezpośrednio związany z tym, co robisz, a także będziesz pamiętać, że pojęcie "tego", nad którym obecnie pracujesz, jest pojęciem JavaScript.

Ostatecznie, spodziewam się, że przestaniesz nazywać to "JavaScript to" i po prostu nazywaj to "tym", będąc w pełni świadomym, co to oznacza w kontekście, w którym pracujesz. Którego bym się spodziewał prawdopodobnie, gdzie chcesz się dostać.

+0

Tak. Z przepraszaniem Zen: zanim nauczyłeś się Javascript, góry są górami; wody to wody. Kiedy nauczyłem się Javascript, góry nie były już górami i wodami, nie były już wodami. Kiedy już opanowałem Javascript, góry znów były górami i wodami ponownie. –

3

this nie wywołujący funkcję jest (chociaż może być) lub zakres, w których funkcja została określona (chociaż może być) - to Function kontekst.

Przesunięcie, o którym mówi @Andrew Hare, prawdopodobnie jest bliższe źródłu twojego zamieszania; Ze względu na prototypowy mechanizm dziedziczenia JS, słowo kluczowe function może oznaczać, w zależności od sposobu jego użycia, coś bliższego Java class niż definicja metody Java.

Zakładając wykonanie w przeglądarce:

var q = this.document; //this is window 

var o = new (function pseudoconstructor(){ 
    this.property = "something else" //the new keyword changed 'this' to mean 'the object I'm about to return' 
})(); 
9

Jedną z możliwych alternatywnych nazw będzie owner. To poprowadzi twój umysł w kierunku, w którym właściciel może się zmienić w zależności od tego, jaki kod wykonujesz.

Ten przykład jest z quirksmode:

W JavaScript this zawsze odnosi się do „właściciela” funkcji mamy do wykonywania, a raczej do obiektu, że funkcja jest metoda. Kiedy definiujemy naszą wierną funkcję doSomething() na stronie, jej właścicielem jest strona, a raczej obiekt okna (lub obiekt globalny) JavaScript. Właściwość onclick jest jednak własnością elementu HTML, do którego należy.

W poniższym kodzie

function doSomething() { 
    this.style.color = '#cc0000'; 
} 

i

element.onclick = doSomething; 

, owner wskazuje na obiekt, który zawiera metodę, gdy jest on wykonywany.

------------ window -------------------------------------- 
|          /\   | 
|           |   | 
|           this   | 
| ----------------      |   | 
| | HTML element | <-- this   ----------------- | 
| ----------------  |   | doSomething() | | 
|    |   |   ----------------- | 
|   --------------------       | 
|   | onclick property |       | 
|   --------------------       | 
|              | 
---------------------------------------------------------- 
+1

Nie spadłem (jeszcze), ale nie podoba mi się ta odpowiedź, ponieważ pozwala wierzyć, że wartość tego wskaźnika jest "zawsze" określane przez to, gdzie zdefiniowana jest funkcja, co jest całkowicie nieprawdziwe. – Triptych

0

I wchłonąć nową składnię z małymi łatwych typu modeli umysłowych, takich jak:

$(document).ready(function() { 

    function baffle() { 
    alert(this.b); 
    } 

    function what() { 
    this.b = "Hello"; 
    baffle(); 
    } 

    function huh() { 
    this.b = "World"; 
    baffle(); 
    } 

    what(); 
    huh(); 

    } 
); 

To źle przekłada się rozlazły, wyobrażonej C++ jak:

template <class This> 
function baffle() { 
    alert(This.b); 
} 

function what() { 
    b = "Hello"; 
    baffle<what>(); 
} 

function huh() { 
    b = "World"; 
    baffle<huh>(); 
} 

what(); 
huh(); 
0

myślę this jest najbardziej odpowiedni ze względów historycznych. W JavaScript nie ma tak naprawdę frazy "uniwersalny", ponieważ nie tylko można ją automatycznie przypisać do bardzo różnych odniesień, np. this w kontekście funkcji proceduralnej lub this w kontekście obiektu. , ale this może być również przypisany przez skrypter przy użyciu Function.apply i Function.call.

Jednak znaczenie this jest tylko regulowane, ponieważ JavaScript i DOM działają w bardzo dziwny sposób. Na przykład głównym zastosowaniem Function.apply jest zachowanie kontekstu odwołania do elementu w wywołaniach zdarzeń. Zobaczysz to w metodzie Prototye'a: Function.bind().

jest symbolem zastępczym kontekstu, w którym funkcja jest wykonywana, i trudno jest uzyskać bardziej szczegółowe informacje. Jednak większość zastosowań this sprawia, że ​​jest to semantycznie odpowiednie słowo kluczowe. W przypadku bind(), mimo że używamy metod, aby arbitralnie zmienić znaczenie this w funkcji, należy go użyć, aby uczynić bardziej odpowiednim, niż byłby bez. Wielu amatorskich programistów JavaScriptu jest odrzucanych przez dziwne zachowanie this w programach obsługi zdarzeń, a Function.apply służy do naprawienia tego "źle".

-1

Logika selfreferential (sama lub ta) pozwala uniknąć paradoksów pracując na innych niż ja (this). Czy self (this) zachować wszystko i wszystko w jednym, może również pozostać statyczne bez instancji i zamiast metody klasy (statyczne). Aby uniknąć paradoksów, unikaj autoreferencji i logiki, aby wszystkie dowody prawdy były udowodnione i viceversa, wszystkie dowody prawdziwe.

Powiązane problemy