0

I've been messing around with JS and various other web-related things lately and kind of learned the whole thing while applying it.

Out of interest I've put my code into a JS validator (jslint.com) and the result is staggering. I do understand most of the warnings, but there is one in particular that I can't get my head around. It reads 'doSomething' is out of scope. Basically, this is the relevant portion, I believe. My entire script is structured like that: ready-function to kick things off and then it goes into the specific functions.

$('document').ready(function () {
    $('#btn').click(function () {doSomething();});
});

function doSomething() {
    console.log('did something');
}

I figured, a variable for instance is "out of scope" if it is declared in an if-expression and used outside of it. Like so:

function whatnot() {
    if (true) {
        var x = 10;
    }
    return x;
}

But how does that translate to my issue? Can you help me understand the problem and maybe give examples for a better code structure (or point me towards some articles that might help?)

Thanks in advance :)

onedude99
  • 11
  • 2
  • it's out of scope of the `document.ready` block - that's likely what the warning means – blurfus May 09 '16 at 15:54
  • Don't guess, make sure: if you run that snippet through JSLint on its own, does it still tell you it's out of scope? – Mike 'Pomax' Kamermans May 09 '16 at 15:54
  • if you directly copy and paste it in jslint.com it does still put out the warning, yes. – onedude99 May 09 '16 at 15:56
  • Maybe **$('document').ready(function () { $('#btn').click(function () {doSomething();}); });** is being executed before doSomething is defined. – F.bernal May 09 '16 at 15:59
  • *"I figured, a variable for instance is "out of scope" if it is declared in an if-expression and used outside of it"* Not in JavaScript, not if you declare it with `var`. JavaScript didn't get block scope until last year, with the introduce of `let` (and `const` and `class`). – T.J. Crowder May 09 '16 at 15:59
  • 1
    Everytime I see a question about JS Lint I find myself lamenting Douglas Crockford's failure to document (at least anywhere near the error messages) his highly opinionated thoughts on what makes good quality JavaScript. . – Quentin May 09 '16 at 16:06

3 Answers3

1

jslint is mistaken. That code will work without any scoping problems.

However, as a matter of style, you might want to define doSomething() above where it is used. Although $('document').ready doesn't get called until the entire DOM is rendered, and that shouldn't happen until after the script tag is fully parsed. As a matter of style, I prefer to define methods before I call them, and jslink would probably be satisfied if you moved your function definition inside of the ready block.

Ken Kinder
  • 12,654
  • 6
  • 50
  • 70
  • 2
    With the code presented, there is **no chance at all** that the `ready` call would occur before `doSomething` is defined. There's no "probably" about it. Function declarations are processed before any step-by-step code is executed. – T.J. Crowder May 09 '16 at 16:00
  • @T.J.Crowder As jquery is implemented, sure. It's still good practice to define your function above where you use it. – Ken Kinder May 10 '16 at 22:00
  • 1
    @KenKinder: It has nothing to do with jQuery. It's how JavaScript, the language, is defined. Replace the `ready` call with a direct cal to `doSomething()`; still works fine: https://jsfiddle.net/2se73shm/ Again: Function declarations are processed before any step-by-step code is executed. Re your "good practice" comment, that's purely a matter of style, and there are plenty of arguments on each side; irrelevant here. – T.J. Crowder May 11 '16 at 06:53
  • Interesting. I had no idea; thanks for the explanation. Updating my answer. – Ken Kinder May 13 '16 at 15:59
0

If you declare your doSomething function before the $('document').ready line then jslint will stop complaining about the out of scope issue.

Gabriel Hautclocq
  • 3,230
  • 2
  • 26
  • 31
-2

In JavaScript, variables are hoisted, essentially this means that the variable declaration is moved to the top of the script file, but remains undefined until it is declared.

If you move the function declaration above the function call in the click handler, the out of scope warning disappears.

Dark Hippo
  • 1,255
  • 2
  • 15
  • 35
  • *"In JavaScript, variables are hoisted, essentially this means that the variable declaration is moved to the top of the script file, but remains undefined until it is declared."* That's A) Irrelevant, the OP's question is about a function declaration, which behaves differently; and B) Incorrect unless you assume the variable is declared with `let`, not `var`. `a = 42; console.log(a); var a = 67;` is perfectly valid (if poorly-written) code in JavaScript which outputs 42. – T.J. Crowder May 09 '16 at 16:05