技術はあとからついてくる。

技術はあとからついてくる。

就活開始の半年前にエンジニアに目覚めた人

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); // エラー
}