delete
strictモードで、が修飾されていない識別子で使用されたときに構文エラーが発生する理由を理解するのに問題があります。
ほとんどの場合、それは理にかなっています...var
キーワードを使用して通常の方法で変数を宣言しdelete
、それらを使用しようとすると、非厳密モードではサイレントに失敗するため、厳密モードで失敗するのは理にかなっていますそのような場合はエラーが発生します。
ただし、修飾された識別子を削除できない場合があります。
(function() {
// "use strict";
var obj = Object.create({}, { bloop: { configurable: false } });
delete obj.bloop; // throws TypeError in strict mode, silently fails in non-strict.
console.log('bloop' in obj); // true
}());
厳密モードでは、ここでランタイムチェックを実行する必要があります。これが発生すると、TypeErrorがスローされるためです。非厳密モードで非修飾識別子を正常に削除できる場合もあります...
// "use strict";
window.bar = 6;
console.log(typeof bar); // number
delete bar; // works in non-strict, syntax error in strict!
console.log(typeof bar); // undefined
実際、私の理解では、(非厳密モードで)削除できるかどうかは内部[[Configurable]]
プロパティに依存し、修飾された識別子とは関係ありません。私の知る限り、厳密モードでは、(ローカルVOのプロパティとして)構成可能な非グローバル変数を削除する方法はありません。
(function() {
// "use strict";
eval('var foo = 5;');
console.log(typeof foo); // number
delete foo; // works in non-strict, SyntaxError in strict.
console.log(typeof foo); // undefined
}());
だから、私の質問は、delete
プロパティが構成可能でない場合にTypeErrorがとにかくスローされるときに、修飾されていない識別子で使用するときにSyntaxErrorをスローすることのポイントは何ですか?これは不要な制限のようであり、場合によっては、厳密モードを使用しない以外に回避策がないように思われます(3番目の例)。この決定の背後にある動機を誰かが説明できますか?
eval
更新:直接呼び出しには、呼び出し元の関数のスコープではなく、厳密モードで独自のスコープがあるため、3番目の例foo
では厳密モードでは定義されないという事実を見落としていることに気づきました。とにかく、ランタイムチェックはこれをキャッチしますが、副次的な質問が発生しますeval
。非厳密の'd変数宣言の場合のように、構成可能なローカル変数を厳密モードにする方法はありませんか?の数少ない合法的な使用法の1つであるAFAIK eval
。