このエントリは、ECMAScript5 の strict モードについてのメモです。
コード関連は、chromeで確認しています。
概要
strict モードにすることで幾つかの機能を制限します。
主に
- 暗黙的なグローバル変数の禁止
- 代入不可なプロパティへの代入の禁止
- 削除できないプロパティの削除の禁止
- 関数の引数名の重複は禁止
- 8進数表記は禁止
- with 禁止
- 幾つかの識別子は予約語にするため使用禁止
などを制限します。
適用方法と範囲
strict モードにするには、
'use strict';
の文をスクリプトの先頭か関数の先頭に追加します。
スクリプト全体
スクリプト全体で strict モードにするには、スクリプトの先頭に追加します。
(js ファイルの先頭かインラインスクリプトの先頭)
// strict モード
'use strict';
var foo1 = 'A';
foo2 = 'B'; // Uncaught ReferenceError: foo2 is not defined
console.log(foo1, foo2); // 例外発生のため実行されない
先頭以外に追加しても strict モードにならず、非 strict モードで動作します。
// 非 strict モード
var bar1 = 'A';
'use strict';
bar2 = 'B'; // 問題なし
console.log(bar1, bar2); // A, B
strict モードはスクリプトを跨ぎません。
// strict モード
'use strict';
<!-- script タグのみ抜粋 -->
<script src="./strict3.js"></script>
<script>
// 非 strict モード
window.addEventListener('load', function() {
foovar1 = 'ABC';
console.log(foovar1); // ABC
} );
</script>
スクリプト全体で strict モードにした場合、非 strict モードのスクリプトと連結すると 非 strict モードのスクリプトが strict モードで動作してしまうため問題になります。
関数内
関数内で strict モードにするには関数の先頭で 'use strict'; を追加します。先頭以外に追加しても strict モードは有効になりません。
// スクリプトは 非 strict モード
function func1() {
// func1 は 非 strict モード
f1foo = 'func1';
console.log(f1foo); // func1
}
function func2() {
// func2 は strict モード
'use strict';
f2foo = 'func2'; // Uncaught ReferenceError: f2foo is not defined
console.log(f2foo); // 例外発生のため実行されない
}
strict モードでの変更点
暗黙的なグローバル変数の禁止
var を使用しないで変数に代入するとグローバル変数になりますが、それを禁止します。つまりグローバル変数を使う場合は、var で宣言する必要があります。
'use strict';
var foo = 111; // 問題なし
bar = 222; // Uncaught ReferenceError: foo is not defined
書き込み不可のプロパティへの代入禁止
'use strict';
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 100; // Uncaught TypeError: Cannot assign to read only property 'x' of object '#<Object>'
getter のみのプロパティへの代入禁止
'use strict';
var obj2 = { get x() { return 17; } };
obj2.x = 5; // Uncaught TypeError: Cannot set property x of #<Object> which has only a getter
拡張不可オブジェクトへの新規プロパティの割り当て禁止
'use strict';
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // uncaught TypeError: Can't add property newProp, object is not extensible
削除できないプロパティの削除の禁止
"use strict";
delete Object.prototype; // Uncaught TypeError: Cannot delete property 'prototype' of function Object() { [native code] }
関数の引数名の重複は禁止
'use strict';
function x(p1, p1) {}; // Uncaught SyntaxError: Duplicate parameter name not allowed in this context
変数の削除は禁止
'use strict';
var obj1 = 123;
delete obj1; // Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
8進数表記は禁止
'use strict';
var x = 077; // Uncaught SyntaxError: Octal literals are not allowed in strict mode.
eval 変数、arguments 変数の宣言禁止
'use strict';
var eval = 123; // Uncaught SyntaxError: Unexpected eval or arguments in strict mode
'use strict';
var arguments = 123; // Uncaught SyntaxError: Unexpected eval or arguments in strict mode
with 禁止
'use strict';
with (Math) { // Uncaught SyntaxError: Strict mode code may not include a with statement
x = cos(2)
};
幾つかの識別子は予約語にするため使用禁止
将来の拡張のためいくつかの識別子は予約語になります。
- implements
- interface
- let
- package
- private
- protected
- public
- static
- yield
'use strict';
var interface = 100; // Uncaught SyntaxError: Unexpected strict mode reserved word
サポートするブラウザ
ECMAScript5 の strict モードをサポートするブラウザです。
ブラウザ |
---|
Firefox 4 以上 |
Chrome 13 以上 |
Safari 6 以上 |
Edge 12 以上 |
Internet Explorer 10 以上 |
参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Strict_mode
https://msdn.microsoft.com/ja-jp/library/br230269(v=vs.94).aspx
http://www.w3schools.com/js/js_strict.asp