JavaScriptオブジェクトからプロパティを削除するにはどうすればいいですか?

以下のようにオブジェクトを作成するとします。

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

プロパティ regex を削除して、次のように新しい myObject を作成するには、どのようにすればよいでしょうか。

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};
ソリューション

こんな感じで。

delete myObject.regex;
// or,
delete myObject['regex'];
// or,
var prop = "regex";
delete myObject[prop];

デモ

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};
delete myObject.regex;

console.log(myObject);

もっと詳しく知りたい方は、Stack Overflowのユーザーであるkangaxさんが、ご自身のブログ「Understanding delete」で、delete文について驚くほど詳細なブログ記事を書いています。これはとてもお勧めです。

解説 (17)

var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

delete myObject.regex;

console.log ( myObject.regex); // logs: undefined

これは、FirefoxとInternet Explorerで動作し、他のすべての環境でも動作すると思います。

解説 (0)

Update 2018-07-21: 長い間、この回答を恥ずかしいと思っていたので、そろそろ少し触ってみようと思います。この回答の無駄に長くて複雑な部分を読みやすくするために、ちょっとした解説や説明、フォーマットをしてみました。


# ♪短いバージョン # 実際の質問への回答 他の人が言っているように、`delete`を使うことができます。
obj // {"foo": "bar"}
delete obj["foo"]
obj // {}
obj["foo"] // undefined

配列と同等

配列から delete を使ってはいけません。代わりに Array.prototype.splice を使用してください。

arr // [1,2,3,4,5]
arr.splice(3,1); // 4
arr // [1,2,3,5]

# 長いバージョン JavaScriptはOOP言語なので、*配列*を含めてすべてがオブジェクトになります。そのため、特に注意点を指摘する必要があると感じています。 配列では、通常のオブジェクトとは異なり、`delete`を使用すると、`null`という形でゴミが残り、配列に「穴」ができてしまいます。
var array = [1, 2, 3, 4];
delete array[2];
/* Expected result --> [1, 2, 4]
 * Actual result   --> [1, 2, null, 4]
 */

ご覧のとおり、delete は必ずしも期待通りには動作しません。値は上書きされますが、メモリは再割り当てされません。つまり、array[4]array[3]に再配置されることはありません。これはArray.prototype.unshiftとは対照的です。Array.prototype.unshiftは配列の先頭に要素を挿入し、すべてをシフトアップします(array[0]array[1]になるなど)。 正直なところ、undefinedではなくnullに設定すること(これは本当に奇妙なことです)を除けば、この動作は驚くべきことではありません。なぜなら、deletetypeofのような単項演算子で、言語にハードボイルドに組み込まれており、使用されるオブジェクトのタイプを気にしないことになっているのに対し、ArrayObjectのサブクラスで、配列を扱うために特別に設計された*メソッドを持っているからです。ですから、deleteに配列を再シフトするための特別なケースを用意する正当な理由はありませんし、それは無駄な作業で物事を遅らせるだけです。振り返ってみると、私の期待は現実的ではありませんでした。 もちろん、それは私を驚かせました。なぜなら、私は「null garbage」に対する私の聖戦を正当化するためにこのように書いたからです。

nullに内在する危険性や問題点、無駄になるスペースを無視して、配列が正確である必要がある場合には、これは問題になります。 これはnullをなくすためのひどい正当化です。null`は不適切に使用された場合にのみ危険であり、「精度」とは何の関係もありません。配列から「削除」してはいけない本当の理由は、ゴミだらけの厄介なデータ構造を放置しておくのは、ずさんでバグが発生しやすいからです。 この後の話は、かなり長いシナリオを想定していますので、「解決策」のセクションまで読み飛ばしていただいても構いません。このセクションを残す理由は、おそらく面白いと思う人がいると思うからで、「面白い」回答を投稿して、後でその「面白い」部分をすべて削除してしまうような「あの男」にはなりたくないからです。 ...バカですよね、私。

♪ 工夫された長文のPDP-11のシナリオ

例えば、JSONシリアライズを使って、「タブ」に使う配列を文字列(ここではlocalStorage)に格納するWebアプリを作っているとしましょう。また、コードでは、画面に描画する際に、配列のメンバーの数値インデックスを使用して「タイトル」を付けているとします。単に「タイトル」も保存するのではなく、なぜこのようなことをするのでしょうか?それは...理由です。 この人は1960年代のPDP-11ミニコンピュータでUNIXを動かしていて、X11は問題外なので、ElinksベースでJavaScriptに準拠したラインプリンタ対応のブラウザを自分で書いています。 ますます馬鹿げたエッジケースのシナリオはさておき、前記の配列に delete を使用すると、null が配列を汚染することになり、おそらく後にアプリのバグの原因となるでしょう。また、nullをチェックすると、そのまま数字がスキップされてしまい、タブが[1] [2] [4] [5] ...のようにレンダリングされてしまいます。 if (array[index] == null) 続けます。 else title = (index + 1).toString(); / 0 -> "1"

  • 1 -> "2"
  • 2 -> (無)
  • 3 -> "4" */ ええ、これは間違いなくあなたが望んでいたものではありません。 ここで、jのような第2のイテレータを用意して、配列から有効な値が読み込まれたときだけインクリメントするようにすることは可能です。しかし、それでは null の問題は正確には解決しませんし、PDP-11 の troll ユーザーを満足させなければなりません。残念ながら、彼のコンピュータには最後の整数を保持するのに十分なメモリがありません (可変幅の配列をどうやって処理するのかは聞かないでください...)。 そこで、彼はあなたに怒りのメールを送ります。 おい、お前のウェブアプリが俺のブラウザを壊したぞ!?あなたの馬鹿げたコードのせいでブラウザがセグメンテーションした後、私のlocalStorageデータベースをチェックしたところ、以下のことがわかりました。 tabs:['Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, ... ] 。]" 貴重なデータをクリアした後、再びセグメンテーションが発生したので、バックトレースをしてみたところ、何が出てきたか?何を見つけたって?変数を使いすぎです。 var i = index; var j = 1; Grr, I am angry now. -Troll Davidson 今頃、あなたは途方に暮れていることでしょう。この人はあなたのアプリについて延々と文句を言っていて、あなたは彼に黙ってもっといいコンピュータを買いに行けと言いたいのです。

    解決策: Array.prototype.splice (Array.prototype.splice)

    幸いなことに、配列にはインデックスを削除してメモリを再割り当てするための特殊なメソッドがあります: Array.prototype.splice().以下のように書くことができます。

Array.prototype.remove = function(index){
  this.splice(index,1);
}
...
array = [1, 2, 3, 4];
array.remove(2);
// Result -> [1, 2, 4]

これで、PDP-11さんを喜ばせることができました。ばんざーい!(それでも私は彼を諭しますが...)。

Array.prototype.splice vs Array.prototype.slice

この2つの似たような名前の関数の違いを指摘することは重要だと思います。

Array.prototype.splice(start, n)

.splice()は、配列を変異させ、削除したインデックスを返します。配列はインデックスstartから始まり、n個の要素が切り取られます。n が指定されていない場合は、start以降の配列全体がスライスされます (n = array.length - start`)。

let a = [5,4,3,2,1];
let chunk = a.splice(2,2);

// a     [5,4,3,2,1]
// start  0 1 2 - -
// n      - - 1 2 -

chunk; // [3,2]
a;     // [5,4,1]

Array.prototype.slice(start, end)

.slice()は非破壊で、startからendまでの指示されたインデックスを含む新しい配列を返します。end が指定されていない場合は、.splice() (end = array.length) と同じ動作になります。なぜかendは0ではなく1からインデックスを作成するので、この動作は少しトリッキーです。また、`end

解説 (22)