2015-02-05 1 views
9

Я играю с некоторой бессмысленной логикой, чтобы лучше понять ES6 и заметил странное появление при определении константы.ES6 Почему я могу переназначить константу, когда она определена в цикле

Представляется возможным изменить постоянное назначение, если определено в цикле:

 "use strict"; 

     for(const i=0;i<10;i++){ //seting constant in loop 
      console.log(i); //is reassigned and incremented 0,1,2,3... 
     } 


     const e = 0; //setting constant outside loop 
     for(;e<10;e++){ //cannot reassign constant 
      console.log(e); 
     } 

Это ожидаемое поведение и может кто-нибудь пролить некоторый свет на то, почему это происходит, это заявление в петле по-другому?

enter image description here


Обновление от Statements/const

This declaration creates a constant that can be global or local to the function in which it is declared. Constants are block-scoped.

+1

Ничего себе, просто попробовал это в Chrome версии 40.0.2214.94, и он генерирует бесконечный цикл, возможно, потому что константа никогда не отключается. Какой браузер вы используете? – Sarcadass

+0

Это, вероятно, означает, что хром имеет правильное значение, не переназначая его (но, скорее всего, следует выкидывать ошибку) и все еще поднимает константу. В вашем случае кажется, что 'const' действует как' let' https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#let_in_loops –

+0

В Firefox я получаю 'TypeError: redeclaration var i' для первого примера – Kapep

ответ

8

Когда Вы изменяете "неизменны связывания", то current draft броски только в строгом режиме:

Как @kangax указал out, переназначение константы всегда должно бросаться, так как const создает "неизменны связывание" с strict флагом на (here):

If IsConstantDeclaration of d is true, then

Call env’s CreateImmutableBinding concrete method passing dn and true as the arguments.

и then:

SetMutableBinding (N,V,S) ...

  1. Else if the binding for N in envRec is a mutable binding, change its bound value to V.
  2. Else this must be an attempt to change the value of an immutable binding so if S is true throw a TypeError exception.

Однако, узел отбрасывает только в строгом режиме:

"use strict"; 

const e = 0; 
e = 42; // SyntaxError: Assignment to constant variable. 

(непонятно, почему это «SyntaxError») ...

В режиме нестрогого, присваивание константы молча игнорируются:

const e = 0; 
e = 42; 
console.log(e); // 0 

Испытан с узлом v0.10.35 с --harmony флагом.

+0

Это похоже на ошибку в узле. Или это не реализовано. Переназначение 'const' должно обязательно бросать, независимо от режима. Если вы посмотрите на https://people.mozilla.org/~jorendorff/es6-draft.html#sec-for-statement-runtime-semantics-labelledevaluation, вы увидите, что 'const' приводит к' CreateImmutableBinding' с S = true, поэтому это TypeError, как только цикл запускает вторую итерацию. – kangax

+2

Вы также можете увидеть точную разбивку поддержки в нашей таблице сопоставлений - https://kangax.github.io/compat-table/es6/#const - которая показывает, что «переопределение константы является ошибкой» на самом деле отсутствует в Chrome на момент (который является тем, что испытывает OP, я предполагаю) – kangax

+0

@kangax: спасибо за указание на то, отредактировано. – georg