5 ms·
I still don't understand why neither JSs var or let allow you to redefine the variable with the same name. I makes chaining things while debugging so much hard
by heavenlyblue 7y ago
I still don't understand why neither JSs var or let allow you to redefine the variable with the same name.
I makes chaining things while debugging so much harder:
let a = a.project();
let a = debug(a);
let a = a.eject();
vs
let a1 = a.project();
let a1d = debug(a1);
let a2 = a1d.eject();
- EGreg 7y agoWhat’s wrong with var a = ...; a = a.project(); a = debug(a); a = a.eject();
- pcr910303 7y agoThat can’t show the programmer’s intent whether it is mutation (e.g. a = a + someNum) verses defining a new variable with different types (but has a similar meaning so has a same name) (e.g. someKindOfData = [...someKindOfData]) Rust allows this, and it really clears codes up. I don’t have to make up different identifiers for same data but different representations. (e.g. I would do the above code in JS as... someKindOfDataAsArray = [...someKindOfObectAsNodeList])
- deleted 7y ago[deleted]
- EGreg 7y agoWhat are you talking about, LOL
- shortercode 7y agoI always assumed it was to protect against: accidental naming errors, confusion of what a declaration is and copy/paste issues. When I first started writing rust and saw it was a thing I thought it was a terrible idea. I'm a more open towards it now, the strong static analysis Rust does help and it can improve code quality if used in small amounts. However, it still can be quite confusing. Given that JS doesn't restrict the type of a declaration you can just assign a new value to it, place it in a small scope or use a chain.
- heavenlyblue 7y ago>> However, it still can be quite confusing. I don't know - it's never confusing to me. I just use the IDE that allows me to view the types of the variables whenever I need to see them. IDE also highlights the definitions and then the usages of the variable, including the syntax scope where it's used. You're definitely using the wrong tools for the job if you get confused with that little detail. >> Given that JS doesn't restrict the type of a declaration you can just assign a new value to it, place it in a small scope or use a chain. Yeah, but I don't want to semantically assign a new value to the variable. I want this to be a new variable, because it is a new variable. So the point of var is slightly over exaggerated because they could have gone the python way and simply allow declarations to be anything that is an assignment.
- jacobwilliamroy 7y agovar and let tell the compiler the scope in which it should declare the variable (oversimplifying). If var or let are not present, the variable is declared in the global scope; unless you're in strict-mode, then you get a scolding. So var and let are only tangential to the whole declaration process and only indicate the scope in which the variable is bound. I feel confused. Why do you want your assignment statements to be prefixed with var's and let's?
- z3t4 7y agoif you put var in-front you don't have to worry about reassigning a variable from parent scope. You also make assignment and comparison semantically different, example var foo=1; vs foo=1 if(foo=1) and it's thus easier to spot bugs and understand the code.
- z3t4 7y agoWhat IDE (+plugins?) are you using ?
- __ryan__ 7y agolet a = a.project(); a = debug(a) a = a.eject(); This is perfectly legal.
- heavenlyblue 7y agoSo what's the point of having let, then?
- chrisweekly 7y agoblock scope
- rpeden 7y agolet declares a block-scoped variable, while var declares a function-scoped variable. Limiting a variable's scope can help avoid subtle and potentially annoying errors. For example, if you use a let variable inside an if block, it'll only be accessible by code inside the block. If you use var inside an if block, your variable will be visible to the entire function.
- heavenlyblue 7y agoThe truth is that if you need to declare a variable outside your current scope you should probably declare it in the outside scope in the first place. In the scenario with var/let I need to grok the code in order to tell which variables are visible in my current scope.
- jarekkruk 7y agoI tend to mainly use const, let only when necessary. I never use var and set linter to scream about it at me. IE11 supports it, so unless you develop application for IE compatibility mode (my condolences) I don't see a reason to use var. On the other hand var mainly bites you when declaring closures inside loops, also hoisting is just plain weird.
- 7y ago
- HelloNurse 7y agolet projected = a.project(); let debugged = debug(projected); let ejected= debugged.eject();
- heavenlyblue 7y agoAnd you need to change 3 lines in total (also you need to make changes mid-lines, too) in order to simply view the data in between, vs only 1 line. And by the way - if you paid attention in the first place my post actually has exactly what you've just written.
- HelloNurse 7y agoMeaningful names? I don't think so.
- heavenlyblue 7y agoAnd what is that meaning for if the functions you are calling have proper names?
- HelloNurse 7y agoIf you use let it means you intend to use that binding "later", up to the end of the scope, and within that scope the value shall not change: that's the Whole point. If you want a variable you can assign successive different values to, it's an entirely different thing, and there have always been var and the assignment operator for that.
- heavenlyblue 7y ago>> within that scope the value shall not change: that's the Whole point. That's pure BS. This is only true for atomics, the value can change (under let, var and const) as we can easily see with Array.push, for example.
- pault 7y agoI think you mean `const`. `let` can be reassigned.
- addicted 7y agoWithout getting into the merits of allowing redefines in a loosely typed language, the simple reason why JS can't support this is hoisting. Any var/let statement of the form var a = 1; is interpreted as 2 statements. (1) The declaration of the variable which is hoisted to the beginning of the variable scope, and the (2) setting of the value, which is done at the location the var statement is at. Having multiple let statements would mean the same variable is declared and hoisted to the same location multiple times. So it's basically unnecessary and breaks hoisting semantics. In addition, the downside risk of accidentally redefining a variable is probably far greater than the semantic benefits of making the redefinition clear to a reader (esp since I think that benefit is extremely limited in a loosely typed language like JS anyways).
- jacobwilliamroy 7y agoThis human gets it. I'd like to add that if you would like to be clear about what your assignment is doing, put some comments in there.
- hajile 7y agoThat's not quite accurate. It's actually the reverse. Think of the closure as an object. It contains variables like `this`, `arguments`, a pointer to the parent closure, all your variables, etc. The interpreter needs to create this closure object BEFORE it runs the function. Before the function can run, it has to be parsed. It looks for any parameters, `var` statements, and function statements. These are all added to the list of properties in the object with a value of `undefined`. If you have `var foo` twice, it only creates one property with that name. Now when it runs, it just ignores any `var` statements and instead, it looks up the value in the object. If it's not there, then it looks in the parent closure and throws an error if it reaches the top closure and doesn't find a property with that name. Since all the variables were assigned `undefined` beforehand, a lookup always returns the correct value. `let` wrecks this simple strategy. When you're creating the closure, you have to specify if a variable belongs in the `var` group or in the `let` group. If it is in the `let` group, it isn't given a default value of `undefined`. Because of the TDZ (temporal dead zone), it is instead give a pseudo "really undefined" placeholder value. When your function runs and comes across a variable in the let group, it must do a couple checks. Case 1: we have a `let` statement. Re-assign all the given variables to their assigned value or to `undefined` if no value is given. Case 2: we have an assignment statement. Check if we are "really undefined" or if we have an actual value. If "really undefined", then we must throw an error that we used before assignment. Otherwise, assign the variable the given value; Case 3: We are accessing a variable. Check if we are "really undefined" and throw if we are. Otherwise, return the value. To my knowledge, there's no technical reason for implementing the rule of only one declaration aside from forcing some idea of purity. The biggest general downside of `let` IMO is that you must do extra checks and branches every time you access a variable else have the JIT generate another code path (both of which are less efficient).
- seanwilson 7y agoAnother disadvantage of reusing the same variable name is the order of the statements is usually important and it isn't always obvious how, especially when you do this in longer functions. When you're refactoring, you then have to be much more careful when moving lines of code of code around. With unique names, you get more of a safety net (including compile time errors if you're using something like TypeScript).