質問するログイン新規登録

回答編集履歴

3

ES5 \(Strict Mode\) ではブロックレベル関数宣言が `SyntaxError` になる

2016/04/21 17:29

投稿

think49
think49

スコア18194

answer CHANGED
@@ -51,7 +51,7 @@
51
51
  function declaration () {}
52
52
  ```
53
53
 
54
- ### ブロックレベル関数宣言(block-level FunctionDeclaration)の巻き上げ
54
+ ### [ES6] ブロックレベル関数宣言(block-level FunctionDeclaration)
55
55
 
56
56
  ES6 から **Strict Mode 限定**でブロックスコープで巻き上げられる関数宣言を定義出来るようになりました(注: IE10- で未対応です)。
57
57
 
@@ -89,14 +89,31 @@
89
89
  console.log(blockedDeclaration); // function blockedDeclaration() {}
90
90
  ```
91
91
 
92
- **(余談)**
92
+ **FunctionStatement**
93
93
  @nanto_vi さんは `if` 文内で条件付関数宣言する動作が Firefox 独自拡張だった頃に便宜上の名称として `FunctionStatement` (function 文) と説明しました。
94
94
  便宜上の名称なので仕様上は「文」ではないのですが、ブロックスコープ単位で評価するこの動作は `Statement` に性質が近いので言い得て妙だと思います。
95
95
 
96
96
  - [Function Expression Statements: Days on the Moon](http://nanto.asablo.jp/blog/2005/12/10/172622)
97
97
 
98
+ ### [ES5] ブロックレベル関数宣言で SyntaxError
99
+
100
+ ES5 の Strcit Mode では**ブロックレベル関数宣言は SyntaxError を返す仕様**でした。
101
+ 「Windows Vista のサポート終了日(2017/04/11)」まではブロックレベル関数宣言の利用を控えた方がいいかもしれません。
102
+
103
+ - [Where's Walden? » New ES5 strict mode requirement: function statements not at top level of a program or function are prohibited](http://whereswalden.com/2011/01/24/new-es5-strict-mode-requirement-function-statements-not-at-top-level-of-a-program-or-function-are-prohibited/)
104
+ - [Windows デスクトップ製品のライフサイクル](https://www.microsoft.com/ja-jp/windows/lifecycle/default.aspx?navIndex=4#vista)
105
+
106
+ ```JavaScript
107
+ 'use strict';
108
+
109
+ if (true) {
110
+ function blockedDeclaration () {} // SyntaxError
111
+ }
112
+ ```
113
+
98
114
  ### 更新履歴
99
115
 
100
116
  - 2016/04/22 01:55 ブロックレベル関数宣言(block-level FunctionDeclaration)の説明追加
117
+ - 2016/04/22 02:25 ES5 (Strict Mode) ではブロックレベル関数宣言が `SyntaxError` になる
101
118
 
102
119
  Re: aaaaaaaa さん

2

ブロックスコープな関数宣言\(FunctionDeclaration\)の巻き上げの説明追加\(ES6 規定\)

2016/04/21 17:29

投稿

think49
think49

スコア18194

answer CHANGED
@@ -3,6 +3,8 @@
3
3
  `var` で変数宣言されたローカル変数(関数式)は関数スコープで巻き上げ(hoisting)されます。
4
4
  (関数やグローバルコードが実行コンテキストに入る時に `var` 宣言された全ての変数を `undefined` で実体化します)。
5
5
 
6
+ - [13.3.2 Variable Statement - ECMA-262 6th Edition](http://www.ecma-international.org/ecma-262/6.0/#sec-variable-statement)
7
+
6
8
  ```JavaScript
7
9
  'use strict';
8
10
  console.log(variableExpression); // undefined
@@ -19,6 +21,8 @@
19
21
 
20
22
  `let`, `const` で宣言されたローカル変数(関数式)は宣言前に参照を試みると `ReferenceError` の例外を返します(ES6 規定)。
21
23
 
24
+ - [13.3.1 Let and Const Declarations - ECMA-262 6th Edition](http://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations)
25
+
22
26
  ```JavaScript
23
27
  'use strict';
24
28
  console.log(letExpression); // ReferenceError: letExpression is not defined
@@ -35,6 +39,8 @@
35
39
 
36
40
  関数宣言(FunctionDeclaration)は関数スコープで巻き上げられます。
37
41
 
42
+ - [14.1 Function Definitions - ECMA-262 6th Edition](http://www.ecma-international.org/ecma-262/6.0/#sec-function-definitions)
43
+
38
44
  ```JavaScript
39
45
  'use strict';
40
46
  console.log(declaration); // function declaration () {}
@@ -45,4 +51,52 @@
45
51
  function declaration () {}
46
52
  ```
47
53
 
54
+ ### ブロックレベル関数宣言(block-level FunctionDeclaration)の巻き上げ
55
+
56
+ ES6 から **Strict Mode 限定**でブロックスコープで巻き上げられる関数宣言を定義出来るようになりました(注: IE10- で未対応です)。
57
+
58
+ - [9.2.12 FunctionDeclarationInstantiation(func, argumentsList) – ECMA-262 6th Edition](http://www.ecma-international.org/ecma-262/6.0/#sec-functiondeclarationinstantiation)
59
+ - [block-level function declaration - ECMAScript 6 compatibility table](http://kangax.github.io/compat-table/es6/#test-block-level_function_declaration)
60
+
61
+ ```JavaScript
62
+ 'use strict';
63
+ console.log(blockedDeclaration); // ReferenceError: blockedDeclaration is not defined
64
+
65
+ /**
66
+ * 関数宣言(Strict Mode ではブロックスコープ)
67
+ */
68
+ if (true) {
69
+ console.log(blockedDeclaration); // function blockedDeclaration() {}
70
+ function blockedDeclaration () {}
71
+ }
72
+
73
+ console.log(blockedDeclaration); // ReferenceError: blockedDeclaration is not defined
74
+ ```
75
+
76
+ 「非Strict Mode (sloppy mode)」では関数スコープで巻き上げられます。
77
+
78
+ ```JavaScript
79
+ console.log(blockedDeclaration); // undefined
80
+
81
+ /**
82
+ * 関数宣言(sloppy mode では関数スコープ)
83
+ */
84
+ if (true) {
85
+ console.log(blockedDeclaration); // function blockedDeclaration() {}
86
+ function blockedDeclaration () {}
87
+ }
88
+
89
+ console.log(blockedDeclaration); // function blockedDeclaration() {}
90
+ ```
91
+
92
+ **(余談)**
93
+ @nanto_vi さんは `if` 文内で条件付関数宣言する動作が Firefox 独自拡張だった頃に便宜上の名称として `FunctionStatement` (function 文) と説明しました。
94
+ 便宜上の名称なので仕様上は「文」ではないのですが、ブロックスコープ単位で評価するこの動作は `Statement` に性質が近いので言い得て妙だと思います。
95
+
96
+ - [Function Expression Statements: Days on the Moon](http://nanto.asablo.jp/blog/2005/12/10/172622)
97
+
98
+ ### 更新履歴
99
+
100
+ - 2016/04/22 01:55 ブロックレベル関数宣言(block-level FunctionDeclaration)の説明追加
101
+
48
102
  Re: aaaaaaaa さん

1

表現の微修正

2016/04/21 16:56

投稿

think49
think49

スコア18194

answer CHANGED
@@ -15,7 +15,7 @@
15
15
  console.log(variableExpression); // function variableExpression() {}
16
16
  ```
17
17
 
18
- ### 関数式(LexicalDeclaration)
18
+ ### let, const 文は巻き上がらない
19
19
 
20
20
  `let`, `const` で宣言されたローカル変数(関数式)は宣言前に参照を試みると `ReferenceError` の例外を返します(ES6 規定)。
21
21
 
@@ -31,7 +31,7 @@
31
31
  const constExpression = function constExpression () {};
32
32
  ```
33
33
 
34
- ### 関数宣言(FunctionDeclaration)
34
+ ### 関数宣言(FunctionDeclaration)の巻き上げ
35
35
 
36
36
  関数宣言(FunctionDeclaration)は関数スコープで巻き上げられます。
37
37