# Best Practices

Rules which enforce generally accepted best practices.

## AvoidWithStatement

Since: PMD 5.0.1

Priority: High (1)

Avoid using with - it’s bad news

This rule is defined by the following XPath expression:

    //WithStatement

Example(s):

    with (object) {
        property = 3; // Might be on object, might be on window: who knows.
    }

Use this rule by referencing it:

    <rule ref="category/ecmascript/bestpractices.xml/AvoidWithStatement" />

## ConsistentReturn

Since: PMD 5.0

Priority: Medium High (2)

ECMAScript does provide for return types on functions, and therefore there is no solid rule as to their usage. However, when a function does use returns they should all have a value, or all with no value. Mixed return usage is likely a bug, or at best poor style.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.ecmascript.rule.bestpractices.ConsistentReturnRule

Example(s):

    // Ok
    function foo() {
        if (condition1) {
            return true;
        }
        return false;
    }

    // Bad
    function bar() {
        if (condition1) {
            return;
        }
        return false;
    }

This rule has the following properties:

Name | Default Value | Description | Multivalued
--- | --- | --- | ---
rhinoLanguageVersion | ES6 | Specifies the Rhino Language Version to use for parsing. Defaults to ES6. | no
recordingLocalJsDocComments | true | Specifies that JsDoc comments are produced in the AST. | no
recordingComments | true | Specifies that comments are produced in the AST. | no

Use this rule with the default properties by just referencing it:

    <rule ref="category/ecmascript/bestpractices.xml/ConsistentReturn" />

Use this rule and customize it:

    <rule ref="category/ecmascript/bestpractices.xml/ConsistentReturn">
        <properties>
            <property name="rhinoLanguageVersion" value="ES6" />
            <property name="recordingLocalJsDocComments" value="true" />
            <property name="recordingComments" value="true" />
        </properties>
    </rule>

## GlobalVariable

Since: PMD 5.0

Priority: High (1)

This rule helps to avoid using accidently global variables by simply missing the "var" declaration. Global variables can lead to side-effects that are hard to debug.

This rule is defined by the following XPath expression:

    //Assignment[Name/@GlobalName = true()]

Example(s):

    function(arg) {
        notDeclaredVariable = 1;    // this will create a global variable and trigger the rule

        var someVar = 1;            // this is a local variable, that's ok

        window.otherGlobal = 2;     // this will not trigger the rule, although it is a global variable.
    }

Use this rule by referencing it:

    <rule ref="category/ecmascript/bestpractices.xml/GlobalVariable" />

## ScopeForInVariable

Since: PMD 5.0

Priority: High (1)

A for-in loop in which the variable name is not explicitly scoped to the enclosing scope with the ‘var’ keyword can refer to a variable in an enclosing scope outside the nearest enclosing scope. This will overwrite the existing value of the variable in the outer scope when the body of the for-in is evaluated. When the for-in loop has finished, the variable will contain the last value used in the for-in, and the original value from before the for-in loop will be gone. Since the for-in variable name is most likely intended to be a temporary name, it is better to explicitly scope the variable name to the nearest enclosing scope with ‘var’.

This rule is defined by the following XPath expression:

    //ForInLoop[not(child::VariableDeclaration)]/Name[1]

Example(s):

    // Ok
    function foo() {
        var p = 'clean';
        function() {
            var obj = { dirty: 'dirty' };
            for (var p in obj) { // Use 'var' here.
                obj[p] = obj[p];
            }
            return x;
        }();

        // 'p' still has value of 'clean'.
    }
    // Bad
    function bar() {
        var p = 'clean';
        function() {
            var obj = { dirty: 'dirty' };
            for (p in obj) { // Oh no, missing 'var' here!
                obj[p] = obj[p];
            }
            return x;
        }();

        // 'p' is trashed and has value of 'dirty'!
    }

Use this rule by referencing it:

    <rule ref="category/ecmascript/bestpractices.xml/ScopeForInVariable" />

## UseBaseWithParseInt

Since: PMD 5.0.1

Priority: High (1)

This rule checks for usages of parseInt. While the second parameter is optional and usually defaults to 10 (base/radix is 10 for a decimal number), different implementations may behave differently. It also improves readability, if the base is given.

See also: parseInt()

This rule is defined by the following XPath expression:

    //FunctionCall/Name[
         @Image = 'parseInt'
         and
         count(../*) < 3
    ]

Example(s):

    parseInt("010");    // unclear, could be interpreted as 10 or 7 (with a base of 7)

    parseInt("10", 10); // good

Use this rule by referencing it:

    <rule ref="category/ecmascript/bestpractices.xml/UseBaseWithParseInt" />