2016-01-23 14 views
5

In Node.js, all'interno di un callback passato a setTimeout(), this sembra essere legato alla timeoutObject restituito da setTimeout() sé (sia in modalità rigorosa e non modalità rigorosa):!Il legame di `this` in un callback setTimeout() in Node.js

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

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

Questo non è il caso nel browser, dove this è legato (come mi sarei aspettato) all'oggetto globale window (o è undefined, in modalità rigorosa).

La documentazione non dice nulla su questo comportamento non standard.

Perché è questo?

+0

Cosa c'è di sbagliato in questo? – Bergi

+2

Ho fatto notare quello che penso sia sbagliato in questo. Mi aspetterei che questo sia legato all'oggetto globale, come in ogni altro callback. Tutti i browser associano 'this' all'oggetto globale, mentre Node.js no. – kYuZz

+2

Hm, il nodo non è un browser e non ha bisogno di ripetere gli errori di vecchi che erano [codificati con HTML5] (http://www.w3.org/TR/html5/webappapis.html#dom-windowtimers-settimeout). L'utilizzo dell'oggetto globale è piuttosto disprezzato nel nodo, quindi perché chiamare la richiamata su di esso?Il rispettivo timer (che non è un numero, ma ha i suoi metodi) ha molto più senso. – Bergi

risposta

1

Ecco una discussione this` binding incorrect for `setTimeouf(..)` and `setInterval(..). Il che spiega la domanda, c'è stato addirittura un tentativo di risolverlo che non è stato accettato.

Ecco alcune idee come sotto

setTimeout lega l'oggetto timer per "questo" oggetto nel callback. Prima di tutto, nella maggioranza dei casi, l'ambiente di esecuzione in nodo è un "modulo", così quando

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

Questa è la differenza tra il browser e il nodo. Fare riferimento a "finestra" oggetto nel browser è facile perché si tratta di un oggetto globale. Ma in Nodo, setTimeout/setInterval non consente di ottenere l'oggetto "exports" né l'ambiente di esecuzione del modulo.


Indipendentemente da ciò, ci sono vantaggi per l'attuale modo set *() funziona (anche se, concesse è documentato, ma viene utilizzato in natura). Per esempio:

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

La discussione nel numero spiega la domanda, c'era persino un [tentativo di risolverlo] (https://github.com/nodejs/node-v0.x-archive/pull/7955) che non è stato accettato. –

1

Nodejs non è browser. "Standard" di cosa stai parlando sono per i browser. Leggere la documentazione:

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

per implementare queste funzioni di temporizzazione 2 "questo" deve essere rilegato all'oggetto finestra (non disponibile in Nodejs) o l'oggetto dei lavoratori (non disponibile in nodejs).

Nodejs ha il proprio oggetto globale, che potrebbe essere un buon obiettivo in questo caso, ma penso che sia meglio associarlo a questa funzione, non a qualche oggetto globale. Sembra che anche gli sviluppatori di Nodejs la pensino così.

Non è contro gli "standard" perché gli standard non hanno nulla su tale ambiente, dove la finestra, la navigazione, gli oggetti di posizione non sono presenti.

Problemi correlati