I'm toying with let in Node v0.10.12. Using the --harmony flag the following code produces a syntax error:
for (let i = 0; i < 2; i += 1) {
console.log('i', i);
}
SyntaxError: Illegal let declaration outside extended mode
However, if I also use the --use-strict flag, then the code runs as expected.
Why is a syntax error thrown when just using the --harmony flag? What is extended mode? What is the connection with strict mode?
It looks like "extended mode" was removed from the current development version of the harmony spec on February 27, 2012, but there's a description of what it was supposed to be in a few older ones (this one is from January 16, 2012):
10.1.2 Extended Code
Extended code is any code contained in an ECMAScript Program syntactic
unit that contains occurrences of lexical or syntactic productions
defined subsequent to the Fifth Edition of the ECMAScript
specification. Code is interpreted as extended code in the following
situations:
Global code is extended global code if it is contained in an ECMAScript Program syntactic unit that has been designated as an
extended Program unit in an implementation defined manner or if ???.
Eval code is extended eval code if the call to eval is a direct call (see 15.1.2.1.1) to the eval function that is contained in
extended mode code or if it begins with ???.
Function code that is part of a FunctionDeclaration, FunctionExpression, or accessor PropertyAssignment is extended function code if its FunctionDeclaration, FunctionExpression, or
PropertyAssignment is contained in extended mode code or if the function code begins with ???.
Function code that is supplied as the last argument to the built-in Function constructor is strict function code if the last argument is a
String that when processed as a FunctionBody begins with ???.
The term “strict code” is used to designate both actual strict mode
code and extended code while the term “extended code” only designates
actual extended code. The term “base code” is used to designate code
that is not extended code.
As for the connection with strict mode, that seems to be specific to V8's (experimental) implementation. Here's what the changelog for revision 10062, which introduced the --harmony flag, says:
This CL introduces a third mode next to the non-strict (henceforth
called 'classic mode') and 'strict mode' which is called 'extended
mode' as in the current ES.next specification drafts. The extended
mode is based on the 'strict mode' and adds new functionality to it.
This means that most of the semantics of these two modes coincide.
The 'extended mode' is entered instead of the 'strict mode' during
parsing when using the 'strict mode' directive "use strict" and when
the the harmony-scoping flag is active. This should be changed once it
is fully specified how the 'extended mode' is entered.
How to obtain harmony in your node.js
The --harmony flag enables ES Harmony features. it seems that --harmony enables new ECMA features in the language, based on the v8, proxies, weak maps, sets, maps, typeof semantics, and block scoping are available when this flag is being used and these are extended features and after extending these features you can use for example let (for block scoping) with strict mode enabled only because it's based on it, otherwise it will throw
SyntaxError: Illegal let declaration outside extended mode.
Extended Mode : When you are using new ECMA features (ECMAScript 5), you are in the extended mode of the language and in this mode ECMAScript’s new features (extended code) and syntax could be used only in strict mode
Concept of “extended code” that means code that may use new Es.next
syntax.
Harmony :
"Harmony" is the name of the major upgrade to JavaScript due to arrive by the end of 2013. In 2008, after much controversy, the ECMA Technical Committee 39, that had been charged with creating the next generation of JavaScript, agreed to work together on a "Harmony" update to JavaScript and it has been in development since then.
A number of the proposed features of Harmony are supported by Google's implementation. These include block scoped bindings and the addition of the let keyword, efficient maps and sets to remove the need to "abuse objects as dictionaries", weak maps for garbage collectable key/value tables and proxies which can simulate any JavaScript object or function to enable customisation.
Some good reads here and hear. Also from Chromium Blog.
Also from Paul Irish :
François Beaufort (originally shared): A new flag named Enable
Experimental JavaScript appeared in the chrome://flags page of the
last Chromium build. This flag enables web pages to use experimental
JavaScript features.
To use extended mode/harmony features now in Chrome we have to enable this and we can enable this by navigating to chrome://flags and can toggle (enable/disable) on "Experimental JavaScript features".
Related
I'm learning tricky parts of Javascript, and without judging, trying to understand how the language works, but as a developer with Java and Python background(even with Typescript) I'm struggling.
I do understand the string primitives are immutable but why this code doesn't throw an error, doesn't it make the language very error-prone?
const str = "hello";
str[0] = 1;
console.log(str) // "hello"
JavaScript was created to be a companion scripting language to Java with a lower barrier to entry and with the then-fashionable Web Philosophy of "be forgiving of imprecise input" (cf HTML vs. XML).
So JavaScript was the product of a 1990s design philosophy that has dated poorly (hindsight!); even so, JavaScript has stood the test of time because the bones of the language were very good (compare and contrast with its competitor at the time, VBScript!). Interestingly, this was not widely understood until about 2005, leading to widespread derision that continues to this day.
Result? There are plenty of silent footguns in sloppy mode, which is an artefact of JavaScript's history; but this cannot be undone now ("don't break the Web!")
You cannot use the square bracket syntax to modify code units within a string. Whether the variable is declared with const or let is immaterial here.
In non-strict mode this fails silently (oops!): but no-one uses non-strict mode for production-facing code. ES5 (2009) introduced pragma-based opt-in strict mode that makes this an error.
ES2015 introduced modules and classes, within which all code is in strict mode (although there are a couple of unusual tricks you can do to break out of it in exceptional cases).
(() => {
'use strict';
let str = 'hello';
str[0] = 1;
console.log('foo');
})();
Is Node.js supporting => function keyword alias already? If yes, starting from which version? How to enable this language extension?
(function() { console.log('it works!') })()
Becomes
(() => { console.log('it works!') })()
In short: yes, arrow functions are reasonably well supported in Node.js since version 4.4.5.
Completely correct support starts with version 6. Initial support was introduced as far as v0.12 but is was very incomplete and disabled by default until v4.0 when it got better. See Node's ES6 compatibility table for details: http://node.green/#ES2015-functions-arrow-functions.
The syntax you're referring to is "arrow function" syntax. It is a feature of ECMAScript 6, also known as "Harmony". The ES6 standard is now finalized, but engines are still implementing its new features.
The V8 now has arrow function support. Node runs on the V8 engine, but it can take some time for Node to incorporate the latest version into its code base.
Whenever it is added, it might possibly be enabled only via a --harmony command-line flag.
You can follow this issue: https://code.google.com/p/v8/issues/detail?id=2700
Currently (as 02.05.2014) arrow functions have been implemented and waiting until this functionality will be landed in v8: https://codereview.chromium.org/160073006/
After then we'll need to wait, until v8 version with arrow function would be integrated into Node.JS. You can follow Node.JS changelog there: https://github.com/joyent/node/blob/master/ChangeLog (search for "v8: upgrade to ....")
kangax's compatibility tables can keep you up-to-date with what is currently available in Node.
Experimental features can be enabled using the instructions on this page:
All shipping features are turned on by default on Node.js
Staged feature require a runtime flag: --es_staging (or its synonym, --harmony)
In progress features can be activated individually by their respective harmony flag (e.g. --harmony_destructuring) but this is highly discouraged
In ESLint 1, I can use the ecmaFeatures option to disable or enable certain language features. E.g.
ecmaFeatures:
defaultParams: false
Above config disables defaultParams.
This is very useful because in runtime like Node, not all features are available, and I don't want to use a transpiler.
But in ESLint 2, that was removed. You only got ecmaVersion, which doesn't alerting on usage of ES2015 features at all even if you give it a ecmaVersion of 5. I guess this make sense since the JavaScript interpreter will complain about the usage of unsupported syntax at interpretation time, but what about developing for browsers have different level of ES2015 support? Syntax that works for Chrome won't work for IE9.
Is there any way to lint the usage of language features, e.g. disable destructuring?
no-restricted-syntax rule disallows specific syntax. This "syntax" is meaning the types of AST nodes. The spec of AST is here: https://github.com/estree/estree
eslint-plugin-node's no-unsupported-features rule disallows unsupported ECMA features by specific Node's version. I don't know whether a similar rule for browsers exists or not.
Is there any support for static typing in ECMAScript 6? How about ECMAScript 7?
No.
But on the ECMA-Script Wikipage there is a paragraph about changes in ECMA-Script 7:
The Seventh Edition is in a very early stage of development, but is intended to continue the themes of language reform, code isolation, control of effects and library/tool enabling from ES6. New features proposed include promises/concurrency, number and math enhancements, guards and trademarks (an alternative to static typing), operator overloading, value types (first-class number-like objects), new record structures (records, tuples and typed arrays), pattern matching, and traits.
Which may interest you.
Though this isn't part of the ES6 spec, Closure Compiler enforces JSDoc argument type annotations in JavaScript code when using its Advanced compilation level. Type annotations are specified using comments so they're ignored in development, but when you build your app for a production release a type mismatch will result in a compiler warning or, optionally, a compiler error.
An example of an enforced JSDoc type annotation:
/**
* #param {string} stringValue
* #return {number}
*/
function toInt(stringValue) {
return parseInt(stringValue, 10);
}
var val = toInt("10"); // Good
var val = toInt(false); // NaN in development, but throws an error (optional)
// or prints a warning (default) at build time
As an added bonus, JSDoc can build API documentation using this same syntax. So it's also handy if you document your code.
But a warning: for Closure Compiler to do its advanced optimization magic, every engineer on your project has to follow certain strict coding conventions. The compiler cannot enforce types unless it can reliably figure out what your code is doing, and that means giving up some of JavaScript's dynamic and wishy-washy syntax. If you don't follow them, errors can creep into your app and they can be very hard to diagnose after the fact. Most popular JavaScript frameworks and libraries do not follow them, though you can sometimes work around that using Compiler's externs feature. (jQuery is supported using externs, for example.)
So if you do use it, make sure you test your app thoroughly. I personally wouldn't even consider using this feature on a web app unless it has a Jenkins build bot and near-100% automated test coverage that can be run against your code after it's been optimized. That's a lot of work and is not for everyone; it took me months to get one of my projects up to that level. But personally, I think it's well worth the effort.
For more information, check out Advanced Compilation and Externs and Annotating JavaScript for the Closure Compiler.
No, there is no support for static typing in either ECMAScript 6 (ES2015).
As for ECMAScript 7 (ES2016), there is no proposal at any of stages 1, 2, 3, 4 or stage 0 for static typing.
I've seen a few proposals/ideas for static typing appear on the es-discuss mailing list, but none of these have actually been proposed for ES7 (ES2016).
If you want static typing right now, you're probably best looking into TypeScript or Flow.
Althought it's not pure ES6, Google's AtScript extending ES6 with type annotations and compiles into valid ES6 code once the compiler gets public: AtScript primer
As an option you can take a look at EsLint plugin https://github.com/yarax/typelint
It's not static check, but optional. The benefit of TypeLint is using already existing app data to build and use types automatically, unlike for example TypeScript or Flow, where you have to describe complex types by yourself.
I was trying this JavaScript piece of code:
class User(name) {
this.name = name;
}
var class = new User("Kimo");
The above was used as is in a JavaScript book, and I was simply playing with it.
firefox 6.0.2 (from the console) refused the 'class' keyword as a variable name (complained about a syntax error), while chrome 13.0.782.220m (from the developer tool) didn't complain at all.
It makes me think, which one is right? Since the notion of a class in JavaScript doesn't exist or it is different than other OOP languages. On the other hand, it might be wiser to prevent developers from using it.
I would like to know why this different approaches between firefox and chrome (I know they use different engines).
Thanks
First of all you can`t create a class in Javascript like this. Either create an object:
var User = {...};
or a constructor function:
function User() {...}
class is reserved word from about.com (some not listed in ECMA 262, but present in JScript) and MDC - reserved for future use. It is true that JavaScript has no classes for the moment. But the word is reserved in the sense that some day it can have such.
Mozilla is more strict about the rules than other browsers and gives a syntax error.
In addition :
JavaScript is not purely Object Oriented Programming language ( OOP ) it is Prototype-based Programming language.
On the other hand, it might be wiser to prevent developers from using it.
As JavaScript is interpreted by the browser, I don`t think the usage of reserved words can be prohibited. In the compiled code you have the compiler to disagree with you about such things, before the product is ready to use.
One other thing - you can write JavaScript code on editor with no capabilities to tell you, that your code has errors, or that you use reserved words for variables.
An error is correct behavior. Class is a restricted keyword in ECMAScript.
Firefox didnt implement Class support yet, if you check ecma6 browser support aka javascript(its a new realease that will have more feactures such as class :D), you will see that Class for mozilla isnt possible, lets hope soon will be available, ecma 6 is in beta stage, so it will be a while till all browsers support all the feactures