643

JavaScript にグローバル変数 (実際にはwindowプロパティですが、重要ではないと思います) があり、以前のスクリプトによって既に入力されていますが、後で実行される別のスクリプトでその値を確認したり、さえ定義されています。

私は入れsome_var = undefinedて、テストの目的で動作しますtypeof some_var == "undefined"が、それが正しい方法だとは本当に思いません。

どう思いますか?

4

12 に答える 12

511

オペレーターはdelete、オブジェクトからプロパティーを削除します。変数を削除することはできません。したがって、質問に対する答えは、グローバル変数またはプロパティがどのように定義されているかによって異なります。

(1) で作成した場合はvar削除できません。

例えば:

var g_a = 1; //create with var, g_a is a variable
delete g_a; //return false
console.log(g_a); //g_a is still 1

(2) なしvarで作成された場合は、削除できます。

g_b = 1; //create without var, g_b is a property
delete g_b; //return true
console.log(g_b); //error, g_b is not defined

技術解説

1.使用var

この場合、参照は、現在のスコープにアタッチされている ECMAScript 仕様が「 VariableEnvironmentg_a 」と呼ぶもので作成されます。考慮する場合)または「グローバル」コードの場合、VariableEnvironmentはグローバル オブジェクトにアタッチされます(多くの場合)。varletwindow

VariableEnvironment内の参照は通常は削除できません - ECMAScript 10.5で詳述されているプロセスでこれについて詳しく説明されていますが、コードがevalコンテキスト (ほとんどのブラウザーベースの開発コンソールが使用する) で実行されない限り、で宣言された変数は削除できvarないと言えば十分です。削除されます。

2.使用せずにvar

キーワードを使用せずに名前に値を代入しようとすると、JavaScript は ECMAScript 仕様で「 LexicalEnvironmentvar 」と呼ばれるもので名前付き参照を見つけようとします。主な違いは、LexicalEnvironmentがネストされていることです。つまり、LexicalEnvironmentには親 ( ECMAScript 仕様で「外部環境参照」と呼ばれるもの)、JavaScript がLexicalEnvironmentで参照を見つけられない場合、親LexicalEnvironmentを検索します(詳細は10.3.1および10.2.2.1を参照)。トップレベルのLexicalEnvironmentは「グローバル環境」です"、そしてその参照がグローバル オブジェクトのプロパティであるという点で、それはグローバル オブジェクトにバインドされます。そのためvar、現在のスコープまたは外部スコープでキーワードを使用して宣言されていない名前にアクセスしようとすると、JavaScript は最終的にプロパティを取得します。windowその参照として機能するオブジェクトの. 前に学んだように、オブジェクトのプロパティは削除できます.

ノート

  1. 宣言は「ホイスト」されることを覚えておくことが重要ですvar。つまり、それらは常に、それらが含まれるスコープの最初に発生したと見なされますが、varステートメントで行われる可能性のある値の初期化ではなく、そのままの場所に残ります。 . したがって、次のコードでは、プロパティではなくVariableEnvironmentaからの参照であり、その値はコードの最後になります。window10

    function test() { a = 5; var a = 10; }
    
  2. 上記の説明は、「厳密モード」が有効になっていない場合です。「厳密モード」を使用する場合のルックアップ規則は少し異なり、「厳密モード」なしでウィンドウ プロパティに解決される語彙参照は、「厳密モード」では「宣言されていない変数」エラーを発生させます。これがどこで指定されているのかよくわかりませんでしたが、ブラウザの動作です。

于 2014-09-18T18:33:28.943 に答える
283

scunliffeの答えは機能しますが、技術的にはそうあるべきです

delete window.some_var;

ターゲットがオブジェクト プロパティでない場合、deleteはノーオペレーションであると想定されています。例えば、

(function() {
   var foo = 123;
   delete foo; // wont do anything, foo is still 123
   var bar = { foo: 123 };
   delete bar.foo; // foo is gone
}());

しかし、グローバル変数は実際には window オブジェクトのメンバーであるため、機能します。

プロトタイプ チェーンが関係している場合、deleteの使用は、プロトタイプではなくターゲット オブジェクトからプロパティを削除するだけなので、より複雑になります。例えば、

function Foo() {}
Foo.prototype = { bar: 123 };
var foo = new Foo();
// foo.bar is 123
foo.bar = 456;
// foo.bar is now 456
delete foo.bar;
// foo.bar is 123 again.

ので注意してください。

注: 私の答えは多少不正確です(最後の「誤解」を参照してください)。リンクはすべての悲惨な詳細を説明していますが、要約すると、ブラウザと削除元のオブジェクトによって大きな違いがある可能性があります. delete object.somePropである限り、一般的に安全object !== windowです。var適切な状況下では可能ですが、宣言された変数を削除するためにそれを使用することはまだありません。

于 2009-10-20T19:47:34.990 に答える
39

を使用せずに変数を暗黙的に宣言する場合var、適切な方法は を使用することdelete fooです。

ただし、削除した後、これを加算などの操作で使用しようとするReferenceErrorと、宣言されていない未定義の識別子に文字列を追加できないため、 a がスローされます。例:

x = 5;
delete x
alert('foo' + x )
// ReferenceError: x is not defined

状況によっては、false、null、または undefined に割り当てた方が安全な場合があります。これにより、宣言され、このタイプのエラーがスローされなくなります。

foo = false

ECMAScriptnullではfalseundefined0NaN、または''はすべて に評価されることに注意してくださいfalse。演算子を使用しないことを確認してください。!==代わり!=に、ブール値の型チェックを行い、ID チェックを行いたくない場合に使用します ( とを使用しnullます)。== falsefalse == undefined

deleteまた、参照を「削除」するのではなく、オブジェクトのプロパティのみを直接削除することに注意してください。

bah = {}, foo = {}; bah.ref = foo;

delete bah.ref;
alert( [bah.ref, foo ] )
// ,[object Object] (it deleted the property but not the reference to the other object)

で変数を宣言した場合、varそれを削除することはできません:

(function() {
    var x = 5;
    alert(delete x)
    // false
})();

サイの場合:

js> var x
js> delete x
false

また、次のような事前定義されたプロパティを削除することもできませんMath.PI

js> delete Math.PI
false

他の言語と同様に、いくつかの奇妙な例外がありdeleteます。

于 2009-10-20T19:31:04.003 に答える
35

詳細については、ノアの回答を参照してください

//Option A.) set to null
some_var = null;

//Option B.) set to undefined
some_var = undefined;

//Option C.) remove/delete the variable reference
delete obj.some_var
//if your variable was defined as a global, you'll need to
//qualify the reference with 'window'
delete window.some_var;

参考文献:

于 2009-10-20T19:24:58.960 に答える
15

TLDR: 単純に定義された変数 ( varlet、なしconst) は で削除できますdelete。,, -を使用するvarと、 も も使用しても削除できませんでした。letconstdeleteReflect.deleteProperty

クローム 55:

simpleVar = "1";
"1"
delete simpleVar;
true
simpleVar;
VM439:1 Uncaught ReferenceError: simpleVar is not defined
    at <anonymous>:1:1
(anonymous) @ VM439:1
var varVar = "1";
undefined
delete varVar;
false
varVar;
"1"
let letVar = "1";
undefined
delete letVar;
true
letVar;
"1"
const constVar="1";
undefined
delete constVar;
true
constVar;
"1"
Reflect.deleteProperty (window, "constVar");
true
constVar;
"1"
Reflect.deleteProperty (window, "varVar");
false
varVar;
"1"
Reflect.deleteProperty (window, "letVar");
true
letVar;
"1"

Firefox Nightly 53.0a1 も同じ動作を示します。

于 2017-01-05T15:13:36.707 に答える
3

成功したときにdelete戻ることに注意してください。true

更新 2021: Chrome 88 および Firefox 84 でテスト済み:

implicit_global = 1;
delete implicit_global; // true

window.explicit_global = 1;
delete explicit_global; // true

const _object = {property: 1};
delete _object.property; // true

function_set = function() {};
delete function_set; // true

function function_declaration() {};
delete function_declaration; // false

(function () {
    var _var = 1;
    console.log(delete _var); // false
    console.log(_var); // 1
})()

(function () {
    let _let = 1;
    console.log(delete _let); // false
    console.log(_let); // 1
})()

(function () {
    const _const = 1;
    console.log(delete _const); // false
    console.log(_const); // 1
})()

この回答の以前の編集は、ブラウザーの更新により関連性がなくなりました。

于 2015-11-23T10:36:38.750 に答える
2

var x;初回使用時に宣言した変数は削除できません。ただし、変数xが最初に宣言なしでスクリプトに表示された場合は、delete演算子 ( delete x;) を使用すると、配列の要素を削除したり、オブジェクトのプロパティを削除したりするのと同じように、変数が削除されます。

于 2016-03-31T17:48:42.737 に答える