The JavaScript delete 演算子は、オブジェクトからプロパティを削除します。同じプロパティへの参照がそれ以上保持されない場合は、自動的に解放されます。

構文

delete expression 

expression には、プロパティへの参照になる式を置きます。例えば:

delete object.property 
delete object['property']

引数

object
オブジェクト名、またはオブジェクトとして評価される式
property
削除するプロパティです。

戻り値

非 strict モードでは、プロパティが編集不可の場合、false が返ります。その他の場合すべてで true が返ります。

例外

strict モード では、プロパティが編集不可の場合、Global_objects/SyntaxError をスローします。

説明

一般的に信じられていることとは異なり、delete 演算子は、直接的にメモリを開放することはありません。メモリの管理は参照が切れることで間接的に行われます。詳細は memory management をご覧ください。

delete 演算子は指定したプロパティをオブジェクトから取り除きます。削除に成功すると true, を返し、そうでなければ false を返します。しかし、次のシナリオを考慮することが重要です:

  • 削除しようとしたプロパティが存在しない場合、delete は何の効果もなく、true を返します。
  • 同様の名前のプロパティがオブジェクトのプロトタイプチェーンに存在する場合、削除後はプロトタイプチェーンのプロパティをオブジェクトが使うようになります (つまり、delete 自身のプロパティにのみ効果があります)。
  • グローバルスコープや関数スコープから var で宣言されたプロパティは削除できません。
    • グローバルスコープで delete は関数を削除できない (これが関数定義か関数式の一部かどうか)。
    • (グローバルスコープとは別に) オブジェクトの一部である関数は delete で削除できる。
  • Any property declared with letconst で宣言されたプロパティはそれらが宣言されたスコープから削除できない。
  • 編集不可能なプロパティは削除できない。これには MathArrayObject のようなビルトインオブジェクトのプロパティや Object.defineProperty() のようなメソッドで編集不可として生成されたプロパティが含まれる。

次のスニペットがシンプルな例です:

var Employee = {
  age: 28,
  name: 'abc',
  designation: 'developer'
}

console.log(delete Employee.name);   // returns true
console.log(delete Employee.age);    // returns true

// When trying to delete a property that does 
// not exist, true is returned 
console.log(delete Employee.salary); // returns true

編集不可のプロパティ

プロパティが編集化に設定されているとき、delete は何の効果もなく、false を返します。strict モードでは、これは SyntaxError を生成します。

var Employee = {};
Object.defineProperty(Employee, 'name', {configurable: false});

console.log(delete Employee.name);  // returns false

varletconst は、delete 演算子で削除できない編集不可のプロパティを生成します:

var nameOther = 'XYZ';

// We can access this global property using:
Object.getOwnPropertyDescriptor(window, 'nameOther');  

// output: Object {value: "XYZ", 
//                  writable: true, 
//                  enumerable: true,
//                  configurable: false}

// Since "nameOther" is added using with the
// var keyword, it is marked as "non-configurable"

delete nameOther;   // return false

strict モードでは、例外が発生します。

Strict vs. 非 strict モード

strict モードのとき、変数や関数の引数、関数名への参照に直接 delete が使われた場合、SyntaxError をスローします。

var で宣言された変数は編集不可に設定されます。次の例では、salary は編集不可で削除できません。非 strict モードでは、delete 演算子は false を返します。

function Employee() { 
  delete salary;
  var salary;
}

Employee();

strict モードで同じコードがどのように振る舞うか見てみましょう。false を返す代わりに、ステートメントは SyntaxError を発生させます。

"use strict";

function Employee() {
  delete salary;  // SyntaxError
  var salary;        
}

// Similarly, any direct access to a function
// with delete will raise a SyntaxError

function DemoFunction() {
  //some code
}

delete DemoFunction; // SyntaxError

// creates the property adminName on the global scope
adminName = 'xyz';            

// creates the property empCount on the global scope
// Since we are using var, this is marked as non-configurable. The same is true of let and const.
var empCount = 43;

EmployeeDetails = {
  name: 'xyz',
  age: 5,
  designation: 'Developer'
};

// adminName is a property of the global scope.
// It can be deleted since it is created without var.
// Therefore, it is configurable.
delete adminName;       // returns true

// On the contrary, empCount is not configurable, 
// since var was used.
delete empCount;       // returns false 

// delete can be used to remove properties from objects  
delete EmployeeDetails.name; // returns true 

// Even when the property does not exists, it returns "true"
delete EmployeeDetails.salary; // returns true 

// delete does not affect built-in static properties
delete Math.PI; // returns false 

// EmployeeDetails is a property of the global scope.
// Since it defined without "var", it is marked configurable
delete EmployeeDetails;   // returns true

function f() {
  var z = 44;

  // delete doesn't affect local variable names
  delete z;     // returns false
}

delete とプロトタイプチェーン

次の例では、 プロトタイプチェーンで同じ名前のプロパティを使用できる間に、オブジェクトの独自のプロパティを削除します :

function Foo() {
  this.bar = 10;
}

Foo.prototype.bar = 42;

var foo = new Foo();

// Returns true, since the own property
// has been deleted on the foo object
delete foo.bar;           

// foo.bar is still available, since it 
// is available in the prototype chain.
console.log(foo.bar);

// We delete the property on the prototype
delete Foo.prototype.bar; 

// logs "undefined" since the property
// is no longer inherited
console.log(foo.bar);           

配列の要素の削除

配列の要素を削除したとき、配列の長さは影響を受けません。これは配列の最後の要素を削除しても保持されます。

delete 演算子が配列の要素を削除すると、要素はもはや配列からなくなります。 次の例では、trees[3]delete で削除されます。

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3];
if (3 in trees) {
    // this does not get executed
}

配列の要素を存在させたいが値が未定義の場合、delete 演算子の代わりに undefined 値を用います。次の例では、trees[3] は undefined が割り当てられていますが、配列の要素はまだ存在しています:

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees[3] = undefined;
if (3 in trees) {
    // this gets executed
}

代わりに、配列の内容を変更して配列要素を削除する場合は、splice メソッドを使用します。次の例では、splice を使用して配列から trees[3] が削除されます:

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.splice(3,1);
console.log(trees); // ["redwood", "bay", "cedar", "maple"]

仕様

仕様 ステータス コメント
ECMAScript Latest Draft (ECMA-262)
The delete Operator の定義
ドラフト  
ECMAScript 2015 (6th Edition, ECMA-262)
The delete Operator の定義
標準  
ECMAScript 5.1 (ECMA-262)
The delete Operator の定義
標準  
ECMAScript 1st Edition (ECMA-262)
The delete Operator の定義
標準 初期定義。JavaScript 1.2 で実装。

ブラウザー実装状況

機能ChromeEdgeFirefoxInternet ExplorerOperaSafari
基本対応 あり あり1 あり あり あり
Temporal dead zone ? ?36 ? ? ?
機能Android webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
基本対応 あり あり あり4 あり あり あり
Temporal dead zone ? ? ?36 ? ? ?

クロスブラウザーの問題点

ECMAScript はオブジェクトのイテレーション順を実装系依存であるとしているにもかかわらず、すべての主要なブラウザーはイテレーション順を、(少なくともプロトタイプ上にないプロパティについて) 最初に追加されたプロパティを最初に持ち出す方式に基づいてサポートしているように見受けられます。ところが Internet Explorer ではプロパティに対して delete を用いたときに、他のブラウザーが単純なオブジェクトを整列された連想配列のように用いることを妨げる、ややこしい動作になる場合があります。Internet Explorer では、プロパティのが実際 undefined に設定されているとき、後から同じ名前で再びプロパティを追加すると、そのプロパティは元の場所でイテレートされるようになるでしょう。削除済みのプロパティを再度追加した場合に期待するであろう、イテレーション順の最後ではありません。

クロスブラウザー環境で整列された連想配列をしたい場合は、可能であれば Map を使用してください。または、2 つに分けた配列 (片方はキー、もう片方は値) やプロパティをひとつ持つオブジェクトの配列などで構造をシミュレートしてください。

関連項目

ドキュメントのタグと貢献者

このページの貢献者: gocho, YuichiNukiyama, fuwafuwafuwa, jungjoo, teoli, ethertank, yyss
最終更新者: gocho,