admin管理员组

文章数量:1317906

function wrapper() {
    var $R = {};

    $R.expandFont = function (direction, max_time) {
        // wtf? $R jslint error
        var self = this,
            el_prim = self[0],
            $R = {};

        alert(direction + max_time + el_prim + $R);
    };
}

This snippet gives error:

line 573 character 13
'$R' is already defined.

I think it is clear that it has not been previously defined.

$R was defined in the outer scope, but this should not be relevant. I should be able to define a local variable with the same name as JavaScript ( the language ) is function scoped. Yes, I know it is not block-scoped, but it is function scoped.

It is basic scoping rules. What gives?

Is this a jslint bug?

function wrapper() {
    var $R = {};

    $R.expandFont = function (direction, max_time) {
        // wtf? $R jslint error
        var self = this,
            el_prim = self[0],
            $R = {};

        alert(direction + max_time + el_prim + $R);
    };
}

This snippet gives error:

line 573 character 13
'$R' is already defined.

I think it is clear that it has not been previously defined.

$R was defined in the outer scope, but this should not be relevant. I should be able to define a local variable with the same name as JavaScript ( the language ) is function scoped. Yes, I know it is not block-scoped, but it is function scoped.

It is basic scoping rules. What gives?

Is this a jslint bug?

Share Improve this question edited Sep 18, 2013 at 19:47 please_delete_my_account asked Jul 24, 2013 at 20:30 please_delete_my_accountplease_delete_my_account 1199 bronze badges 13
  • Are you using prototype.js? It defines $R. What happens if you omit this code and type $R in the console? – Paul Commented Jul 24, 2013 at 20:31
  • 2 It doesn't give me that result when I run that code through JS Lint. – Quentin Commented Jul 24, 2013 at 20:32
  • To successfully set $R.something = function(){...}; $R has to be defined. – Paul Commented Jul 24, 2013 at 20:36
  • it might be because you are sawing off the limb you are sitting on... – dandavis Commented Jul 24, 2013 at 20:39
  • 1 @WilliamTweed — Presumably, when you created your reduced test case, you reduced it so far that the problem you described went away. – Quentin Commented Jul 24, 2013 at 20:45
 |  Show 8 more ments

4 Answers 4

Reset to default 6

This is a new feature in JSLint. It was added by a mit on 24 July 2013. The following example demonstrates the cause of the error:

(function () {
    var a = 1; // This declaration...
    return function () {
        var a = 2; // ... is shadowed by this one.
    };
}());

It appears that the warning is only issued when JSLint encounters a variable declared in function scope (not in the global scope) that is later shadowed (which may explain why menters on your question were unable to reproduce it).

It appears that currently there is no way to turn off this warning.

Crockford has the following to say about this new warning:

JSLint now warns when a var is defined that has the same name as something in the outer scope. This is confusing because the reader cannot easily tell which variable he is looking at. It is sometimes an error because the new variable is accidentally hiding the old one. In some cases, the old one is the one intended.

I will get a page fully explaining this up on http://jslinterrors. as soon as I get a chance.

I think that your understand yourself, that if you rename $R in outer or in inner scope of the function the JSLint "error" will be fixed.

I decided to write my answer only because I think there are misunderstanding about the goal of JSLint. It's not just a tool which helps you to find errors from the point of view of JavaScript language. You can consider the tool as AddOn to the book JavaScript: The Good Parts. Douglas Crockford tried to show which constructions of the language could be misunderstood by people which read the code. Some from the potential misunderstandings he declared as "warnings", another as "errors". Some from the "warnings" or "errors" can be suppressed by ments like /*jslint ... */ another not (like declaration of var inside of for-loop header). The choice which potential misunderstandings should be interpret as a "warning" and which one as an "error" is very subjective and represents only the personal meaning of Douglas Crockford.

I'm not always agree with remendations of Douglas Crockford, but the warning ("error"): '$R' is already defined I would personally find also as critical because of difficulties to read such code. I would remend you to rename one from $R variables too. I want to emphasize one more time that the goal of such changes not fixing of an JavaScript error, but improving of readability of your program for other people.

By the way I would remend you to use variables with all capital letters only on the top level ($R looks so, independent from the first $ letter). See the last sentence of the JSLint remendation about the naming convention.

line 573 character 13
'$R' is already defined

This is because $R is already defined. Two options:

Change the variable name

Or change your code to this:

var $R = {};

$R.expandFont = function (direction, max_time) {
    // wtf? $R jslint error
    var self = this,
        el_prim = self[0];

    $R = {};

Also, see this post by DC on redefinition.

Obviously,

$R is causing confusion. To the jslint syntax analyzer and the the members of SO. Change it, when you move from outer scope to inner scope.

From $R to something like $PR, or other.

There is no need to cause this confusion, when you could simply change the variable name.

Crockford is no fool. These are good guidelines should you choose to follow them.

本文标签: javascriptJslint claims variable is already defined (1)Stack Overflow