
rules.jshint.W089.html Maven / Gradle / Ivy
Show all versions of sonar-web-frontend-js Show documentation
When do I get this error?
The "The body of a for in should be wrapped in an if statement to filter
unwanted properties from the prototype" error is thrown when JSLint encounters
a for-in
statement in which the first statement is not an if
statement
containing a call to the hasOwnProperty
method. JSHint and ESLint are a
little more leniant and do not enable this feature by default. They will only
warn when they encounter a for-in
statement in which the first statement is
not an if
statement, regardless of the condition of that if
statement.
Here's an example in which we attempt to enumerate the properties of an object:
x 1/*jshint forin: true */
2/*eslint guard-for-in: 1 */
3/*global doSomething */
4
5var me = {
6 name: "James",
7 age: 23
8 },
9 prop;
10
11for (prop in me) {
12 doSomething(prop);
13}
14
Why do I get this error?
This error is raised to highlight bad practice and code that may not work
as you expect it to. Your code may run without error, depending on whether
you've extended the prototype of the object you're trying to enumerate, or, for
example, Object.prototype
, with enumerable properties, but it's bad practice
and could lead to problems in the future.
The for-in construct will enumerate all enumerable properties of an object,
whether they belong to the object itself or an object in its prototype chain.
Consider the following example, in which we add a completely useless random
method to Object.prototype
:
5 1Object.prototype.random = function () {
2 "use strict";
3 return Math.random();
4};
5
After the above snippet has executed, all objects in our script will have access
to that random
method (via their prototype chain, all the way down to
Object.prototype
). Since we have not defined our method as non-enumerable
(which is only possible in ECMAScript 5 environments that support the
Object.create
and Object.defineProperty
methods), it will be enumerated
along with any other enumerable properties by a for-in
loop.
However, all objects also inherit a (non-enumerable) method called
hasOwnProperty
, which can be used to check whether or not an object has a
property with a given identifier that belongs to it and not to its prototype, or
any objects down its prototype chain (ES5 §15.2.4.5):
3. Let desc be the result of calling the [[GetOwnProperty]] internal
method of O passing P as the argument.
4. If desc is undefined, return false.
5. Return true.
The "[[GetOwnProperty]] internal method" (ES5 §8.12.1)
returns a value that tells the engine whether or not the object in question has
an "own property" with the given identifier. And "own property" is defined as a
"property that is directly contained by its object" (ES5
§4.3.30).
In our example, since the random
method would be accessible (via inheritance)
to the me
object, but isn't an "own property" of it, we would need to use the
hasOwnProperty
method to ensure we don't mistakenly handle it:
16 1/*jshint forin: true */
2/*eslint guard-for-in: 1 */
3/*global doSomething */
4
5var me = {
6 name: "James",
7 age: 23
8 },
9 prop;
10
11for (prop in me) {
12 if (me.hasOwnProperty(prop)) {
13 doSomething(prop);
14 }
15}
16
In JSHint 1.0.0 and above you have the ability to ignore any warning with a
special option syntax. The identifier of this warning is W089.
This means you can tell JSHint to not issue this warning with the /*jshint
-W089 */
directive.
In ESLint the rule that generates this warning is named guard-for-in
. You can
disable it by setting it to 0
, or enable it by setting it to 1
.