2016-01-23 12 views
5

W node.js, wewnątrz zwrotnego przekazanego setTimeout(), this wydaje się być związany z timeoutObject zwróconej sama setTimeout() (zarówno w trybie ścisłe i, nie strict mode):Wiązanie `this` w setTimeout() zwrotnego w node.js

var timeoutObject = setTimeout(function() { 
    console.log(this === timeoutObject); // true 
}, 0); 

var timeoutObject = setTimeout(function() { 
    'use strict'; 
    console.log(this === timeoutObject); // true 
}, 0); 

to nie jest sprawa w przeglądarce, gdzie this jest związany (jak bym się spodziewał) do obiektu globalnego window (lub jest undefined, w trybie ścisłym).

Dokumentacja nie mówi nic o tym niestandardowym zachowaniu.

Dlaczego tak jest?

+0

Co jest nie tak z tym? – Bergi

+2

Zwróciłem uwagę na to, co moim zdaniem jest złe. Spodziewam się, że "to" będzie związane z obiektem globalnym, tak jak w każdym innym wywołaniu zwrotnym. Wszystkie przeglądarki wiążą 'this' z obiektem globalnym, natomiast Node.js nie. – kYuZz

+2

Hm, węzeł nie jest przeglądarką i nie musi powtarzać błędów, które zostały [skodyfikowane za pomocą HTML5] (http://www.w3.org/TR/html5/webappapis.html#dom-windowtimers-settimeout). Korzystanie z obiektu globalnego jest w nim w zasadzie pogardzane, więc po co wywoływać wywołanie zwrotne?Odpowiedni timer (który nie jest liczbą, ale ma własne metody) ma dużo więcej sensu. – Bergi

Odpowiedz

1

Oto jedna dyskusja this` binding incorrect for `setTimeouf(..)` and `setInterval(..). Co wyjaśnia pytanie, była nawet próba naprawienia tego, co nie zostało zaakceptowane.

Oto kilka pomysłów, jak poniżej

setTimeout wiąże obiekt Timer do „tego” obiektu w zwrotnego. Przede wszystkim, w większości przypadków, środowisko wykonanie w węźle jest „moduł”, więc kiedy

var k=2; 
exports.k=3; 
console.log(k);//2 
console.log(this.k);//3 

Jest to różnica pomiędzy przeglądarką a węzłem. Nawiązanie do obiektu "okno" w przeglądarce jest łatwe, ponieważ jest to obiekt globalny. Ale w węźle setTimeout/setInterval nie ma możliwości uzyskania obiektu "export" ani środowiska wykonawczego modułu.


Niezależnie od tego, istnieją zalety obecnego sposobu Set *() działa (chociaż, przyznane jest nieudokumentowane, ale jest on używany w środowisku naturalnym). Na przykład:

setInterval(function() { 
    if (/* <condition> */) 
    this.unref(); 
    // do more stuff 
}, /* <n> */); 
+0

Dyskusja w numerze wyjaśnia pytanie, była nawet [próba naprawienia tego] (https://github.com/nodejs/node-v0.x-archive/pull/7955), która nie została zaakceptowana. –

1

Nodejs nie jest przeglądarką. "Standardy", o których mówisz, dotyczą przeglądarek. Przeczytaj dokumenty:

https://html.spec.whatwg.org/multipage/webappapis.html#dom-windowtimers-settimeout

Aby realizować te funkcje 2 czasowe „to” powinno być zbindowanych do obiektu window (niedostępne w Nodejs) lub obiektu pracownika (niedostępne w nodejs).

Nodejs ma swój własny obiekt globalny, który może być dobrym celem w tym przypadku, ale myślę, że lepiej jest powiązać go z tą funkcją, a nie z jakimś globalnym obiektem. Wygląda na to, że tak samo myślą o deweloperach z Nodejs.

Nie jest to sprzeczne z "standardami", ponieważ normy nie mają nic wspólnego z takim środowiskiem, w którym nie ma okien, nawigacji, obiektów lokalizacji.