Why re-assigning a const variable is not a static error

Source: Internet
Author: User

The only difference between Const and let is that variables declared with const cannot be re-assigned (read-only variables), such as the following:

const FOO = 1//  typeerror:assignment to constant variable.
Note: This article does not use the term "constant" because I think the term is easy to be ambiguous: Some people call these immutable literals, such as numbers, strings, or constants, and some read-only properties as constants, such as Math.PI, and others that use const-declared variables in ES6 as constants. But generally speaking, this ambiguity is not a thing.

Unfortunately, this error is not a static error, but rather a runtime error. Static error, also known as parsing error (parsing error), because it is in the parsing of the wrong, in fact, the orthodox name in the specification is called Advance error (early error), and sometimes can see the corresponding late error, but in fact, the orthodox names in the norm only Runtime error. Given that the average person has absolutely no idea what early error is, this article uses the term static error.

The error is of course the sooner you know the better, so the static error must be better than the run-time error, such as the following code:

const FOO = 1/* Here are a lot of lines of code */If (this///  code executed only in the production environment )    / *     There are many lines    of code *    //// The person who wrote this line of code forgot that Foo was used Const declaration of  //  Development Environment Popup 1, online environment error, tragedy

If Foo = 2 is a static error, the code is directly in the development environment, even if Foo = 2 is not executed.

So why did ES6 not design this error as a static error? In fact, when the 11 const entered the ES6 draft, re-assigning the const variable in strict mode is a static error (the error type is SyntaxError), and in strict mode is also a run-time error (Error type TypeError), and Brendan Ei CH also implemented this rule in SpiderMonkey in the same year (Firefox 7). By the Year 12, the draft was changed to a static error that was not in strict mode, and another engineer, SpiderMonkey, Tom Schuster, realized the change on November 19, 2014 (Firefox 36).

Some students asked, why the same mistake to be reported in two stages? A run-time error with a static error should never be triggered. This is because in some cases the error is impossible or difficult to detect statically, such as:

const FOO = 1= "foo = 2"//  is destined to be a run-time error

In eval, the const variable is re-assigned, and this error is impossible to analyze statically, either from the specification or the implementation or logically, for example:

function f () {   ///  may be a static error? = 1f () 

When the engine resolves to foo = 2, it is not known that Foo will be a read-only variable at the back, and it is difficult for the engine to detect such errors statically. Perhaps the engine can be implemented, such as the previously parsed into the function of the implicit global variables of the information stored down, if later resolved to a const variable with the same name, and then error, can you? Who knows, anyway Firefox 36 was not able to detect such a mistake at the time, the Declaration and the assignment upside down can be:

Another case is that, although it is declared and re-assigned, the Declaration and assignment are in two different <script> tags respectively, as follows:

 <  script  >  const foo  =  1  </  script  >  <  script  >  foo  =  2  </  script  >  

The engine in parsing the second <script> foo = 2 o'clock may not go to the management of Foo is not already declared, such as Firefox 36 implementation is this (in the JS command line execution of each line of code, is quite so placed in the page a separate <sci The same as in the rpt> tag):

Write in a row to report a static error (non-strict mode also reported static error), divided into two lines of silence failure (no static analysis of the error, and run-time error only in strict mode only reported).

In the third case, when Tom Schuster on November 7, 14 to make the bug ready for that change, I expected it to happen, and I found Tom Schuster (Evilpie) in the IRC group that night and asked him if he felt the performance. A bit strange, his answer is that this kind of weird will only happen in JS command line, will not happen in the Web page. Indeed, in a normal Web page, it is difficult to see the declaration of the const variable and the re-assignment of it in two <script>. Although I thought he said a little bit of truth, but still vaguely feel where there is a problem, but even I can not say what the problem is.

Then about the next day (remember), I found that the original one months ago (2014 October), SpiderMonkey, another engineer Shu-yu Guo has been in Esdiscuss mentioned a related issue (the content of this post is the core of this article), And the question is very simple and clear:

1. As to how the engine should try to detect this static error, the specification is too general and may cause differences in engine implementations.

Indeed, the following is the specification of this early error detection description, specification only said can be statically determined, and did not specifically say how, I mentioned above some of the Firefox 36 did not detect the situation also confirmed this point.

  • It is a Syntax Error if lefthandsideexpression are an identifierreference so can be statically determined to ALW Ays resolve to a declarative environment record binding and the resolved binding are an immutable binding.

2. Static errors are reported in any mode, while run-time errors are only reported in strict mode.

I see here, it dawned, this is not the day before I felt the problem of the point ... A code can be static analysis of the error, the results in the implementation of the time is correct? That doesn't work.

ES6 's editor, Allen Wirfs-brock, on the second floor of the post, responded to these 2.11:

1. With regard to the 1th, this is a known issue, and a related bug has been built (the site's HTTPS certificate has expired; There are also two other examples of difficult static testing), and the specification will attempt to elaborate on what the can be statically determined specifically refers to.

2. With regard to the 2nd, this is a specification bug, not intentionally designed, because of the runtime errors and ES5 that are re-assigned to a const variable in ES6. The run-time error of re-assigning a function name to a function expression in strict mode is thrown in the same internal method (setmutablebinding):

(function  foo () {  "use strict"  = 1}) ()

Because the latter is only in strict mode error, so the former also inherited this performance, this is a bug, these two errors should be separated.

In fact, the 2 floor of the reply has solved the landlord's doubts, this post has been to discuss something has been concluded, the conclusion is: No matter what mode is reported static error (the specification will improve the specific static detection rules); No matter what mode all reports run-time errors (all errors that escaped static detection will be captured here). It's perfect, isn't it.

However, V8 engineer Erik Arvidsson on the third floor to say: The engine with a pre-parser to achieve this static detection is very difficult, the specification is more mandatory, or simply delete this requirement, ambiguity two may lead to the implementation of the engine is not unified.

Then V8, another engineer, Andreas Rossberg, also posted a few comments, and I summed up what he said:

1. A full AST is required to report this static error, and V8 's pre-parser does not

2. Not having the engine implement this can cause significant performance problems and may be difficult to optimize

3. This error is not particularly common, not to let the engine processing price is not high, or to lint tools to do it

4. An error that is equally difficult to detect statically-the non-existent variable is assigned a value in strict mode ("use strict"; Foo = 1) is a run-time error and this error should not be special

After discussion of this post, at the TC39 meeting on November 18, 2014, one months later, TC39 decided to delete the static error for the const variable, leaving only the run-time error (any mode). The minutes of the meeting said that the reason for the deletion was that "the engine is difficult to implement" and "in which cases the re-assignment of const variables should be statically detected without consensus".

Then I went to SpiderMonkey's IRC and told them: the specification changed, the static error you realized in the last two days should be removed, and then a group of SpiderMonkey people Spit Groove specification is too unstable.

As for Let/const, a code style that is now highly respected online is all-purpose const, unless the variable is re-assigned to let. ESLint There's a prefer-const rule that can force you to do this, I'm here to warn you, if you use this coding style, your editor is best to turn on ESLint's no-const-assign rules, otherwise using a const will not do you any good. You may also encounter the kind of online bug at the beginning of the article.

Extra tips: How to tell if an error is a static error or a run-time error

In most cases, the SyntaxError type of error is a static error, while other types of errors are run-time errors, but there are exceptions, such as:

// static error, but a referenceerror

And also:

// It's a run-time error in V8, but a syntaxerror,spidermonkey is a static error .

How do you know that? I usually write alert () in the console of the browser developer tool, followed by the test code, such as:

//

And:

// The alert will pop up in Chrome, proving/(/is a run-time error, in Firefox instead

Why re-assigning a const variable is not a static error

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.