web-dev-qa-db-ja.com

JavaScriptオブジェクトからプロパティを削除する方法

次のようにオブジェクトを作成したとします。

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

次のように、プロパティregexを削除して新しいmyObjectにする最良の方法は何ですか?

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};
5509
johnstok

このような:

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 user kangax は、自分のブログのdeleteステートメントに関する信じられないほど詳細なブログ記事を書いています。deleteについてお勧めです。

7568
nickf

演算子deleteは予想外に遅いです!

ベンチマークを見てください。

削除は、残り物なしでオブジェクトのプロパティを削除する唯一の真の方法ですが、「代替」と比較して、100倍遅く〜動作しますobject[key] = undefined

この選択肢は、この質問に対する正しい答えではありません!ただし、注意して使用すると、一部のアルゴリズムを劇的に高速化できます。ループでdeleteを使用していて、パフォーマンスに問題がある場合は、詳細な説明を読んでください。

いつdeleteを使用し、値をundefinedに設定する必要がありますか?

オブジェクトは、キーと値のペアのセットとして見ることができます。 「値」と呼ぶものは、その「キー」に接続されたプリミティブまたは他のオブジェクトへの参照です。

制御できないコードに結果オブジェクトを渡す場合(または不明な場合)は、deleteを使用しますあなたのチームまたはあなた自身について)。

ハッシュマップからキーを削除します。

 var obj = {
     field: 1     
 };
 delete obj.field;

パフォーマンスを重視する場合は、undefinedの設定を使用します。コードを大幅に強化できます。

キーはhashmap内のその場所に残り、値のみがundefinedに置き換えられます。 for..inループはそのキーを繰り返し処理することを理解してください。

 var obj = {
     field: 1     
 };
 obj.field = undefined;

このメソッドを使用すると、すべての プロパティの存在を判断する方法 が期待どおりに機能するとは限りません。

ただし、このコード:

object.field === undefined

両方の方法で同等に動作します。

テスト

要約すると、違いはすべて、プロパティの存在を判断する方法とfor..inループに関するものです。

 console.log('* -> "Takes prototype inheritance into consideration, that means it lookups all over prototype chain too."');

 console.log(obj.field === undefined, 'obj.field === undefined', 'You get "undefined" value when querying for "field" in object-hashmap. *');

 console.log(obj["field"] === undefined, 'obj["field"] === undefined', 'Just another way to query (equivalent). *');

 console.log(typeof obj.field === "undefined", 'typeof obj.field === "undefined"', 'Get the value attached to "field" key, and check it\'s type is "undefined". *');

 console.log("field" in obj, '"field" in obj', 'This statement returns true if "field" key exists in the hashmap. False otherwise. *');

 console.log(obj.hasOwnProperty("field"), 'obj.hasOwnProperty("field")', 'This statement returns true if \'field\' key exists in the hashmap. The ONLY way NOT to lookup for property in the prototype chain!');
 //Object.keys().indexOf() is an overkill that runs much slower :)

 var counter = 0,
     key;
 for (key in obj) {
     counter++;
 }
 console.assert(counter === 0, 'counter === 0', '"field" is not iterated using "for .. in" loop. *');

メモリリークに注意してください!

obj[prop] = undefinedの使用はdelete obj[prop]の実行よりも高速ですが、別の重要な考慮事項は、obj[prop] = undefinedが常に適切であるとは限らないことです。 delete obj[prop]propobjから削除してメモリから消去しますが、obj[prop] = undefinedpropの値をundefinedに設定するだけでpropを残します_まだメモリ内にあります。したがって、多くのキーが作成および削除される状況では、obj[prop] = undefinedを使用すると、高価なメモリ調整(ページがフリーズする原因となる)が発生し、メモリ不足エラーが発生する可能性があります。次のコードを調べます。

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /*************************************************/
            /****/ nodeRecords[i][lastTime] = undefined; /****/
            /*************************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

上記のコードでは、nodeRecords[i][lastTime] = undefined;を実行するだけで、各アニメーションフレームで大量のメモリリークが発生します。各フレーム、すべての65536 DOM要素は、さらに65536個の個別のスロットを占有しますが、前の65536スロットは未定義に設定されるだけで、メモリにハングアップしたままになります。コンソールで上記のコードを実行してみて、自分で確認してください。メモリ不足エラーを強制した後、代わりにdelete演算子を使用する次のバージョンのコードを除き、エラーを再度実行してください。

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /********************************************/
            /****/ delete nodeRecords[i][lastTime]; /****/
            /********************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

上記のコードスニペットに見られるように、delete演算子にはまれな適切なユースケースがいくつかあります。ただし、この問題についてはあまり心配しないでください。これは、新しいキーが絶えず追加される長寿命オブジェクトでのみ問題になります。それ以外の場合(実際のプログラミングではほとんどすべての場合)、obj[prop] = undefinedを使用するのが最も適切です。このセクションの主な目的は、注意を喚起することです。これにより、コードで問題が発生する可能性が非常に低くなり、問題をより簡単に理解できるため、コードを詳しく調べるために時間を浪費する必要がなくなります。この問題を理解してください。

常にundefinedに設定しないでください

考慮すべき重要なJavascriptの1つの側面は、ポリモーフィズムです。多態性とは、以下に示すように、同じ変数/オブジェクト内のスロットに異なる型を割り当てる場合です。

var foo = "str";
foo = 100;          // variable foo is now labeled polymorphic by the browser
var bar = ["Some", "example"];
bar[2] = "text";    // bar is a monomorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = undefined; // bar is now a polymorphic array

ただし、ポリモーフィック配列には修正不可能な2つの大きな問題があります。

  1. それらは遅く、メモリ効率が悪いです。特定のインデックスにアクセスする場合、ブラウザは配列のグローバルタイプを取得する代わりに、インデックスごとにタイプを取得する必要があります。これにより、各インデックスはそのタイプの追加メタデータを保存します。
  2. ポリモーフィックになると、常にポリモーフィックになります。配列が多相になっている場合、Webkitブラウザーで多相を元に戻すことはできません。そのため、ポリモーフィック配列を非ポリモーフィックに復元した場合でも、ブラウザはポリモーフィック配列として保存します。

多型を麻薬中毒にたとえることができます。一見したところ、それはすばらしくluかるように見えます。すてきなふわふわしたコードです。次に、コーダーは配列を多型の薬物に導入します。即座に、ポリモーフィック配列の効率は低下し、ドラッグされるため、以前ほど効率的になることはありません。このような状況を現実の生活に関連付けるために、コカインを使用している人は単純なドアハンドルを操作することすらできず、PIの桁を計算することはできません。同様に、多型の薬物の配列は、単型配列ほど効率的ではありません。

しかし、薬物旅行の類推はどのようにdelete操作に関連していますか?答えは、上記のスニペットの最後のコード行です。したがって、今回はひねりを加えて再検討してみましょう。

var bar = ["Some", "example"];
bar[2] = "text";    // bar is not a polymorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = "";        // bar is still a monomorphic array
bar[1] = undefined; // bar is now a polymorphic array

観察する。 bar[1] = ""はポリモーフィズムを強制しませんが、bar[1] = undefinedは強制します。したがって、誤ってポリモーフィズムを引き起こさないように、可能な場合は常に、オブジェクトに対応する型を使用する必要があります。そのような人は、次のリストを一般的な参考資料として使用して、それらを実行することができます。ただし、以下のアイデアを明示的に使用しないでください。代わりに、コードに適したものを使用してください。

  • ブールプリミティブに型指定された配列/変数を使用する場合は、falseまたはundefinedを空の値として使用します。不要なポリモーフィズムを避けることは良いことですが、明示的に禁止するようにすべてのコードを書き換えると、実際にはパフォーマンスが低下する可能性があります。一般的な判断を使用してください!
  • 数値プリミティブに型指定された配列/変数を使用する場合は、0を空の値として使用します。内部的には、高速整数(2147483647〜-2147483648を含む)と低速浮動小数点の倍精度(NaNおよびInfinityを含むもの以外)の2種類の数値があることに注意してください。整数がdoubleに降格されると、整数に戻すことはできません。
  • 文字列プリミティブに型指定された配列/変数を使用する場合は、""を空の値として使用します。
  • シンボルを使用するとき、待って、なぜシンボルを使用するのですか?!?!シンボルはパフォーマンスにとって悪いジュジュです。シンボルを使用するようにプログラムされたものはすべて、シンボルを使用しないように再プログラムできるため、シンボルのない高速なコードになります。シンボルは本当に非常に非効率的なメタ糖です。
  • 他のものを使用する場合は、nullを使用します。

ただし、注意してください!このような既存のコードが壊れたり、奇妙なバグが発生したりする可能性があるため、既存のすべてのコードでこれを突然開始しないでください。むしろ、そのような効率的なプラクティスは最初から実装する必要があり、既存のコードを変換するときは、古いコードをこの新しいプラクティスにアップグレードしようとして、それに関連するすべての行を二重、三重、四重チェックすることをお勧めしますやりがいがあるので危険です。

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

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

これはFirefoxとInternet Explorerで機能しますが、他のすべてでも機能すると思います。

221
redsquare

pdate 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言語であるため、arraysを含むすべてがオブジェクトです。したがって、特定の注意事項を指摘する必要があると感じています。

配列では、単純な古いオブジェクトとは異なり、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[0]array[1]などになります)

正直なところ、nullではなくundefinedに設定することは別として、これは正当に奇妙なことです。この動作は、驚くべきことに、deletetypeofのような単項演算子であり、言語にハードボイルドされており、type使用されているオブジェクトのArrayは、特定の目的のために設計されたメソッドを持つObjectのサブクラスです配列の操作。したがって、deleteが配列を再シフトするための特別なケースを用意する理由はありません。これは、不必要な作業で物事を遅くするだけです。振り返ってみると、私の期待は非現実的でした。

もちろん、didびっくりしました。私がこれを書いたのは、「ヌルごみ」に対する私の十字軍を正当化するためです。

nullに固有の危険性と問題、および無駄になるスペースを無視すると、配列を正確にする必要がある場合、これは問題になる可能性があります。

これはnulls --nullを取り除くためのひどい正当化であり、不適切に使用された場合にのみ危険であり、「精度」とは関係ありません。配列からdeleteをすべきではない本当の理由は、不要なデータ構造を乱雑に残したままにしておくと、ずさんでバグが発生しやすいことです。

以下は、非常に長い時間を費やした不自然なシナリオです。したがって、必要に応じてThe Solutionのセクションにスキップできます。このセクションを去る唯一の理由は、おそらく面白いと思う人がいると思うからです。「面白い」答えを投稿し、後で「面白い」をすべて削除する「あの人」になりたくない。

...それは愚かだ、知っている。

工夫された長いPDP-11シナリオ

たとえば、JSONシリアル化を使用して、「タブ」に使用される配列を文字列(この場合はlocalStorage)に格納するwebappを作成するとします。また、コードが配列のメンバーの数値インデックスを使用して、画面に描画するときにそれらに「タイトル」を付けるとしましょう。 「タイトル」だけを保存するのではなく、なぜこれを行うのですか?なぜなら...理由.

さて、1960年代のUNIXを実行しているPDP-11ミニコンピューターを実行するこのoneユーザーの要求でメモリを節約しようとしているとしましょうX11は問題外であるため、独自のElinksベース、JavaScript準拠、ラインプリンター対応のブラウザーを作成しました。

ますます愚かなエッジケースシナリオを別にすれば、上記の配列でdeleteを使用すると、nullが配列を汚染し、後でアプリにバグを引き起こす可能性があります。そして、nullをチェックすると、数字をまっすぐスキップして、[1] [2] [4] [5] ...のようにタブがレンダリングされます。

if (array[index] == null)
    continue;
else
    title = (index + 1).toString();
/* 0 -> "1"
 * 1 -> "2"
 * 2 -> (nothing)
 * 3 -> "4"
 */

ええ、それは間違いなくあなたが望んだものではありません。

ここで、couldは、有効な値が配列から読み取られたときにのみ増分するように、jなどの2番目のイテレーターを保持します。しかし、それはnullの問題を正確に解決するものではありません。 トロル PDP-11ユーザー。悲しいかな、彼のコンピューターは、最後の整数を保持するのに十分なメモリを持っていません (可変幅配列をどのように処理するかを尋ねないでください...)

それで、彼はあなたに怒りのメールを送ります:

Hey, your webapp broke my browser! I checked my localStorage database after your stupid code made my browser segfault, and this is what I found:

>"tabs:['Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ... ]"

After clearing my precious data, it segfaulted again, and I did a backtrace, and what do I find? WHAT DO I FIND!? YOU USE TOO MANY VARIABLES!

>var i = index;
>var j = 1;

Grr, I am angry now.
-Troll Davidson

今、あなたは機知に富んでいます。この男はあなたのアプリについてノンストップで不平を言ってきました。

解決策:Array.prototype.splice

幸いなことに、配列doには、インデックスを削除してメモリを再割り当てするための特別なメソッド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)と同じです。何らかの理由で、0ではなく1からendインデックスが作成されるため、この動作は少し注意が必要です。これを行う理由はわかりませんが、そのようになっています。また、end <= startの場合、結果は空の配列になります。

let a = [5,4,3,2,1];
let chunks = [
    a.slice(2,0),
    a.slice(2,2),
    a.slice(2,3),
    a.slice(2,5) ];

// a             [5,4,3,2,1]
// start          0 1 2 - -
// end, for...    - - - - -
//   chunks[0]  0 - - - - -   
//   chunks[1]    1 2 - - -
//   chunks[2]    1 2 3 - -
//   chunks[3]    1 2 3 4 5

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

それは実際に起こっていることではありませんが、そのように考える方が簡単です。 MDNによると、実際に起こっていることは次のとおりです。

// a             [5,4,3,2,1]
// start          0 1 2 - - -
// end, for...    - - - - - -
//   chunks[0]    0 - - - - -
//   chunks[1]    0 1 2 - - -
//   chunks[2]    0 1(2)3 - -
//   chunks[3]    0 1(2 3 4)5

endで指定されたインデックスは、スライスから単に除外されます。括弧で囲まれたインデックスは、スライスされるものを示します。いずれにせよ、動作は直感的ではなく、オフバイワンエラーをかなりの割合で発生させるはずです。したがって、.splice()の動作をより厳密にエミュレートするラッパー関数を作成すると便利です。

function ez_slice(array, start = 0, n = null){
    if(!Array.isArray(array) || !is_number(start))
        return null;

    if(is_number(n))
        return array.slice(start, start + n);

    if(n === null)
        return array.slice(start);

    return null;
}

ez_slice([5,4,3,2,1], 2, 1) // [3]
ez_slice([5,4,3,2,1], 2)    // [3,2,1]

/* Fun fact: isNaN is unreliable.
 * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(isNaN)
 * [NaN, {}, undefined, "Hi"]
 *
 * What we want is...
 *
 * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(is_nan)
 * [NaN]
 */
function is_nan(num){
    return typeof num === "number"
        && num !== num;
}

function is_number(num){
    return !is_nan(num)
        && typeof num === "number"
        && isFinite(num);
}

ラッパー関数は型について非常に厳密になるように設計されており、何かがオフの場合はnullを返すことに注意してください。これには、"3"のような文字列を含めることが含まれます。彼の型について熱心に取り組むことはプログラマに任されています。これは、優れたプログラミングの実践を促進するためです。

is_array()に関する更新

これは、この(現在は削除された)スニペットに関するものです。

function is_array(array){
    return array !== null
        && typeof array === "object"
        && typeof array.length !== "undefined"
        && array.__proto__ === Array.prototype;
}

結局のところ、実際にはISが配列が本当に配列であるかどうかを知るための組み込み方法であり、それがECMAScript 5(2009年12月)で導入されたArray.isArray()です。私はこれを、オブジェクトから配列を伝えることについて質問するかどうか、私のものよりも良い解決策があるかどうか、またはない場合は追加するかどうかを調べているときに見つけました。そのため、ECMA 5より前のバージョンのJavaScriptを使用している場合、ポリフィルがあります。ただし、古いバージョンのJavaScriptを引き続きサポートすることは、それらを実装する古いブラウザーを引き続きサポートすることを意味するため、is_array()関数の使用を強くお勧めします。つまり、安全でないソフトウェアの使用を奨励し、ユーザーをマルウェアの危険にさらすことを意味しますしたがって、Array.isArray()を使用してください。 letおよびconstを使用します。言語に追加される新しい機能を使用します。 ベンダープレフィックスを使用しないでくださいあなたのウェブサイトからIEポリフィルがらくたを削除します。そのXHTML <!CDATA[[...がらくたも削除します。2014年にHTML5に移行しました。誰もが古い/難解なブラウザのサポートをすぐに廃止すると、ブラウザベンダーは実際にWeb標準に従い、新しいテクノロジを採用します。より早く、より安全なWebに移行できます。

190
Braden Best

昔の質問、現代の答え。オブジェクトの分解、 ECMAScript 6 機能を使うと、次のように簡単になります。

const { a, ...rest } = { a: 1, b: 2, c: 3 };

または質問サンプルでは:

const myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
const { regex, ...newObject } = myObject;
console.log(newObject);

Babelの試作エディタで実際に動作しているのを見ることができます。


編集:

同じ変数に再割り当てするには、letを使用します。

let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);
143
Koen.

別の方法は Underscore.js ライブラリを使用することです。

_.pick()_.omit()は両方ともオブジェクトのコピーを返し、元のオブジェクトを直接変更しないことに注意してください。オリジナルのオブジェクトに結果を代入することはトリックをするべきです(示されていない)。

参照: link _.pick(object、* keys)

ホワイトリストに登録されたキー(または有効なキーの配列)の値のみを持つようにフィルタ処理されたオブジェクトのコピーを返します。

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

_.pick(myJSONObject, "ircEvent", "method");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

参照: link _.omit(object、* keys)

ブラックリストに記載されているキー(またはキーの配列)を除外するようにフィルタリングされた、オブジェクトのコピーを返します。

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

_.omit(myJSONObject, "regex");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

配列の場合、_.filter()_.reject()を同じように使用できます。

87
Thaddeus Albers

スプレッド構文 (ES6)

必要な人には….

このスレッドで@Koenという答えを完成するには、スプレッド構文を使用して動的変数を削除したい場合は、次のようにします。

const key = 'a';

const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };

console.log(rest); // { b: 2, c: 3 }

* fooは、aの値(1)を持つ新しい変数になります。


UPDATE
オブジェクトからプロパティを削除する一般的な方法はほとんどありません。
それぞれ独自の長所と短所があります( このパフォーマンスの比較を確認してください )。

削除演算子
読みやすくて短いですが、パフォーマンスが最適化されていないため、多数のオブジェクトを操作している場合は最適な選択肢とは言えません。

delete obj[key];


再割り当て
deleteよりも2倍以上速いですが、このプロパティは ではなく 削除されているため、繰り返すことができます。

obj[key] = null;
obj[key] = false;
obj[key] = undefined;


Spread Operator
このES6演算子を使用すると、既存のオブジェクトを変更することなく、プロパティを除いてまったく新しいオブジェクトを返すことができます。欠点は、上記のうちパフォーマンスが悪いため、一度に多数のプロパティを削除する必要がある場合には使用しないことをお勧めします。

{ [key]: val, ...rest } = obj;
53
Lior Elrom

質問タイトルRemove a property from a JavaScript objectで使用した用語は、いくつかの異なる方法で解釈できます。 1つはメモリ全体とオブジェクトキーのリストを削除することで、もう1つはオブジェクトから削除することです。他の回答でも述べたように、キーワードdeleteが主要部分です。次のようなオブジェクトがあるとしましょう。

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

もしあなたがそうするなら:

console.log(Object.keys(myJSONObject));

結果は次のようになります。

["ircEvent", "method", "regex"]

次のようにオブジェクトキーからその特定のキーを削除できます。

delete myJSONObject["regex"];

Object.keys(myJSONObject)を使ったオブジェクトキーは次のようになります。

["ircEvent", "method"]

しかし、ポイントは、メモリを気にしていて、オブジェクト全体をメモリから削除したい場合は、キーを削除する前にnullに設定することをお勧めします。

myJSONObject["regex"] = null;
delete myJSONObject["regex"];

ここでもう1つ重要な点は、同じオブジェクトに対する他の参照に注意することです。たとえば、次のような変数を作成したとします。

var regex = myJSONObject["regex"];

あるいは、それを別のオブジェクトへの新しいポインタとして追加します。

var myOtherObject = {};
myOtherObject["regex"] = myJSONObject["regex"];

それであなたがそれをあなたのオブジェクトmyJSONObjectから取り除いたとしても、その特定のオブジェクトはメモリから削除されないでしょう。なぜならregex変数とmyOtherObject["regex"]はまだそれらの値を持っているからです。では、どうすれば確実にオブジェクトをメモリから削除できますか?

その答えは、自分のコードにあるすべての参照をそのobjectを参照して削除し、さらにobject_への新しい参照を作成するためにvar文を使用しないことです。 varステートメントに関する最後のポイントは、varステートメントを使用すると作成されたオブジェクトが削除されなくなるため、通常直面する最も重大な問題の1つです。

これは、この場合、regexステートメントを介してvar変数を作成したために、そのオブジェクトを削除できないことを意味します。

delete regex; //False

結果はfalseになります。これは、あなたのdelete文があなたの期待通りに実行されていないことを意味します。しかし、その変数を以前に作成したことがなく、最後の既存の参照としてmyOtherObject["regex"]しかない場合は、次のように削除することでこれを実行できます。

myOtherObject["regex"] = null;
delete myOtherObject["regex"];

つまり、JavaScriptオブジェクトは、そのオブジェクトを指すコード内に参照がなくなるとすぐに強制終了されます。


更新: @AgentMEに感謝します。

削除する前にプロパティをnullに設定しても何も達成されません(Object.sealによってオブジェクトが封印されていて削除に失敗した場合を除きます。通常はそうではありません)。

Object.sealの詳細情報を取得するには、 Object.seal() を使用してください。

45
Mehran Hatami

ECMAScript 2015(またはES6)には Reflect objectが組み込まれています。ターゲットオブジェクトとプロパティキーをパラメータにして Reflect.deleteProperty() functionを呼び出すことで、オブジェクトのプロパティを削除することができます。

Reflect.deleteProperty(myJSONObject, 'regex');

これは以下と同等です。

delete myJSONObject['regex'];

しかし、オブジェクトのプロパティが設定できない場合は、deleteProperty関数でもdelete演算子でも削除できません。

let obj = Object.freeze({ prop: "value" });
let success = Reflect.deleteProperty(obj, "prop");
console.log(success); // false
console.log(obj.prop); // value

Object.freeze() (他のものを除いて)オブジェクトのすべてのプロパティを設定不可能にする。 deleteProperty関数(および delete演算子 と同じ)は、そのいずれかのプロパティを削除しようとするとfalseを返します。 propertyが設定可能な場合は、propertyが存在しなくてもtrueを返します。

deletedeletePropertyの違いは、厳密モードを使用する場合です。

"use strict";

let obj = Object.freeze({ prop: "value" });
Reflect.deleteProperty(obj, "prop"); // false
delete obj["prop"];
// TypeError: property "prop" is non-configurable and can't be deleted
38
madox2

次のようなオブジェクトがあるとします。

var Hogwarts = {
    staff : [
        'Argus Filch',
        'Filius Flitwick',
        'Gilderoy Lockhart',
        'Minerva McGonagall',
        'Poppy Pomfrey',
        ...
    ],
    students : [
        'Hannah Abbott',
        'Katie Bell',
        'Susan Bones',
        'Terry Boot',
        'Lavender Brown',
        ...
    ]
};

オブジェクトプロパティの削除

staff配列全体を使用したい場合は、これを行う正しい方法は次のようになります。

delete Hogwarts.staff;

あるいは、これを行うこともできます。

delete Hogwarts['staff'];

同様に、Students配列全体を削除するには、delete Hogwarts.students;またはdelete Hogwarts['students'];を呼び出します。

配列インデックスの削除

1人のスタッフまたは学生を削除する場合、手順は少し異なります。両方のプロパティが配列そのものであるためです。

あなたがあなたのスタッフのインデックスを知っているなら、あなたは単にこれをすることができます:

Hogwarts.staff.splice(3, 1);

インデックスがわからない場合は、インデックス検索も行う必要があります。

Hogwarts.staff.splice(Hogwarts.staff.indexOf('Minerva McGonnagall') - 1, 1);

注意

技術的には配列にdeleteを使用できますが、それを使用すると、後でHogwarts.staff.lengthを呼び出すときに誤った結果が得られる可能性があります。つまり、deleteは要素を削除しますが、lengthプロパティの値は更新しません。 deleteを使うことはまたあなたのインデックス付けを台無しにするでしょう。

そのため、オブジェクトから値を削除するときは、常にオブジェクトのプロパティを扱うのか配列の値を扱うのかを最初に検討し、それに基づいて適切な戦略を選択してください。

これを試してみたい場合は、 this Fiddle を出発点として使用できます。

37
John Slegers

delete演算子 がそのための最善の方法です。

表示するライブの例:

var foo = {bar: 'bar'};
delete foo.bar;
console.log('bar' in foo); // Logs false, because bar was deleted from foo.
27
Tarun Nagpal

私は個人的に Underscore.js または Lodash をオブジェクトと配列の操作に使います。

myObject = _.omit(myObject, 'regex');
27
emil

delete methodを使用するのが最善の方法です。MDNの説明によると、delete演算子はオブジェクトからプロパティを削除します。だからあなたは単に書くことができます:

delete myObject.regex;
// OR
delete myObject['regex'];

Delete演算子は、与えられたプロパティをオブジェクトから削除します。正常に削除された場合はtrue、それ以外の場合はfalseが返されます。ただし、以下のシナリオを検討することが重要です。

  • 削除しようとしているプロパティが存在しない場合、deleteは効果がなく、trueを返します。

  • 同じ名前のプロパティがオブジェクトのプロトタイプチェーンに存在する場合、削除後、オブジェクトはプロトタイプチェーンのプロパティを使用します(つまり、deleteは自身のプロパティにのみ影響します)。

  • Varで宣言されたプロパティは、グローバルスコープまたは関数のスコープから削除できません。

  • そのため、deleteはグローバルスコープ内の関数を削除できません(これが関数定義の一部であるか関数(式)の一部であるかにかかわらず)。

  • オブジェクトの一部である関数
    グローバルスコープ)はdeleteで削除できます。

  • Letまたはconstで宣言されたプロパティは、定義されている範囲から削除することはできません。構成不可能なプロパティは削除できません。これには、Math、Array、Objectなどの組み込みオブジェクトのプロパティ、およびObject.defineProperty()などのメソッドを使用して構成不可能として作成されたプロパティが含まれます。

次のスニペットは別の簡単な例を示しています。

var Employee = {
      age: 28,
      name: 'Alireza',
      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

より多くの情報とより多くの例を見るために、以下のリンクを訪問してください:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete

22
Alireza

Array#reduceを使用したもう1つの解決策。

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

myObject = Object.keys(myObject).reduce(function(obj, key) {
  if (key != "regex") {           //key you want to remove
    obj[key] = myObject[key];
  }
  return obj;
}, {});

console.log(myObject);

しかし、元のオブジェクトはmutateされます。指定したキーで新しいオブジェクトwithoutを作成したい場合は、reduce関数を新しい変数に代入してください。

(ES6)

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

const myNewObject = Object.keys(myObject).reduce((obj, key) => {
  key !== 'regex' ? obj[key] = myObject[key] : null;
  return obj;
}, {});

console.log(myNewObject);
20
kind user

この記事は非常に古く、とても役に立ちましたので、他の誰かがこの記事を見た場合に備えて、私が書いた設定解除関数を共有し、PHP設定解除関数ほど単純ではない理由を考えます。

この新しいunset関数を書く理由は、このhash_mapの他のすべての変数のインデックスを保持するためです。次の例を見て、hash_mapから値を削除しても "test2"のインデックスが変わらないことを確認してください。

function unset(unsetKey, unsetArr, resort){
  var tempArr = unsetArr;
  var unsetArr = {};
  delete tempArr[unsetKey];
  if(resort){
    j = -1;
  }
  for(i in tempArr){
    if(typeof(tempArr[i]) !== 'undefined'){
      if(resort){
        j++;
      }else{
        j = i;
      }
      unsetArr[j] = tempArr[i];
    }
  }
  return unsetArr;
}

var unsetArr = ['test','deletedString','test2'];

console.log(unset('1',unsetArr,true)); // output Object {0: "test", 1: "test2"}
console.log(unset('1',unsetArr,false)); // output Object {0: "test", 2: "test2"}
19
talsibony

良い答えはたくさんありますが、JavaScriptでプロパティを削除するためにdeleteを使うときは、エラーを防ぐためにそのプロパティが存在するかどうかを最初に確認するのが賢明です。

例えば

var obj = {"property":"value", "property2":"value"};

if (obj && obj.hasOwnProperty("property2")) {
  delete obj.property2;
} else {
  //error handling
}

JavaScriptの動的な性質のため、プロパティが存在するかどうかがわからない場合がよくあります。 &&の前にobjが存在するかどうかをチェックすることで、未定義のオブジェクトに対してhasOwnProperty()関数を呼び出すことによるエラーをスローしないようにすることもできます。

これがあなたの特定のユースケースに追加されなかった場合は申し訳ありませんが、オブジェクトとそのプロパティを管理するときに適応するのに良い設計だと私は思います。

18
Willem

ramda#dissoc を使用すると、属性regexを持たない新しいオブジェクトが得られます。

const newObject = R.dissoc('regex', myObject);
// newObject !== myObject

他の関数を使用して同じ効果を得ることもできます - 省略、選択、...

14
Amio.io

次の方法を試してください。 Objectプロパティ値をundefinedに割り当てます。それからstringifyオブジェクトとparse

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

myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));

console.log(myObject);
13
Mohammed Safeer

ES6を使用する:

(デストラクチャリング+スプレッド演算子)

    const myObject = {
      regex: "^http://.*",
      b: 2,
      c: 3
    };
    const { regex, ...noRegex } = myObject;
    console.log(noRegex); // => { b: 2, c: 3 }
11
Srinivas

オブジェクト内で深くネストされたプロパティを削除したい場合は、2番目の引数としてプロパティへのパスを指定して次の再帰関数を使用できます。

var deepObjectRemove = function(obj, path_to_key){
    if(path_to_key.length === 1){
        delete obj[path_to_key[0]];
        return true;
    }else{
        if(obj[path_to_key[0]])
            return deepObjectRemove(obj[path_to_key[0]], path_to_key.slice(1));
        else
            return false;
    }
};

例:

var a = {
    level1:{
        level2:{
            level3: {
                level4: "yolo"
            }
        }
    }
};

deepObjectRemove(a, ["level1", "level2", "level3"]);
console.log(a);

//Prints {level1: {level2: {}}}
11
ayushgp

deleteキーワードを使用すると、オブジェクトの任意のプロパティを簡単に削除できます。

例えば:

var obj = {key1:"val1",key2:"val2",key3:"val3"}

key1と言うプロパティを削除するには、次のようにdeleteキーワードを使用します。

delete obj.key1

あるいは、配列風の表記法を使うこともできます。

delete obj[key1]

参照: _ mdn _

7
Kalpesh Patel

元のオブジェクトは常にプログラムの他の部分から参照される可能性があるため、"regex"プロパティを指定せずに新しいオブジェクトを作成することを検討してください。したがって、あなたはそれを操作することを避けるべきです。

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

const { regex, ...newMyObject } = myObject;

console.log(newMyObject);
6
ideaboxer

'削除'は非常に遅いというダンの主張と彼が発表したベンチマークは疑われていた。それで私はChrome 59で自分でテストを実行しました。それは '削除'が約30倍遅いようです:

var iterationsTotal = 10000000;  // 10 million
var o;
var t1 = Date.now(),t2;
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   delete o.a; delete o.b; delete o.c; delete o.d; delete o.e;
}
console.log ((t2=Date.now())-t1);  // 6135
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   o.a = o.b = o.c = o.d = o.e = undefined;
}
console.log (Date.now()-t2);  // 205

他の操作による影響を最小限に抑えるために、1つのループサイクルで複数の「削除」操作を意図的に実行したことに注意してください。

6
Chong Lip Phang

Object.assign()とObject.keys()およびArray.map()

const obj = {
    "Filters":[
        {
            "FilterType":"between",
            "Field":"BasicInformationRow.A0",
            "MaxValue":"2017-10-01",
            "MinValue":"2017-09-01",
            "Value":"Filters value"
        }
    ]
};

let new_obj1 = Object.assign({}, obj.Filters[0]);
let new_obj2 = Object.assign({}, obj.Filters[0]);

/*

// old version

let shaped_obj1 = Object.keys(new_obj1).map(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
        }
        return new_obj1;
    }
)[0];


let shaped_obj2 = Object.keys(new_obj2).map(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
        return new_obj2;
    }
)[0];


*/


// new version!

let shaped_obj1 = Object.keys(new_obj1).forEach(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
            default:
                break;
        }
    }
);

let shaped_obj2 = Object.keys(new_obj2).forEach(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
    }
);
6
xgqfrms-gildata
const myObject = {
        "ircEvent": "PRIVMSG",
        "method": "newURI",
        "regex": "^http://.*"
    };

const { regex, ...other } = myObject;

console.log(myObject)
console.log(regex)
console.log(other)
5
xiang

これを試して

delete myObject['key'];
5
codemirror

こんにちはあなたはこの単純なソートを試すことができます

var obj = [];

obj.key1 = {name: "John", room: 1234};
obj.key2 = {name: "Jim", room: 1234};

delete(obj.key1);
5
Dhaval Gohel

JavaScriptによるプロパティの削除

このページにはさまざまなオプションが表示されていますが、ほとんどのオプションが間違っているため、または答えが重複しているためではありません。適切な手法は現在の状況や自分や自分のタスクの目的によって異なります。チームは達成しようとしています。明確にあなたの質問に答えるために、人は知る必要があります:

  1. ターゲットにしているECMAScriptのバージョン
  2. プロパティを削除するオブジェクトの種類の範囲と省略できるプロパティの名前の種類(文字列のみ?記号?任意のオブジェクトからマッピングされた弱い参照?これらはすべてJavaScriptのプロパティポインタの種類です) )
  3. あなたとあなたのチームが使うプログラミングの精神/パターン。あなたは機能的なアプローチを好みますか、そして、あなたのチームでは突然変異は言葉で表現されていますか、それともあなたは野生の西の突然変異オブジェクト指向のテクニックを採用しますか?
  4. 純粋なJavaScriptでこれを実現しようとしていますか、それともサードパーティのライブラリを使用しても構わないと思いますか。

これら4つの質問に答えたら、あなたの目標を達成するために選ぶべきJavaScriptの「プロパティ除去」の4つのカテゴリーが本質的にあります。彼らです:

変異型オブジェクトプロパティの削除、危険

このカテゴリは、元の参照をそのまま使用し続け、コード内でステートレスな機能原則を使用していない場合に、オブジェクトリテラルまたはオブジェクトインスタンスを操作するためのものです。このカテゴリの構文の例

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
delete iLikeMutatingStuffDontI[Symbol.for('amICool')] // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
delete iLikeMutatingStuffDontI['amICool'] // throws

このカテゴリは、最も古く、最もわかりやすく、最も広くサポートされているプロパティの削除カテゴリです。文字列に加えてSymbol&array indexもサポートしており、最初のリリースを除くすべてのバージョンのJavaScriptで動作します。ただし、これは突然変異型であり、プログラミングの原則に違反しており、パフォーマンスに影響を及ぼします。厳密モードの 設定不可能なプロパティに対して使用すると、キャッチされない例外が発生する可能性があります

休符ベースの文字列プロパティの省略

このカテゴリは、非突然変異的なアプローチが望まれていて、Symbolキーを考慮する必要がないときに、新しいECMAScriptフレーバーのプレーンオブジェクトまたは配列インスタンスを操作するためのものです。

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

変異型オブジェクトプロパティの削除、安全

このカテゴリは、設定不可能なプロパティでスローされる例外から保護しながら、元の参照を保持または使用し続けたい場合に、オブジェクトリテラルまたはオブジェクトインスタンスを操作するためのものです。

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
Reflect.deleteProperty(iLikeMutatingStuffDontI, Symbol.for('amICool')) // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
Reflect.deleteProperty(iLikeMutatingStuffDontI, 'amICool') // false

さらに、インプレースでオブジェクトを変更することはステートレスではありませんが、Reflect.deletePropertyの機能的性質を使用して、部分的な適用およびdeleteステートメントでは不可能な他の機能的手法を実行できます。

構文ベースの文字列プロパティの省略

このカテゴリは、非突然変異的なアプローチが望まれていて、Symbolキーを考慮する必要がないときに、新しいECMAScriptフレーバーのプレーンオブジェクトまたは配列インスタンスを操作するためのものです。

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

図書館による財産の省略

このカテゴリは一般に、シンボルの計算と1つのステートメント内の複数のプロパティの省略を含め、より大きな機能の柔軟性を可能にします。

const o = require("lodash.omit")
const foo = { [Symbol.for('a')]: 'abc', b: 'b', c: 'c' }
const bar = o(foo, 'a') // "'a' undefined"
const baz = o(foo, [ Symbol.for('a'), 'b' ]) // Symbol supported, more than one prop at a time, "Symbol.for('a') undefined"
4
james_womack

Lodashを使う

import omit from 'lodash/omit';

const prevObject = {test: false, test2: true};
// Removes test2 key from previous object
const nextObject = omit(prevObject, 'test2');

Ramdaを使う

R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}
4
johndavedecano

ES6分解をrest演算子と一緒に使用できます。

destructuring rest演算子 と組み合わせて使用​​して、プロパティを削除できます。あなたの例では、正規表現は分解され(無視され)、残りのプロパティはrestとして返されます。

const noRegex = ({ regex, ...rest }) => rest;
const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

console.log(noRegex(myObjext)) //=> {  "ircEvent": "PRIVMSG","method": "newURI" }

あるいは、このようなプロパティを動的に除外することもできます。

const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};
const removeProperty = prop => ({ [prop]: _, ...rest }) => rest

const removeRegex = removeProperty('regex') //=> {  "ircEvent": "PRIVMSG","method":"newURI" }
const removeMethod = removeProperty('method') //=> {  "ircEvent": "PRIVMSG", "regex":"^http://.*" }
3
Bhargav Patel

@johnstock 、JavaScriptのプロトタイピングの概念を使用して、オブジェクトにメソッドを追加し、呼び出し元のオブジェクトで使用可能な渡されたキーをすべて削除することもできます。

上記の答えは大歓迎です。

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

// 1st and direct way 
delete myObject.regex;  // delete myObject["regex"]
console.log(myObject); // { ircEvent: 'PRIVMSG', method: 'newURI' }

 // 2 way -  by using the concept of JavaScript's prototyping concept
Object.prototype.removeFromObjectByKey = function(key) {
     // If key exists, remove it and return true
     if(this[key] !== undefined) {
           delete this[key]
           return true;
     }
     // Else return false
     return false;
}

var isRemoved = myObject.removeFromObjectByKey('method')
console.log(myObject)  // { ircEvent: 'PRIVMSG' }

// More examples
var obj = { a: 45, b: 56, c: 67}
console.log(obj) // { a: 45, b: 56, c: 67 }

// Remove key 'a' from obj
isRemoved = obj.removeFromObjectByKey('a')
console.log(isRemoved); //true
console.log(obj); // { b: 56, c: 67 }

// Remove key 'd' from obj which doesn't exist
var isRemoved = obj.removeFromObjectByKey('d')
console.log(isRemoved); // false
console.log(obj); // { b: 56, c: 67 }
3
hygull

とても簡単

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

delete myObject.regex;
2

以下のようにdelete演算子を使うことができます。

 var multiverse = {
        earth1: "Silver Age",
        earth2: "Golden Age"
    };

delete multiverse.earth2;//will return true if it finds 

// Outputs: { earth1: "Silver Age" }
console.log(multiverse);

Delete演算子にはreturn value.もあります。プロパティの削除に成功した場合、trueが返されます。プロパティが書き込み不可であるためにプロパティの削除に失敗した場合はreturn falseになります。厳密モードの場合はエラーをスローします。

1
MANISH MOHAN

すでに多くの人が言っているように、 "delete"(javascriptプロパティ)または "unset"(lodashを使用)のどちらかを使用できます。

また、lodashプロパティ "pick"を使用して必要なオブジェクトプロパティのみを選択することもできます。オブジェクトから複数のプロパティを削除するときに役立ちます。

下記のように使用方法:

var _   = require("lodash");
var obj = {"a":1, "b":2, "c":3};
obj = _.pick(obj,["a","b"]);    
//Now obj contains only 2 props {"a":1, "b":2}
1
Mythili

lodash "unset" をネストされたオブジェクトに対しても行うために使用しています。これは、省略メソッドで期待されるプロパティキーのパスを取得するための小さなロジックを書く必要があるだけです。

  1. プロパティパスを配列として返すメソッド
var a = {"bool":{"must":[{"range":{"price_index.final_price":{"gt":"450","lt":"500"}}},{"bool":{"should":[{"term":{"color_value.keyword":"Black"}}]}}]}};

function getPathOfKey(object,key,currentPath, t){
     var currentPath = currentPath || [];

    for(var i in object){
                if(i == key){
        t = currentPath;
      }
      else if(typeof object[i] == "object"){
        currentPath.Push(i)
       return getPathOfKey(object[i], key,currentPath)
      }
    }
        t.Push(key);
    return t;
}
document.getElementById("output").innerHTML =JSON.stringify(getPathOfKey(a,"price_index.final_price"))
<div id="output"> 

</div>
  1. その後、 lodash unset methodオブジェクトからプロパティを削除します。
var unset = require('lodash.unset');
unset(a,getPathOfKey(a,"price_index.final_price"));
1
function removeProperty(obj, prop) {
    if(prop in obj){

    Reflect.deleteProperty(obj, prop);
    return true;
   } else {
    return false;
  }
}
1
diayn geogiev

For

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

myObject ["regex"];を削除します。また、Egのキーのインデックスも知っています。あなたはそれから2nd key(regex)を削除する必要があります。

var key =  Object.keys(myObject)[2]
delete myObject[key];

オブジェクト内のインデックスベースの削除が必要になることが多いです

1
RITESH ARORA

プロパティなしでオブジェクトを複製するには:

例えば:

let object = { a: 1, b: 2, c: 3 };   

そして 'a'を削除する必要があります。

1.明示的なpropキーを使って:

const { a, ...rest } = object;
object = rest;

2.可変支柱キー付き:

const propKey = 'a';
const { [propKey]: propValue, ...rest } = object;
object = rest;

3.クールアロー機能

const removePropery = (propKey, { [propKey]: propValue, ...rest }) => rest;

object = removePropery('a', object);
0
YairTawil