JavaScript の delete
演算子は、オブジェクトからプロパティを削除します。同じプロパティへの参照がそれ以上保持されない場合は、自動的に解放されます。
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
構文
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
で削除できます。
- そのため、
let
やconst
で宣言された任意のプロパティはそれらが宣言されたスコープから削除できません。- 編集不可能なプロパティは削除できません。これには
Math
やArray
、Object
のようなビルトインオブジェクトのプロパティや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
var
や let
、const
は、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 (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 で実装。 |
ブラウザー実装状況
BCD tables only load in the browser
クロスブラウザーの問題点
ECMAScript はオブジェクトのイテレーション順を実装系依存であるとしているにもかかわらず、すべての主要なブラウザーはイテレーション順を、(少なくともプロトタイプ上にないプロパティについて) 最初に追加されたプロパティを最初に持ち出す方式に基づいてサポートしているように見受けられます。ところが Internet Explorer ではプロパティに対して delete
を用いたときに、他のブラウザーが単純なオブジェクトを整列された連想配列のように用いることを妨げる、ややこしい動作になる場合があります。Internet Explorer では、プロパティの値が実際 undefined に設定されているとき、後から同じ名前で再びプロパティを追加すると、そのプロパティは元の場所でイテレートされるようになるでしょう。削除済みのプロパティを再度追加した場合に期待するであろう、イテレーション順の最後ではありません。
クロスブラウザー環境で整列された連想配列をしたい場合は、可能であれば Map
を使用してください。または、2 つに分けた配列 (片方はキー、もう片方は値) やプロパティをひとつ持つオブジェクトの配列などで構造をシミュレートしてください。