Overview
This is one of the longer messages that JSLint reports. Here it is in full:
The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.
Here, JSLint is counselling you against making the assumption that the only object members ever found will be those that have been explicitly added to it (and not, say, to a base object).
For ‘Member’ In ‘Object’
Firstly, let’s recreate it:
var a = {b:1, c:2};
var x = 0;
for (x in a){
alert(a[x]);
}
In the above code, we are creating a simple object using the object literal notation, and then iterating over its member. All seems well when we run it, as can be seen as this JSFiddle. So, what is the reason for JSLint’s complaint?
Here we are relying on the fact that elsewhere in our code base no-one will ever tinker with the underlying object, and add some unexpected properties or methods. Consider the following line of code:
Object.prototype.somefn = function(){};
Here, the prototype keyword allows us to extend the underlying object, effectively adding a new method somefn to every object in our system. Its effect can be seen in this JSFiddle – as well as the “1″ and “2″ alerts we also get the function definition alerted.
Clearly we want to filter out properties or methods that are not part of the immediate collection. But How?
We could extend out function to check for properties explicitly, like so:
function AlertAll(o){
var x = 0;
for (x in o){
if (x === 'b' || x === 'c'){
alert(o[x]);
}
}
}
(Also in this updated fiddle)
But this isn’t very scalable, of, for that matter, very good! It introduces all sort of dependencies, coupling, technical debt, and other general bad words when it comes to programming. So how do we search for an objects own properties?
Easy! We check the hasOwnProperty property of the object, like so:
function AlertAll(o){
var x = 0;
for (x in o){
if (o.hasOwnProperty(x)){
alert(o[x]);
}
}
}
(Also in this further updated fiddle)
For ‘Element’ in ‘Array’
Done correctly, the for…in construct can be quite useful for iterating over object members (as shown in the above example). In JavaScript, every object has an equivalent array representation, so we can access the members using the array literal notation []. So, by logical extension, we can also use the for..in construct to iterate over a pure array.
This is madness inviting atrophy, as shown in the following code:
function AlertAll(arr){
var x = 0;
for (x in arr){
alert(arr[x]);
}
}
//We don't actually need to extend Array to show the ensuing atrophy
//Array.prototype.somefn = function(){};
var a = [0,1];
AlertAll(a);
If you don’t mind having to dismiss about 30 dialog boxes then feel free to see the problems at this JSFiddle. By examining the hasOwnProperty property as before we can, of course, solve this, but this is missing the point somewhat, which is “What is the point?”
We all (should?) know how to iterate over an array in JavaScript. We do it with a standard for loop like so:
function AlertAll(arr){
var x = 0;
for (x=0; x < arr.length; x++){
alert(arr[x]);
}
}
var a = [0,1];
AlertAll(a);
Provided for all its pointlessness at this updated JSFiddle.
Resouces
As always, a couple of resources from Stack Overflow:
Stack Overflow: What does the JSLint error ‘body of a for in should be wrapped in an if statement’ mean?
Stack Overflow: JavaScript: JSLint error “The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype”
A Guide To JSLint Messages
This article is one of a series on the error and warning messages produced by JSLint.
JavaScript, javascript-for-in, jslint, jslint-messages