9 ms·
var's function scope is a feature! You don't have to place variable declarations in the header! (they are hoisted) Placing the var declarations where they are u
by z3t4 10y ago
var's function scope is a feature! You don't have to place variable declarations in the header! (they are hoisted) Placing the var declarations where they are used makes the code easier to understand.
The point of constructor functions is not having to write new. So classes does nothing besides syntactic sugars over the prototype system, witch actually makes it more complicated and the code harder to maintain.
Async programming is hard, but not because of callbacks. Promises is just a wrap around callbacks, witch just adds complexity and more boilerplate. It will get better with async/await but I will still prefer simple callbacks.
Arrow functions are very nice for one liners, but will ruin your code if you use them everywhere instead of named functions. You should always name your closures, then it's easier to debug and lift them out.
- chrisseaton 10y agoHow is having var be function scoped instead of block scoped a useful feature?
- treehau5 10y agoParent literally said why in the rest of their comment. And if you still don't understand why, this probably goes back to understanding JavaScript fundamentals. Not understanding function scope vs block scope is the number one smell for me that someone did not learn JavaScript correctly.
- chrisseaton 10y agoI don't think anything in the rest of their comment has anything to do with block scoping vs function scoping. I do understand the technical difference very well - I have a PhD in implementing programming languages with function scoping like JavaScript. If you agree with the person I was replying to maybe could you humour me and explain why you think function-scoping var is a useful feature?
- treehau5 10y ago> I do understand the technical difference very well - I have a PhD in implementing programming languages like JavaScript. I am happy for your PhD and that it is for implementing programming languages like JavaScript. My assertion is the advantage of having function scoping is apparent to those who understand function scoping. Block scoping-style programming in JavaScript was always, in my experienced, shoe-horned in by people who wanted to make JavaScript more like Java. That is all there is to my point.
- fenomas 10y ago> My assertion is the advantage of having function scoping is apparent to those who understand function scoping. I assert that if you can't say what the advantage is then you don't understand it yourself. "You'd see the advantages if you understood this, and since you don't you must not understand it" is not a reasonable thing to say to people.
- deleted 10y ago[deleted]
- deleted 10y ago[deleted]
- chrisseaton 10y agoBut I do understand function scoping. I understand what it is, what its semantics are, and how to implement and use it. And the advantage over block scoping isn't apparent to me. But even if it should be apparent to me, why can't you explain the reason to me? What is this - some kind of argument that is impossible to comprehend unless you already agree with it? I can understand your argument that block scoping was shoe-horned into JavaScript, post hoc, but that isn't a technical argument for the benefit of function scoping, is it?
- z3t4 10y agoeven if block scope was better, its not worth having three ways to declare a variable. Most JS programmers do not know about scope and they do not declare variables, but if they do, they more likely mean it to belong to the function, like in VBscript or PHP, rather then to the if statement. Explaining why you should declare variables is hard. Now I also have to explain block scope, and angel brackets now makes a huge difference! if(...) // use angel brackets foo = 1; // declare variables if(foo) ...
- tlrobinson 10y agoI understand it well and think relying on hoisting is a bad idea, as do most people. Declaring a var in a block and using it outside of that block (which is what hoisting enables) is the opposite of "Placing the var declarations where they are used". Please provide an example of what you believe to be a good usage of hoisting.
- gbog 10y ago> You should always name your closures Yes. Why? Because you should have readable tracebacks. Why? Because you should receive all meaningful errors reports from the devices.
- epmatsw 10y agoPromises and callbacks have fundamentally different behavior. Promises are much more reliable (only executed a single time, always executed asynchronously vs possibly synchronously, etc.) and also have slightly different execution behavior in the event loop. People emphasize the syntax differences, but that's not the most useful thing about Promises imo. You Don't Know JS's async book has an excellent in-depth writeup on it.
- depr 10y agoThe function passed to the promise is executed synchronously, the call to `then` is always asynchronous.
- epmatsw 10y agoTrue, worded that poorly. The resolutions are always executed asynchronously, versus a callback approach where the code receiving the callback can inappropriately and unexpectedly choose to execute the callback synchronously.
- ChemicalWarfare 10y ago>>> You don't have to place variable declarations in the header! (they are hoisted) probably splitting hairs here but imo "hoisting" as in using variables before they are declared is generally a bad practice especially considering that init assignments are not "hoisted". >>>Arrow functions are very nice for one liners, but will ruin your code if you use them everywhere instead of named functions. Based on arrow functions' relationship with "this" pretty sure the intent is to primarily use arrow functions instead of anonymous functions especially when passing them around as params. Even with one-liners you have to be wary of what "this" is when dealing with an arrow function inside of an object for example.
- WorldMaker 10y agoArrow functions get auto-named in many browsers based on how they are used. This auto-naming is actually being somewhat standardized between browsers and means there is no difference between anonymous-style function () {} and arrow functions. Promises are more than just a wrapper around callbacks because they also standardize behavior between "stacks" of callbacks, by instead "chaining" them and creating a standard infrastructure for things like error propagation down a chain. That error propagation and the ability for simple action chaining is worth having over "simple" callbacks, even without the syntactic sugar of async/await. let/const have similar benefits to function hoisting in that you don't need to declare let/const variables until when you use them. In this case the runtime behavior throws an exception if you try to use them before they are declared (in the so-called hoisting dead zone).
- z3t4 10y agoPromises spreads like a virus so that all asynchronous functions eventually end up returning a Promise. They are hard to understand and it's easy to forget handling errors or return values. I think callbacks are much easier to understand and get right using named functions and closures. If you want to call everything in serial and wait between each step, why not make it synchronous instead of .then chaining ?
- WorldMaker 10y agoThere are other high level operations (combinators) with Promises beyond just .then() chains: Promise.all(), Promise.race() out of the box of the spec; others from various libraries. Doing the equivalent with raw callbacks is much more complicated. The "magic" that Promises bring to code is that they "just look serial" with .then() chains. That's part of the point of Promises and that's part of the infrastructure what powers the ability to write async/await code. Just because it looks nice and serial doesn't mean it is synchronous. (In High Functional speak, Promises are the Continuation monad, and the near isomorphism with synchronous code (especially async/await) is a wonderful product of standardizing the monad.) Which is to say: tl;dr: Promises spreading like a virus is a feature, not a bug.
- tuxracer 10y agoPromises definitely do not just "wrap around" callbacks https://blog.domenic.me/youre-missing-the-point-of-promises/ https://blog.domenic.me/youre-missing-the-point-of-promises/
- minitech 10y ago> var's function scope is a feature! You don't have to place variable declarations in the header! (they are hoisted) Placing the var declarations where they are used makes the code easier to understand. For the vast majority of variables, you don’t need hoisting (i.e. you can declare them in the appropriate scope and only end up using them after the declaration). > The point of constructor functions is not having to write new. Um, what? This is completely wrong. You have to write new with constructor functions unless you specifically add code to check whether you’re in a constructor and re-call with new, which is bad practice. > Async programming is hard, but not because of callbacks. Promises is just a wrap around callbacks, witch just adds complexity and more boilerplate. It will get better with async/await but I will still prefer simple callbacks. No, async/await is just a wrapper around promises. Promises are pretty great overall, and if your Promise code looks like callbacks then you might be using them wrong. (I would always use bluebird[1] over native promises, though.) I agree with you that large parts of ES6 add unnecessary complexity, but I don’t think your examples are well-chosen. [1] http://bluebirdjs.com/ http://bluebirdjs.com/
- z3t4 10y ago> Um, what? Sorry for the confusion, the ES5 example looked like a "factory" function, so I assumed that was what he meant. You do not have to wrap the constructor function in another function! ... function Animal(name) { // This code is run when the object is created. No need to wrap another function around Foo var animal = this; animal.name = name; } Animal.prototype.speak = function speak() { var animal = this; console.log(animal.name + ' makes a noise.'); } Here is a "factory" function: function AnimalFactory(name) { var animalName = name; function speak() { console.log(animalName + ' makes a noise.'); } return {speak: speak} } var animal = AnimalFactory('Animal'); // You can omit new animal.speak(); // animal makes a noise setTimeout(animal.speak, 1000); // you can also do this