JavaScriptの'use strict'によって許容されなくなるもの
use strictのあるなしで挙動の違いをまとめた
変数宣言が強制される
function hoge() { 'use strict'; foo = 'foo' // fooはグローバルスコープに存在しないとする console.log(foo); // エラー }
- 非Strictでは出力されるが、Strictモードではエラーになる
- グローバルスコープの汚染も防げる
thisの振る舞いが変わる
- 非Strictモードでは、thisとして関数に渡された値は、常にオブジェクトとして扱われる。
- Strictモードでは、thisの暗黙的な変換が発生しなくなる。
function notstrict() { console.log(typeof this); } function strict() { 'use strict'; console.log(typeof this); } notstrict.call('foo'); // object strict.call('foo'); // string
thisの振る舞いが変わることのメリット
function notstrict() { console.log(null === this); } function strict() { 'use strict'; console.log(null === this); } notstrict.call(null); // false strict.call(null); // true
非Strictモードの場合、関数に渡したnullが null以外の何か に変換されている → 非Strictではthisにnullやundefinedを渡すとグローバルオブジェクトとして扱われる
- Strictモードを使えば、意図せずnullやundefinedを渡していてもグローバルオブジェクトへの影響を避けられる
エラーが黙殺されなくなる
いわゆる「エラーになったけどなんか動く」が許されなくなる
重複するプロパティ名やパラメータ名の禁止
こんなコードはエラーになる。
'use strict'; var obj = { val: 'hoge', val: 'foo' // プロパティ名の重複 } function fnc(param, param) { // パラメータの重複 %%% }
非Strictの場合、名前が重複した時は「後勝ち」になる。
変数や関数へのdelete演算子の仕様禁止
delete演算子は、あくまでもオブジェクトのプロパティを削除するための演算子であり、変数や関数の削除はできない。
非Strictモードでは、変数や関数にdelete演算子を用いてもエラーにはならないが、Strictモードではエラーになる。
制限済みオブジェクト/プロパティへの操作禁止
Object.preventExtensions(), Object.seal(), Object.freeze()メソッドを使用したオブジェクトなどへの操作をエラーにする。
argumentsの独立
- 非Strictモードでは、関数パラメータとargumentsオブジェクトはお互いに影響し合う
- Strictモードでは、関数パラメータとargumentsオブジェクトをそれぞれ独立して扱える
function notstrict(val) { val = 1; console.log(val); // 1 console.log(arguments[0]); // 1 arguments[0] = 9; console.log(val); // 9 console.log(arguments[0]); // 9 } function strict(val) { 'use strict'; val = 1; console.log(val); // 1 console.log(arguments[0]); // 0 arguments[0] = 9; console.log(val); // 1 console.log(arguments[0]); // 9 } notstrict(0); strict(0);
8進数リテラルの禁止
function nostrict() { console.log(011); // 9 } function strict() { 'use strict'; console.log(011); // エラー }
withの禁止
function nostrict() { let val = 3.5; with(Math) { console.log(cell(val) + floor(val)); } }
evalが独自のスコープを持つ
eval関数: eval()は文字列として表された JavaScript コードを式として評価する関数
eval関数内で定義された変数は、eval関数が含まれるスコープ内で有効であったが
Strictモードでは、eval関数内で定義された変数はeval内でのみ参照可能となる
function nostirct() { eval('val hoge = "hoge";'); console.log(hoge); // hoge eval('let fuga = "fuga";'); console.log(fuga); // エラー(そもそもletはブロックスコープ) } function strict() { 'use strict'; eval('val hoge = "hoge"'); console.log(hoge); // エラー }