6

JSHint shows the error: "Function declared within loop referencing an outer scope variable may lead to confusing semantics". How can I improve the following code to get rid of the warning?

var getPrecedence  = function getPrecedence(operator, operators) {
    var keys = Object.keys(Object(operators));
    for (var i = 0, len = keys.length; i < len; i++) {
        var check = Object.keys(operators[keys[i]]).some(function (item) {
            return item === operator;
    });
    if (check) return operators[keys[i]][operator];
    }
};
5
  • It would help us help you if you showed us an example of the structure of operators. Not least because Object(operators) looks quite odd looks quite odd... Commented Jan 25, 2018 at 11:49
  • This is operators. Commented Jan 25, 2018 at 13:05
  • this.operators = {"operators": { "^": 1, "*": 2, "/": 2, "%": 2, "+": 3, "-": 3, }, "functions": { "log": 0, "sin": 0, "cos": 0, "tan": 0, }, "brackets": { "open": ["("], "close": [")"] }, "equal": { "=": 4 } }; Commented Jan 25, 2018 at 13:05
  • To improve the question, use the "edit" link under the question, not comments (particularly not when you need code formatting). Commented Jan 25, 2018 at 13:07
  • @Kasia You might want to change your data structure into having a single level only, like {"^": {prec: 1, type: "op"}, "*": {prec: 2, type: "op"}, "log": {prec: 0, type:"fn"}, "(": {prec: 4, type:"open"} or so. (Although your structure for the brackets doesn't seem to fit in there anyway) Commented Jan 25, 2018 at 13:27

2 Answers 2

6

You are supposed not to use the function expression inside the loop body, but instead declare it outside:

function getPrecedence(operator, operators) {
    function isOperator(item) {
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        return item === operator;
    }
    var keys = Object.keys(Object(operators));
    for (var i = 0, len = keys.length; i < len; i++) {
        var check = Object.keys(operators[keys[i]]).some(isOperator);
//                                                       ^^^^^^^^^^
        if (check) return operators[keys[i]][operator];
    }
}

Of course the whole thing could be simplified by just using includes instead of some, and find instead of the loop:

function getPrecedence(operator, operators) {
    var keys = Object.keys(Object(operators));
    var opkey = keys.find(key =>
        Object.keys(operators[key]).includes(operator)
    );
    if (opkey) return operators[opkey][operator];
}

And finally, Object.keys(…).includes(…) can be simplified to operator in operators[key].

Sign up to request clarification or add additional context in comments.

1 Comment

"And finally, Object.keys(…).includes(…) can be simplified to operator in operators[key]" In this case, though not, of course, in the general case.
1

Add it before calling the function, this one will bypass that check

/* jshint -W083 */

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.