3

Is there a way to scope a variable that is assigned within an if statement's condition?

The following will of course assign el to my element and will be globally scoped (as will date).

if (el = document.querySelector('.footer__year'), el) {
    var date = new Date();
    el.textContent = date.getFullYear();
}

But say I wrap that in an iife.

(function() {
    if (el = document.querySelector('.footer__year'), el) {
        var date = new Date();
        el.textContent = date.getFullYear();
    }
})();

el is still accessible via window.el but date is not.

Using if (var el = document.querySelector('.footer__year')) ends up with an unexpected token error.

Is there a way to scope this?

Also, I am aware that the following would fix my issue.

(function() {
    var el = document.querySelector('.footer__year');
    if (el) {
        var date = new Date();
        el.textContent = date.getFullYear();
    }
})();

But would like to know if this is even possible!

UPDATE

Overall variable scoping is not the problem here (the last example works just fine and el is not globally scoped), it is the ability to declare vs. assign a variable within the condition of an if statement.

MJ12358
  • 1,378
  • 1
  • 9
  • 15
  • `var el; if (el = .....` – Keith Nov 23 '18 at 23:13
  • The last one is the closest to what you want. Even with ES6, `let` is not scoped to if statements in that way. – c1moore Nov 23 '18 at 23:14
  • The core problem with then presented code is “var”/“let” are not expressions: fix this and then the underlying scoping rules can be discussed. – user2864740 Nov 23 '18 at 23:21
  • 1
    Possible duplicate of [What is the scope of variables in JavaScript?](https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript) – stealththeninja Nov 23 '18 at 23:22
  • 2
    I disagree with the 'possible duplicate'. I was unclear on variable assignment vs. declaration within the condition of an `if` statement. Thanks @MarkMeyer for clarifying! – MJ12358 Nov 23 '18 at 23:44
  • I agree @MJ12358, I don't think that question answers your question. – Mark Nov 23 '18 at 23:47

2 Answers2

2

The condition inside of the if parenthesis needs to be an expression. var, const and let declarations are statements, which means you can't declare a variable with the if condition (even though you can assign a variable, because assignment is an expression).

You can take advantage of block scoping with let or const to avoid the IEFE:

var el = 100 // outside
{ let el = 5
  if (el === 5) {
        console.log("inside:", el)
  }
}
console.log("outside:", el)  // still outside
Mark
  • 90,562
  • 7
  • 108
  • 148
1

In short, no. There is no way you can prevent an assignment in an if statement from being hoisted globally.

A workaround for this (though a terrible one-off that still flashes the variable in the global scope) would be to simply use delete window[var] which will remove the variable from the global scope after use. It's not advisable and if you showed your boss they'd either insist you get more training or send you off to greener pastures, but the result is more or less similar.

(function() {
    if (el = document.querySelector('.footer__year'), el) {
        var date = new Date();
        el.textContent = date.getFullYear();
        delete window["el"];
    }
})();
console.log(el);
<div class="footer__year"></div>

There are a slew of problems with doing the above. At worst you'll be rewriting variables in Global Scope and then deleting them, causing the rest of your code not to function and throwing an error, at best you'll be performing more operations for no real reason, and making your code much less clear to others since there's effectively an invisible declaration. It's honestly just a mess that's best to, and easy to, avoid.

TLDR; No. Utilize proper declarative statements and the appropriate keywords and remain employed/happy.

zfrisch
  • 8,474
  • 1
  • 22
  • 34