21 ms·
Overview of JavaScript ES6 features
- neximo64 10y agoUsing const and `splice` breaks the rules: const info = [1,2,3,4] const newInfo = info.splice(2); 'info' has changed
- josephg 10y agoThe const keyword makes the object reference constant. It doesn't make the object's value constant. You can change the contents of 'info' (info.push(5) is fine). You just can't change which object the variable points to. (info = [] will throw). If you know C/C++, the code 'const info = []' makes 'info' a constant pointer to a list not a pointer to a constant list. If you want to stop a variable from being changed, use Object.freeze() - https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze https://developer.mozilla.org/en/docs/Web/JavaScript/Referen...
- samcodes 10y agoThis was what I came to comment on; when introducing ES6 features, this always trips people up. Thanks for "constant pointer to a list, not pointer to a constant list", I will use that next time I explain this. This also means that objects defined with const can be mutated: const x = { y: 2 }; x.y = 3; Doesn't error. However with types that are immutable, like numbers and strings, const really is a constant: const HELLO = "hi" will never change.
- deleted 10y ago[deleted]
- robrichard 10y agoconst only guards against changing the reference that it was assigned to. This won't break because info is still assigned to the same array. It doesn't matter that the array was mutated.
- Tankenstein 10y agoCommon misconception, const only disallows reassignment. For instance, const number = 1337; number = 10; // fails But objects/arrays are not immutable in js, so you can do this: const person = { name: 'Dude' }; person.name = 'Dudette'; Which is perfectly valid. If you want full immutability, i recommend you check out https://facebook.github.io/immutable-js/ https://facebook.github.io/immutable-js/, been running it in production, a real pleasure to work with.
- jasoncchild 10y agoFWIW Immutable.js is not deeply immutable. Seamless-immutable however is.
- masklinn 10y ago> Seamless-immutable however is. Only in development mode, by freezing the objects.
- Roboprog 10y agoAny popular "deep freeze" utilities around?
- pitaj 10y agofunction deepFreeze(obj) { const out = Object.freeze(obj); Object.keys(out).forEach(key => { if (typeof out[key] === 'object') { out[key] = Object.freeze(out[key]); } }); return out; }
- Roboprog 10y agoI think you meant "out[ key ] = deepFreeze( out[ key ] )" in the innermost step :-) (recursive)
- Cthulhu_ 10y agoThe only language I've found / used so far that has these (expected) mechanics is Swift, which, when using a `let` for e.g. a list, will make the list itself immutable (in addition to the reference). It's really something that is confusing in every language that has some form of 'final', be it Java (which added immutable list implementations or wrappers to their existing collections), C++, JS, or what-have-you.
- masklinn 10y ago> The only language I've found / used so far that has these (expected) mechanics is Swift Rust has similar semantics: https://is.gd/hsRjPh https://is.gd/hsRjPh versus https://is.gd/ROgzXl https://is.gd/ROgzXl IIRC you can also declare const objects in C++, but constness is more complex and overridden there.
- mattmanser 10y agodestructing is very useful and encourage good coding styles Is it? Personally I'd say that was bad code. What so wrong with using the original objects? Putting aside the need to variable swap once a year or so, all the other examples look really confusing to me and unclear what they're doing. The `Deep Matching` especially.
- fnord123 10y agovar lst = [[1,2], [3,4], [5,6]]; for (var [a,b] of lst) { console.log(a + b); } You could write a `zip` function to merge multiple iterables together and iterator them. Or use something like `.enumerate()` to yield indices along with the values.
- rubber_duck 10y ago>Is it? Yes, but not in the silly example showed. Consider something like : zip(fooArray, barArray, bazArray).map(([foo, bar, baz]) => foo + bar + baz) zip(fooArray, barArray, bazArray).map((arr) => arr[0] + arr[1] + arr[2]);
- ubertaco 10y agoIt's really nice for when you have to do operations where you want a "tuple" in Javascript. Consider the case of finding all companies along with their hires from the last week, but only if the company has a hire from the last week: companies.map(c => [c, employeeStorage.getEmployees(c)]) .map(([company, employees]) => [company, employees.filter(e => e.hireDate > aWeekAgo)]) .filter(([company, employees]) => employees.length > 0)
- my123 10y agoOn the web browser side, I don't recommend using ES6 yet, without any kind of fallback. Internet Explorer 11 is still used, as are devices on older iOS versions. (without counting people using the default browser on pre-Lollipop Android)
- jaquers 10y agoIndeed. Are there any 'good' strategies for this (loading ES6 for supported browsers)? I imagine you'd have to do UA sniffing on the server side, and I suppose it's kind of a moot point if you're using React/JSX.
- Tankenstein 10y agoThere's no need unless you need runtime-only concepts, like new string methods. Use https://babeljs.io/ https://babeljs.io/ to turn nice es6 into es5. (I imagine you already know this, if you're using react/jsx)
- megous 10y agoJust try to eval a sample of ES6 syntax you use, and if it throws error, load ES5 code. You'd need to feature check all the features that you use, to cover the browser versions with incomplete ES6 support.
- hzoo 10y agoWorking on https://github.com/babel/babel-preset-env https://github.com/babel/babel-preset-env right now which should help with this
- Tankenstein 10y agoFor anyone who wants to use ES6 in production, https://babeljs.io/ https://babeljs.io/ is amazing.
- treve 10y agoIt's both amazing, and 600MB worth of dependencies. We use it for server-side code. It's high quality, and we only have a few issues with it, but I can't wait to be able to ditch is (pretty much when async/await lands in a stable node).
- bpicolo 10y ago> Because even though the if-block is not executed, the line 4 still redefines var x as undefined. This is because of hoisting. Not quite right as described.
- fenomas 10y agoYeah, that example should be changed - the "before" version isn't code anyone would write on purpose, and which JSHint/JSLint would flag as a bug.
- ciju 10y agoProbably add pointers to where the images were taken from. Ex: https://kangax.github.io/compat-table/es6/ https://kangax.github.io/compat-table/es6/
- Mchl 10y agoWhat's interesting is that the author apparently has a QUERTY keyboard layout...
- adriansky 10y agoha, I do
- z3t4 10y agovar'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.
- qaq 10y agoYou might as well use babel and then you can use async/await which makes code way more readable.
- mooveprince 10y agoIf someone wants to dig more on ES5 vs ES6 , check this presentation (use side arrow for navigation) http://coenraets.org/present/es6/#1 http://coenraets.org/present/es6/#1
- Roboprog 10y agoThis one is a useful reference, as well: http://es6-features.org/#Constants http://es6-features.org/#Constants
- lacostenycoder 10y agoHelpful article. Small typo on section 3.5. shouldn't 'construtor' == 'constructor' ?
- bluepnume 10y agoJavascript's weak comparison operators aren't that bad.
- tychuz 10y agoemojis - just because you can, doesn't mean you should...
- jnasc 10y agoWhat about import from? (modules)
- ggregoire 10y agoIn my opinion it's the biggest improvement from ES6. However, you still need Babel to use this feature, even in Chrome/Firefox. For those interested: import: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... export: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- adriansky 10y agoYou can't use it in the browser yet. That's why it has been excluded. You need typescript or babel to use it
- goatlover 10y agoSome of these features are really nice, but JS is on a path to become as complex as C++.
- warlox 10y agoThat's the natural result of being unable to remove any features to maintain legacy compatibility.
- Klathmon 10y agoWell unlike the majority of C++ warts, JS is doing a very good job of "hiding" it's ugly parts with things like "use strict" Things like `with` and a bunch of ugly parts were hidden with the introduction of "use strict", and i'm more than confident it will happen again in the future with something similar that can let you "opt in" to an even stricter JS that leaves behind the "current" warts of javascript in favor of much better ways.
- ggregoire 10y agoI'm surprised by the state of const/let nowadays. The well-known good practice: use const by default; use let when it's needed. At the release of ES6, it was the way to go. But everyday I notice libraries—and some really famous— that use let everywhere in their docs, or some really influent developers from Google or Facebook who share samples of code on Twitter using let when it's not needed [1]. I don't know why. Seems like most people now think that const is for declaring constants (in the traditional meaning, like const API_URL) when it's just the normal way to declare variables that don't need to be reassigned (so basically most variables). Dan Abramov said: "some people say const is ugly" [2]. Well, if it's a matter of appearance... [1] https://twitter.com/addyosmani/status/789126892402204673 https://twitter.com/addyosmani/status/789126892402204673 [2] https://twitter.com/dan_abramov/status/783708858803978240 https://twitter.com/dan_abramov/status/783708858803978240
- djur 10y agoIt should have been "let"/"let mut", not "const"/"let" (or some other scheme that makes immutable bindings terser). I recall people warning of this outcome at the time of standardization.
- pmoleri 10y agoI resisted const for like 10 minutes. You get used to it really quickly and then when you see a 'let' in your code you just know something is happening with that variable afterwards. When I have to go back to programming in a language without const declarations it feels bad.
- VeejayRampay 10y agoI have a question: What does `for element of arr` buy me over `arr.forEach(element => ...)` I don't find the for...of syntax particularly appealing or useful, but I might be missing something. Is it a matter of preference?
- duckfruit 10y agofor...of is more flexible. While forEach is a method on Array.prototype, for...of is a consistent syntax that can be used in more places. For instance, iterables: function *myIterable (v) { while(--v) yield v } let launchCountdown = myIterable(60) for (let i of launchCountdown) console.log(`t minus ${i} seconds`) So in effect arrays can be thought of as iterables in ES6. So IMHO it allows for more consistent behavior with the way iterators in other languages like Java and C++
- VeejayRampay 10y agoAh, I see, good point. And how would you handle cases (that I end up using quite often) such as : arr.map(...).filter(...).forEach(...) which allows me to iterate over the filtered result? One would assign the result of filter to a variable and call for...of on that? EDIT: Also, I never saw any mention of for...of working for object literals (à la `for (let [key, value] of obj`), I suppose that's out of scope, correct?
- bzbarsky 10y ago> arr.map(...).filter(...).forEach(...) which allows me to iterate over the filtered result? Just like that. It would be pretty nice to have generic filter/map that can work on arbitrary iterables, but we don't have that right now. :( > Also, I never saw any mention of for...of working for object literals (à la `for (let [key, value] of obj`) for (let [key, value] of Object.entries(obj)) { } it's not in "ES6"/ES2015, but it's in ES2017 drafts and is implemented in Chrome and Firefox but so far not elsewhere. The need to do Object.entries instead of obj.entries() is annoying, but needed in case your literal has a property named "entries"... There's also Object.keys() and Object.values(), of course.
- zelias 10y agoWhile I'm a big believer in most of the ES6 changes (arrow functions! let/const! classes! generators!), I am not a big fan of many of the new destructuring features. They can actually make your code less approachable if you don't already know what's going on.
- fryan 10y agoI agree that object destructuring makes the code far less readable. Array destructuring however is easy for anyone to grok.
- ggregoire 10y agoIt depends I think. For example, in my opinion const Header = ({ children, iconName, iconSize, title }) => { ... }; is more readable than const Header = (props) => { ... };
- fryan 10y agoconst Header = ({ children, iconName, iconSize, title }) => { ... }; Once you get used to the destructuring parameter idiom, sure. It also conveys more information. But that statement is overloaded in that it makes use of implicit object shortcuts which has a bit of a learning curve for longtime ES5 users. const Header = ({ children: children, iconName: iconName, iconSize: iconSize, title: title }) => { ... }; When object destructuring is nested it can be confusing and more verbose.
- lhnz 10y agofunction thisIsBad ({ someKey: renamedSomeKey, someOtherKey: renamedSomeOtherKey = 'otherDefaultValue', meta: { innerMetaKey = 'someInnerMetaKeyValue', otherInnerMetaKey, ...remainingMeta } } = { someKey: 'defaultValue', someOtherKey: SOME_CONSTANT, meta: {} }) { // ... return { someKey: renamedSomeKey } } My favourite messed up part of the syntax is the way the `:` character is used to describe either the default value of a property or a way of renaming the name of a property internally (depending on whether it is to the left or right of an `=`). And also, the way you can destructure the inside of an object, and automatically lose the original value. For example `meta` is not accessible within the function defined above. This is syntax which can simplify your code if you apply it carefully, but will ruin your code if you over-use it.
- pwython 10y agoCan anyone recommend books or online courses that teach ES6 for someone just starting out with JS?
- waylandsmithers 10y agoThe book from the "You Don't Know JS" series is very thorough: https://github.com/getify/You-Dont-Know-JS/tree/master/es6%20%26%20beyond https://github.com/getify/You-Dont-Know-JS/tree/master/es6%2...
- Scarbutt 10y agoLearn ES5 first, you will need it(majority of JS code out there), ES6 is just sugar over ES5, so knowing ES5 will make it easier to understand ES6.
- albertTJames 10y ago[a, b] = [b, a]; Great !
- Roboprog 10y agoUgh. All this "make Javascript like Java" stuff needs to stop. Cool stuff: Tail call elimination. Arrow functions. Assignment spread for multiple return values and "rest" / default parameters. Proxying (combined with computed get/set on properties) for easy decoration. Classes and let: meh.
- Meegul 10y agoLet is a game changer imo. In the world of tens of dependencies, knowing that your variables are scope restricted reduces your cognitive load. It's one less thing that can go wrong. I agree with you on classes, but that's probably more because I've never been a big fan of OO in practice. It doesn't really seem to have seen much use in the greater js ecosystem though, unlike let/const.
- SHOwnsYou 10y agoHonest question here --- What is the difference between let and global variables? There are hundreds of articles written about the doom associated with PHP globals, but let appears to be universally lauded. I must be missing something, but I can't tell where.
- Meegul 10y agoIt's spelled out pretty well in the article. But if you want another example, consider these two code blocks: var foo; var bar; { let foo = "hello"; var bar = "world"; } console.log(foo); console.log(bar); This produces: undefined world The reason being that the `let` statement restricted that variable to the block it was in (defined by the { and }). `var` declares the variable globally, allowing it to be accessed outside of the {}. We prefer now to use `let` and `const` over `var` because it doesn't pollute the global namespace. With the asynchronous nature of Javascript, it's theoretically possible for you to declare a variable with `var`, assign it a value, then immediately use that value and find that it's different than what you expected because of another function using the same variable name. This isn't possible with `let`.
- AgentME 10y agoThe most interesting part about template strings was skipped over: tagged template literals. You can prefix a template string with a function which will get called with the list of string parts and the values passed in ${...} parts, and then it's up to the function to choose how to join the values up into the resulting string (or hell, you could make it return something besides a string if you want). The function can even access the raw version of the string containing any backslash escapes in it as-is. The default `String.raw` function is handy if you're writing something like an SQL query with a few \ characters that need to be in the final query. Both of these strings are the same here: const a = "SELECT id FROM foo WHERE name CONTAINS r'\\n'"; const b = String.raw `SELECT id FROM foo WHERE name CONTAINS r'\n'`; You could even assign `String.raw` to a variable first, and then make strings look like raw string literals of other languages: const r = String.raw; const s = r`SELECT id FROM foo WHERE name CONTAINS r'\n'`; Another good use of template strings is automatic HTML encoding (with a small module of mine on npm): https://www.npmjs.com/package/auto-html https://www.npmjs.com/package/auto-html
- CGamesPlay 10y agoHow does this work? I can't find any examples and I also don't really understand what mechanism makes your npm module work.
- AgentME 10y agoA tagged template literal is just a special ES6 syntax for calling a function with a specific set of arguments. You could pass a function which returns all of the arguments as an array to see what's passed in. Try the following in the console of a modern browser: function log(...args) { return args; } log `abc ${'blah'} fooo\n ${12+3} bar`; Or you could even shorten the above down to this: ((...args)=>args) `abc ${'blah'} fooo\n ${12+3} bar`; The expression will evaluate to this: [["abc ", " fooo\n ", " bar"], "blah", 15] The first argument is an array of the parts of the literal text, and then the rest of the arguments are the values that were passed in. Additionally, the first argument (the array of string parts) has the `raw` property set to point to an array of string parts with the backslash escapes uninterpreted. Here's an example re-implementation of `String.raw`: function raw({raw}, ...values) { const parts = new Array(raw.length*2-1); parts[0] = raw[0]; for (let i=0, len=values.length; i<len; i++) { parts[2*i+1] = values[i]; parts[2*i+2] = raw[i+1]; } return parts.join(''); }
- kin 10y agoAppreciate the article, but this is relatively dated information. While I can see that many enjoyed the article, many have also been working in ES6 for over a year now. If you're ready to join, I highly suggest everyone make their way to https://babeljs.io/ https://babeljs.io/ and everything it has to offer resource-wise or tooling-wise.
- drivingmenuts 10y agoCan someone smarter than me (not a high bar) explain why they didn't just fix var, rather than introducing let?
- ChemicalWarfare 10y agobackward compatibility would be one reason.
- stigi 10y agoIf you want to learn ES6 I highly recommend the Tower of Babel interactive tutorial: https://github.com/yosuke-furukawa/tower-of-babel https://github.com/yosuke-furukawa/tower-of-babel
- iamleppert 10y ago"best practices": "use class instead of manipulating prototype directly" Who comes up with these "rules"? This is not a hard and fast rule. Manipulating the prototype of an object is not "dangerous". I'm sick and tired of some loud mouth saying something is dangerous without explaining why. WHY? Why it it dangerous? Don't talk at me. Provide me a sound reason and case to justify what you say. Talk is cheap. It makes me not trust anything else in this article when someone is flippant.
- CGamesPlay 10y agohttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... This has some warnings at the top as to why.
- hajile 10y ago__proto__ !== prototype One points to the parent of an object and the other points to the object's prototype (which in turn has it's own `__proto__ property). Accessing `prototype` is just fine, but if you want to access `__proto__` then you should use `Object.create()` instead.
- smagch 10y agoI always turn to an ES6 article on babeljs.io when I check out ES6 features. https://babeljs.io/docs/learn-es2015/ https://babeljs.io/docs/learn-es2015/ One of the features I like is default parameters. I'd like to add a usage that isn't mentioned in the article. It's really handy to pass optional parameters since default parameters can be nested. class Hoge { foo({active=true, collapsed=false, silent=false}={}) { } } let hoge = new Hoge(); hoge.foo({collapsed: true});
- pluma 10y agoI gave a more complete overview of ES6 (and ES2016 and so on) features at a user group last month. Slides: http://files.meetup.com/11421852/WhatsNewInJavaScript.pdf http://files.meetup.com/11421852/WhatsNewInJavaScript.pdf The slides are mostly code examples and I tried to go for completeness rather than detail, so there are some mentions you don't normally see in these overviews (e.g. the article doesn't mention proxies).
- sametmax 10y ago"you can start using it right now" if you don't care about IE8, IE9, IE10, and many mobile browsers and are willing to ignore 20% of your customers. e.g: http://caniuse.com/#search=let http://caniuse.com/#search=let const does not have block scope in those browsers either, but will work, adding to your debugging confusion. template literals and multiline string has no IE support at all (you need edge: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...) so you can forget most most enterprise clients Similar things are missing for most features from the article. I wonder how many JS dev have to answer to actual customers because none of my clients in the last decade who would have accepted to have a possible failure on 1/5 of their visitors. Are they all bloggers or working in hype start ups ?
- ggregoire 10y agoWe use Babel to compile ES6/ES7/ES8 to ES5. https://babeljs.io https://babeljs.io
- sametmax 10y agoIt's not what the article is about. The article is obviously talking about native ES6 features, otherwise it would advertise es7 features as well and advise to use transpilers.
- Klathmon 10y agoThere's no reason why someone using babel needs to use ES2016+ features, they can stick to ES2015 just like this article. I'd actually recommend avoiding the still-not-standardized features as you'll have less/no change when it lands in browsers.
- Can_Not 10y agoI looked at the prospects of starting a React, Aurelia, or VueJS projects a few days ago and a year ago. Anyone who wants to wait to upgrade to these new things will be really happy to see how much nicer these things get every year. Tooling and starter kits just keep getting better, and best of all, you could probably wait a long time to switch and miss out on nothing important.
- hzoo 10y agoFor those using Babel already or want to use ES6+ on a set of supported browsers: we have started work on https://github.com/babel/babel-preset-env https://github.com/babel/babel-preset-env. Would appreciate more testing! It allows passing in a set of supported browsers and transpiling what is required using the lowest common denominator env (uses https://github.com/kangax/compat-table https://github.com/kangax/compat-table for data). // .babelrc with preset options { "presets": [ ["env", { "targets": { "chrome": 52, "ie": 11, "browsers": ["last 2 versions", "safari 7"] } }] ] } If you have questions, ask below (or make an issue)
- epmatsw 10y agoWow, this is really excellent. Definitely will give this a shot!
- caub 10y agouhhh edge still hasn't destructuring
- irascible 10y agoPlease stop trying to fuck up javascript.
- viebel 10y agoGreat article! It would be fantastic to make all the code snippet interactive with the klipse plugin. http://blog.klipse.tech/javascript/2016/06/20/blog-javascript.html http://blog.klipse.tech/javascript/2016/06/20/blog-javascrip...
- firethief 10y agoEqually spacing the points on the timeline may make for an aesthetic image, but it fails to illustrate the author's point. "As you can see, there are gaps of 10 and 6 years between the ES3, ES5, and ES6. The new model is to make small incremental changes every year." No, we can't see. In that pretty graphic, ES5->ES6 is exactly the same distance as ES6->ES7.