2010-05-22 2 views
14

Ho ricevuto questo errore e non so quale potrebbe essere la causa. Qualche idea?Rapporto errori JSLint - Cosa c'è di sbagliato in questo?

Problema alla riga 2127 carattere 18: Errore nella variabile "sport". per (sport in sugested_sports)

   // make array 
     var sugested_sports = data.split(","); 

      // pre build DIV 
     var sporty_items = ''; 
     for (sport in sugested_sports) 
     { 
      if (sugested_sports.hasOwnProperty(sport)) { 
       sporty_items += '<a href="#'+identifier[1]+'">'+sugested_sports[sport]+'</a>'; 
      } 
     } 
      // insert DIV 
     DIVsuggestions.html(sporty_items); 

thx alot.

+5

JSLint potrebbe non suggerirvi questo, ma io, per * iterare * un oggetto array (o un oggetto simile ad un array), raccomando sempre vivamente di usare un semplice ciclo 'for', l'istruzione' for-in' è pensato per essere usato per * enumerare * le proprietà dell'oggetto, con questa istruzione, anche se si usa il controllo 'hasOwnProperty' per evitare di enumerare le proprietà sulla catena del prototipo, l'ordine di iterazione è * non garantito * dalle specifiche, può essere arbitrario, quindi il ciclo potrebbe non visitare gli elementi nell'ordine numerico. Vedi anche: [Enumerazione vs. Iterazione] (http://bit.ly/9GPWDY) – CMS

+0

@CMS che link è andato male, grazie per il suggerimento però, ho avuto questo problema pure. – Jordan

+0

@Jordan, la pagina è stata salvata da archive.org, puoi vederlo [qui] (http://web.archive.org/web/20101213150231/http://dhtmlkitchen.com/?category=/JavaScript/&date = 2007/10/21/& entry = iterazione enumerazione-Primitivi-e-Objects). – CMS

risposta

19

Prova

var sport; 
for (sport in sugested_sports) 

Questo si prende cura di dichiarazione delle variabili mancanti e lo colloca al di fuori del ciclo for (vedi jsLint error "Cannot set property 'first' of undefined").

+0

grazie, quanto stupido ;-) – Hans

+6

La dichiarazione della variabile qui causerà un altro errore jslint. Vars deve essere dichiarato nella parte superiore dell'ambito in base a jslint i.e. ambito globale o funzione. –

+4

Se si presta attenzione a JSLint è vero. Se non lo fai, non importa. – Pointy

17

La risposta di Pointy è probabilmente quella di cui si lamenta la lanuggine.


Come regola generale, è necessario prestare attenzione quando si utilizza for (... in ...). Le persone spesso confondono questo costrutto con foreach da C#, o altri concetti simili in altre lingue, quando in realtà non è correlato. Il costrutto javascript for in esegue iterazioni su tutti i membri dell'oggetto, anziché solo sui valori di una raccolta, compresi i metodi e le proprietà. Questo comportamento può spesso portare a effetti collaterali imprevisti se non si è consapevoli di come funziona in anticipo.

Ad esempio:

x = ['one', 'two']; 
for (var value in x) { 
    alert(value); 
} 

che produce due avvisi, il primo contaning 0 e la seconda 1, in particolare gli indici della collezione.

Se cambiamo che un po ':

x = ['one', 'two']; 
x.method = function() {}; 
for (var value in x) { 
    alert(value); 
} 

Finiamo con tre allarmi questa volta, 0, 1, e method. Questo è il comportamento inaspettato a cui mi riferivo. Va bene usare in se sai cosa fa, ma ho visto che catturare le persone in più di un'occasione.

le seguenti opere con entrambi esempi:

x = ['one', 'two']; 
for (var i = 0; i < x.length; i++) { 
    alert(i); 
} 
+0

+1 Impossibile concordare di più, inoltre, l'ordine di iterazione non è garantito dalle [specifiche della lingua] (http://bclary.com/2004/11/07/#a-12.6.4), le proprietà (gli indici di array) potrebbero non essere visitati nell'ordine numerico, e inoltre, se l'oggetto 'Array.prototype' è esteso (come [alcune librerie] (http://mootools.net/docs/core/Native/Array) continuano a farlo), queste proprietà saranno anche elencate ... – CMS

+2

+1 questa dovrebbe essere la risposta accettata – NimChimpsky

2
var sugested_sports = data.split(","), 
    sport, 
    sport_items = ''; 

    for (sport in sugested_sports) 
    { 
     // 
    } 
3

Tutto l'errore significa in JSHint/JSLint è che non ha dichiarato la propria chiave/iteratore variabile. Come @Christopher suggests, JSLint vuole di dichiarare che nella parte superiore del suo campo di applicazione (google JavaScript hoisting per maggiori informazioni sul sollevamento, like this link):

/*global data, identifier, DIVsuggestions */ 
// We'll pretend all of the above were passed in from a function's parameters 
// by using JSLint's "global" keyword -- now you can paste this code into 
// jslint.com and have it pass muster. 

// make array 
var sugested_sports = data.split(","), 
    sporty_items = '', // pre build DIV 
    sport; // <<<< **** DECLARE YOUR "KEY" HERE **** 

for (sport in sugested_sports) 
{ 
    if (sugested_sports.hasOwnProperty(sport)) { 
     sporty_items += '<a href="#'+identifier[1]+'">' 
      +sugested_sports[sport]+'</a>'; 
    } 
} 
// insert DIV 
DIVsuggestions.html(sporty_items); 

Questo errore bad for in variable qui si riduce alla stessa di un errore di 'sport' was used before it was defined altrove.


EDIT: Vale la pena ricordare che, se il vostro for è in una funzione interna, è necessario dichiarare la variabile for in in quello stesso contesto. JSLint si lamenterà se dichiari lo for in nel contesto genitore.

Esempio:

function spam(d) 
{ 
    var fnTest, row; // `row` is defined "too early" 

    fnTest = function (data) { 
     for (row in data) 
     { 
      if (data.hasOwnProperty(row)) 
      { 
       console.log(data.row); 
      } 
     } 
    }; 

    fnTest(d); 
} 

Per rendere le cose felici, spostare row nella funzione interna. Anche se tecnicamente è ancora nel campo di applicazione, a JSLint non piace la "superscope" che è stata utilizzata prima.

function spam(d) 
{ 
    var fnTest; 

    fnTest = function (data) { 
     var row; // and JSLint is happy! ;^D 
     for (row in data) 
     { 
      if (data.hasOwnProperty(row)) 
      { 
       console.log(data.row); 
      } 
     } 
    }; 

    fnTest(d); 
} 


A proposito, James' preoccupazione è coperto dal controllo hasOwnProperty l'OP è inserito. Prendi quel controllo, e JSLint si lamenterà: "Il corpo di un for in dovrebbe essere racchiuso in un'istruzione if per filtrare le proprietà indesiderate dal prototipo". Here's a little more on hasOwnProperty with for... in, if you're interested.

+0

Il downlocoter anonimo desidera commentare? Non riesco a risolvere la tua preoccupazione senza alcune informazioni (e questa risposta è davvero ciò che JSLint sta facendo qui, quindi sono curioso). – ruffin