Can't use "let" keyword in Safari Javascript? - javascript

I don't understand the best way to use "let" keyword...
In IE11 and Chrome45 I can use it fine
In Safari8.0.4, like in older versions of Chrome, it gives the error "unexpected use of reserved word 'let'"
In Firefox the let keyword only works inside <script type="application/javascript;version=1.7"/>, but this script type isn't even recognized as Javascript in IE11, Chrome45, Safari8.
Here's a JSFiddle that shows it in action: https://jsfiddle.net/p6cgtyg6/1/
So -- I don't mind requiring users to use modern versions of their browsers.
And I don't mind excluding Safari if there honestly is no version of Safari that supports this keyword. (Is that really true? Why does everyone spend all their time griping about IE when Safari seems so much worse in ES6 terms? Have I missed something?).
But how should I allow "let" to work in Firefox while not preventing Chrome/IE? (I haven't yet found links from people griping about how Firefox script tag behaves differently from Chrome, and I'd have expected more complaints, so I figure I must have missed something obvious...)

Concerning Safari 8, it's just not supported ; for that browser, I'd recommend using Babel.
If you have the gut feeling that this bug won't be fixed anytime soon* then you could have a script that detect Firefox which would then inject your script(s) with the appropriate value for the type attribute.
As a side note, I would advise not to use let blocks—unless you wanna use this transpiler—nor let expressions which will be dropped.
* fixed in Firefox 44

let is a part of ECMAScript 6 specification, and ECMAScript 6 itself is in 'draft' status. Even in its incomplete form its features aren't supported fully by actual browser versions.
Since you want to dive into ES6 today for production, your best bet is to use ES6 to ES5 transpiler, most prominent ones are Babel and Traceur, which are available as both CLI and packages for the build system of your choice. There are online tools for Babel and Traceur to try them out. And Scratch JS extension for Chrome uses both Babel and Traceur and is excellent for developing and compiling ES6 scripts if the build system is not an option.
Here is up-to-date comparison table that embraces ES6 feature support in both browsers and ES6 compilers.
And here is a great collection of ES6-related tools.

See browser compatability of this ES6 keyword.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Browser_compatibility
Also see this SO post for ES6 feature detection.

Related

ES6 (ECMAScript 2015) support as of 2018

As a long time programmer just getting into JavaScript programming, I have the following questions that are still unclear despite having read many articles.
Looking at the ES6 (ECMAScript 2015) support by browsers, I can see that the supporting level is much less than that of Node.js, so the question is,
If both Node.js and browsers are using the modern V8 engine, why supporting level are so different?
Looking at the ES6 support in Node.js, I can see really really few ES6 features are unsupported now. However, what exactly does the supported means in the chart? I.e.,
Does it means even I write using the support ES6 features, I still need to use the Babel compiler to compile ES6 code to ES5 for Node.js to use it?
For TypeScript ES6-style JavaScript code that runs for Node.js, they are still need to be transpiled into an ES5 compatible form, despite that Node.js almost cover all ES6 featues, right? I.e.,
for the following code,
class Animal {
constructor(public name) { }
move(meters) {
console.log(this.name + " moved " + meters + "m.");
}
}
class Snake extends Animal {
move() {
console.log("Slithering...");
super.move(5);
}
}
class Horse extends Animal {
move() {
console.log("Galloping...");
super.move(45);
}
var sam = new Snake("Sammy the Python")
var tom: Animal = new Horse("Tommy the Palomino")
sam.move()
tom.move(34)
Does it need to be transpiled into an ES5 compatible form to runs with Node.js or not?
Finally, any online site that I can try playing with TypeScript/ES6 code like above?
I copy it to my chrome console, and got an error that I don't understand - Unexpected strict mode reserved word, and
I tried it on http://www.typescriptlang.org/play/index.html, but the console output is not working there.
Please help. thx.
Looking at the ES6 (ECMAScript 2015) support by browsers, I can see that the supporting level is much less than that of Node.js, so the question is,
Many different browsers and many different Javascript engines in them, each with their own level of ES6 support. The latest version of node.js is generally pretty up-to-date on what the V8 engine supports. Many browsers have longer release cycles and may not be as current, but each is different and has their own release strategy and level of ES6 support.
If both Node.js and browsers are using the modern V8 engine, why supporting level are so different?
If you compare the latest release of node.js with the latest release of Chrome on Windows, you won't see much difference in support. The ES6 support chart you're looking at seems old to me. For example, Chrome has had support for the Set object for a long time, but your chart says false.
Looking at the ES6 support in Node.js, I can see really really few ES6 features are unsupported now. However, what exactly does the supported means in the chart? I.e.,
Supported means you can use the feature directly without a transpiler, but how accurate that is depends upon the source of the document claiming it. Some documents do extensive testing of all the various edge cases of a given feature.
Others just look for general implementation. So if for example, you're looking at support for the Set object and it says "supported", then that is suppose to mean that you can just write plain Javascript that uses the Set object and it will just work. How accurate that document is depends upon the source of their data and the thoroughness of their testing.
Does it means even I write using the support ES6 features, I still need to use the Babel compiler to compile ES6 code to ES5 for Node.js to use it?
No. In a Javascript engine that supports a given feature in ES6, you can write ES6 code for that feature and directly run it in that Javascript engine. No transpiling is needed.
For TypeScript ES6-style JavaScript code that runs for Node.js, they are still need to be transpiled into an ES5 compatible form, despite that Node.js almost cover all ES6 featues, right? I.e.,
The class definitions you show are plain ES6 code. Those will work just fine as is in an ES6 capable Javascript engine.
If you write Typescript code, then you will have to transpile the TypeScript to Javascript because no Javascript engine (I know of) supports TypeScript directly. When transpiling form TypeScript to Javascript, you can usually specify whether you want the transpiler to generate ES5 compatible code (which will run in an ES5 engine or an ES6 engine) or ES6 compatible code (which will only run in an ES6 engine) depending upon what your target environment is capable of.
Does it need to be transpiled into an ES5 compatible form to runs with Node.js or not?
Your particular code appears to contain at least one TypeScript style variable declaration which would need to be transpiled. The rest looks like plain ES6 Javascript which should work in any ES6 engine without transpiling.
When I remove the TypeScript, fix some syntax errors in your code and implement the Animal constructor properly, then this code works fine in node.js v8.8.1 (which is what I currently have installed) and in Chrome 63.0.3239.132, Edge 41.16299.15.0 and Firefox 57.0.4 all on Windows 10:
// Generic ES6 code
class Animal {
constructor(name) {
this.name = name;
}
move(meters) {
console.log(this.name + " moved " + meters + "m.");
}
}
class Snake extends Animal {
move() {
console.log("Slithering...");
super.move(5);
}
}
class Horse extends Animal {
move() {
console.log("Galloping...");
super.move(45);
}
}
var sam = new Snake("Sammy the Python");
var tom = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
You can run this snippet yourself in any browser you desired to see the results (assuming the browser is modern enough to support a stack overflow snipppet). It works in all the current versions of browsers I have except IE 11.192.16299.0 (no surprise that IE doesn't support ES6).
I copy it to my chrome console, and got an error that I don't understand - Unexpected strict mode reserved word,
This happened to me when I tried to run your code in node.js until I removed the TypeScript from it so that it was just plain ES6. I think this particular error is caused by the public in this line:
constructor(public name) { }
since that is not part of the ES6 specification (it's apparently part of TypeScript).
It seems that there's one question you're dying to ask, but haven't exactly articulated is: "How do you know whether you have to transpile or not?".
The answer is that you have to understand the cross between the target environments you wish to run in and the newest features you plan to use. If you are writing server-side code that will only run in node.js, then it's a lot simpler. Examine a comprehensive table such as http://node.green/, study what it says for the node.js version you plan to use and the feature in question. If it indicates you should be able to use that feature, then write your code using that feature, write a test case for it and verify that both the code you wrote and the feature you are using both work. Add that to your body of knowledge about what you can and can't use in that version of node.js. You can then assume all future versions of node.js will also support that feature.
If you're writing code to run in a browser, life is much more complicated. If you plan to support a lot of browsers and really don't want to worry about ES6 support at all, then just transpile to an ES5 target and go about your business.
If you want to use non-transpiled code, then you have a lot of testing to do in a lot of browsers. You have to first specify exactly which versions of which browsers you are going to support and then you have to write your code and test cases and you have to test in every browser you plan to support. There really is no shortcut. When you find things that don't work, you'll have to either look for polyfills or work-arounds or stop using that ES6 feature.
Test the code in the environments that the code is going to be used in. Use the available means to implement the specific standard or specification within the environment that you are using the code at. Or try to create an approach yourself to resolve an issue that you encounter during development of your code while noting the progressions and persistent issue for others to be able to possibly address and resolve the issue, bug or requirement from their own perspective.
Simply due to the fact the a document states that the browser has implemented a specification or standard does not mean that the implementation is consistent with the specification, or implemented at all. The only way to verify whether a browser implements a standard is to test with code yourself. File issues and attempt to fix bugs yourself.
Browsers use different engines including Gecko, WebKit, not V8 alone; and can change over time in both name and implementations of specifications; see Monitor and potentially deprecate support for multitrack SourceBuffer support of 'sequence' AppendMode; How to use "segments" mode at SourceBuffer of MediaSource to render same result at Chomium, Chorme and Firefox?. There are many browsers. For example, Lynx does not use V8.
See web platform tests
The web-platform-tests Project is a W3C-coordinated attempt to build a
cross-browser testsuite for the Web-platform stack. Writing tests in a
way that allows them to be run in all browsers gives browser projects
confidence that they are shipping software that is compatible with
other implementations, and that later implementations will be
compatible with their implementations. This in turn gives Web
authors/developers confidence that they can actually rely on the Web
platform to deliver on the promise of working across browsers and
devices without needing extra layers of abstraction to paper over the
gaps left by specification editors and implementors.
For example, one test for Web Speech API, where volume property is specified as capable of being set, though was not able to detect a change of audio output for either Chromium or Firefox when setting the volume property of SpeechSynthesisUtterance to different values within the specified ranges.
Specifications are a totally different regime than actual browser implementations. Specifications or standards can be and are written well in advance of actual browser implementation, if implemented at all. You can use browserify, or write the code yourself to use NodeJS modules or other non-native code in the browser.

ES6 Proxy Polyfill for IE11

IE11 does not and will not implement ES2015 Proxy objects. Yet IE11's end of extended support is October 14, 2025.
Is there any way to polyfill Proxy objects for IE11? All other browsers support Proxy already.
If yes then we would all be able to use it in production today. If not then we'll have to wait almost a decade...
Edit: I'm asking specifically for IE11 as I know IE to usually have IE specific features that I'm often not aware of.
Edit2: I'm particularly interested in being able to implement a catch-all interceptor. Similar to __getattr__ in Python. It only has to work in IE11.
Best you can get is github: GoogleChrome/proxy-polyfill
According to Babel docs:
Due to the limitations of ES5, Proxies cannot be transpiled or polyfilled.
There's quite a concise answer for this question on Quora
Proxies require support on the engine level and it is not possible to polyfill Proxy.
Most major JS engines have yet to implement support. Check out the ECMAScript 6 compatibility table.
You may want to use Object.observe instead, possibly with polyfills for browsers other than Chrome, but even then the proposal has been withdrawn, and it has been announced it will be removed from Chrome in a future version.
I personally haven't tried the Object.observe solution but it might be a good place to start.
Good luck!
EDIT:
Thank you to Matt Jensen in the comments for pointing out there is infact a way to polyfill some parts of ES6 Proxy using this package: github.com/GoogleChrome/proxy-polyfill
AWESOME
Direct solution for polyfilling ES6 Proxy in environments without support this feature, of course is impossible - if storing some polyfill function info window.Proxy is meant. But if thinking this way, most modern features of ES6 can't be supported, because they will raise syntax error for old-version ECMAScript engine.
That's why you should use transpiler, which perform preceding wrapping ES6 code into specific constructions, and then evaluate transformed code on old engine. In current case, just use one Babel plugin: https://www.npmjs.com/package/babel-plugin-proxy
Of course, while using this solution, you should configure Webpack to segregate target bundles for different client agents / browsers, depending on it's feature set discovery. See details here: https://gist.github.com/newyankeecodeshop/79f3e1348a09583faf62ed55b58d09d9

es6 modules native support

I understand the ES6 modules specification, the question is about its support. AFAIK, there are no browsers that implement this natively (see Browser compatibility here). Got a couple of questions about this:
ES6 modules is an ES6 feature, obviously. When I look at kangax compatibility table, I don't see such row (for ES6 modules) at all, why is that? It's a ES6 feature afterall...
hence, the only way to use ES6 right now is to use a build tool, such as babel, browserify or any other aternative, right?
how are the modules gonna be fetched, when they're natively supported - as async AJAX calls from the browser?
ES6 modules is an ES6 feature, obviously. When I look at kangax compatibility table, I don't see such row (for ES6 modules) at all, why is that?
There's an issue being discussed on kangax's github.
the only way to use ES6 right now is to use a build tool, such as babel, browserify or any other aternative, right?
No. There is also a polyfill by Guy Bedford at http://github.com/ModuleLoader/browser-es-module-loader.
And there's already the preview release of Edge that implements it natively.
how are the modules gonna be fetched, when they're natively supported - as async AJAX calls from the browser?
Yes but not exactly: they will be fetched when the are used for the first time, by a call to an object (a function or a property) on the imported library.
Native modules are available in the following versions of browsers:
Safari 10.1
Chrome Canary 60 – behind the Experimental Web Platform
flag in chrome:flags.
Firefox 54 – behind the dom.moduleScripts.enabled setting in about:config.
Edge 15 – behind
the Experimental JavaScript Features setting in about:flags.
source

Browserify: IE8 Compatibility

I've seen it mentioned in a few places that Browserify isn't compatible with IE8 and below (here, here, and alluded to here).
I don't see anything official about this in the docs. It looks like it may be the use of Function.prototype.call() but I can't tell for sure.
Does anyone know for sure:
how far back IE is supported
what code (if any) is incompatible with IE8
any recommended workarounds for IE8 specifically
I use Browserify for my library http://github.com/pllee/luc to build all of the browser code. My tests pass on IE6 and I am using ES5 shim but I don't think that would make Browserify work (chicken and egg situation). Those links you show are quite old and I know Browserify has changed its implementation since then.
You can see on their official page that they do support IE7 and greater.

ES6 Template String testbed

I'm really interested in finding out about ES6 Template Strings and have been doing a little bit of reading on the feature.
However now that Chrome Canary does not support it (although maybe I'm wrong about that!) is there anywhere/anything I can use to try out this new functionality? Any browser beta around that does?
I've already enabled Experimental Javascript Features inside chrome://flags
It's only supported in Traceur at the moment.
You can play with it in their REPL.
es6fiddle.net doesn't seem to support it yet, but probably will soon.
Mozilla is working on it so expect to see it in nightly builds soon as well.
It's Supported in
Edge
Firefox
Chrome/Opera
Webkit
Missing in safari ;( though
cough safari is the new ie cough
source
Regarding template strings and support for ES6 features
I would also use traceur to play around with most ES6 features, but have a look at this ES6 compatibility table, it's invaluable when you want to find out which platforms/transpilers support which features.
For anyone else landing on this question, go and check out tagtree's videos onn ES6 features.
To see template strings, arrow syntax and desctructuring, have a look at this free tagtree tutorial screencast, no registration is required.

Categories