Bagaimana cara menghapus properti dari objek JavaScript?

6142

Katakanlah saya membuat objek sebagai berikut:

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

Apa cara terbaik untuk menghapus properti regexagar berakhir dengan yang baru myObjectsebagai berikut?

let myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};
Johnstok
sumber
@EscapeNetscape Ini adalah pertanyaan tentang perilaku, jadi tolok ukur menggambarkan gambar yang salah. Tentu saja deleteakan menjadi pilihan paling lambat karena ini merupakan operasi yang sebenarnya daripada dua lainnya yang hanya tugas sederhana. Tetapi inti masalahnya adalah bahwa menempatkan properti ke nullatau undefinedtidak benar-benar menghapus properti dari objek, tetapi sebaliknya menetapkan properti itu sama dengan nilai konstan tertentu. (Jawaban di bawah ini memberikan alasan mengapa ini merupakan perbedaan yang signifikan.)
Abion47

Jawaban:

8307

Seperti ini:

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

Demo

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

console.log(myObject);

Bagi siapa pun yang tertarik untuk membaca lebih lanjut tentang hal itu, kangax pengguna Stack Overflow telah menulis posting blog yang sangat mendalam tentang deletepernyataan di blog mereka, Memahami hapus . Sangat direkomendasikan.

nickf
sumber
47
Dicentang, ini juga berfungsi dengan "delete myJSONObject ['regex'];" Lihat: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
johnstok
110
Hasil dari salah satu pengamatan di tautan "memahami penghapusan" di atas, adalah bahwa, karena Anda tidak dapat serta-merta menghapus suatu variabel, tetapi hanya properti objek, karenanya Anda tidak dapat menghapus properti objek "dengan referensi" - var value = obj [ 'menopang']; hapus nilai // tidak berfungsi
Dexygen
27
Jadi sebenarnya tidak menghapusnya? Itu hanya menjadi tidak terdefinisi, tetapi kuncinya masih ada? Apakah saya melewatkan sesuatu?
Doug Molineux
152
@ Jangan, tidak menghapusnya. Diberikan: var x = {a : 'A', b : 'B'};Bandingkan: delete x.a; typeof x.a; /* "undefined" */ x.hasOwnProperty('a'); /* false */kex.b = undefined; typeof x.b; /* "undefined" */; x.hasOwnProperty('b'); /* true */
nickf
16
@ChristopherPfohl bekerja untuk saya. Seperti yang saya katakan, ini sebenarnya cukup mendalam, jadi agak sulit untuk merangkumnya. Respons dasar dalam jawaban di atas cukup untuk hampir semua kasus, blog masuk ke beberapa kasus tepi dan alasan kasus tersebut ada.
nickf
953

Objek dalam JavaScript dapat dianggap sebagai peta antara kunci dan nilai. The deleteoperator yang digunakan untuk menghapus kunci ini, lebih dikenal sebagai properti obyek, satu per satu.

var obj = {
  myProperty: 1    
}
console.log(obj.hasOwnProperty('myProperty')) // true
delete obj.myProperty
console.log(obj.hasOwnProperty('myProperty')) // false

The deleteOperator tidak langsung memori bebas, dan hal itu berbeda dari hanya menetapkan nilai dari nullatau undefinedke properti, dalam bahwa properti itu sendiri akan dihapus dari objek. Perhatikan bahwa jika nilai properti yang dihapus adalah tipe referensi (objek), dan bagian lain dari program Anda masih memegang referensi ke objek itu, maka objek itu, tentu saja, tidak akan menjadi sampah yang dikumpulkan sampai semua referensi ke sana memiliki lenyap.

delete hanya akan bekerja pada properti yang deskriptor menandainya sebagai dapat dikonfigurasi.

Dan
sumber
43
properti yang ditugaskan ke undefined masih merupakan properti objek, sehingga tidak akan dihapus oleh GC, kecuali salah membaca paragraf terakhir Anda.
Lance
8
Saya salah menyentuh tema GC di sini. Kedua metode memiliki hasil yang sama untuk GC: mereka menghapus nilai yang dikaitkan dengan kunci. Jika nilai itu adalah referensi terakhir ke beberapa objek lain, objek itu akan dibersihkan.
Dan
15
properti yang ditugaskan ke undefined masih merupakan properti objek, sehingga tidak akan dihapus oleh GC GC tidak mengelola apa pun tentang properti. Ia mengumpulkan dan menghapus nilai. Selama tidak ada referensi nilai (objek, string, dll) lagi, GC tidak menghapusnya dari memori.
Meandre
8
BTW, itu adalah masalah ganda untuk memeriksa apakah ada properti pada objek Javascript. Menggunakan di operator adalah terpercaya tetapi lambat. Periksa apakah properti itu tidak ditentukan "bukan jawaban yang benar" tetapi itu adalah cara yang lebih cepat. check
rdllopes
8
Apakah jawaban ini masih relevan? jsperf saat ini sedang turun, tetapi tolok ukur ini tampaknya menunjukkan bahwa perbedaan kecepatan adalah hanya 25%, yang mana jauh dari "~ 100 kali lebih lambat" dalam jawaban ini.
Cerbrus
248

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

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

Ini berfungsi di Firefox dan Internet Explorer, dan saya pikir itu berfungsi di semua yang lain.

kotak merah
sumber
216

The deleteoperator yang digunakan untuk menghapus sifat dari benda-benda.

const obj = { foo: "bar" }
delete obj.foo
obj.hasOwnProperty("foo") // false

Perhatikan bahwa, untuk array, ini tidak sama dengan menghapus elemen . Untuk menghapus elemen dari array, gunakan Array#spliceatau Array#pop. Sebagai contoh:

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

Detail

deletedalam JavaScript memiliki fungsi yang berbeda dengan kata kunci dalam C dan C ++: tidak secara langsung membebaskan memori. Sebaliknya, tujuan utamanya adalah untuk menghapus properti dari objek.

Untuk array, menghapus properti yang berkaitan dengan indeks, membuat array jarang (mis. Array dengan "lubang" di dalamnya). Sebagian besar browser menyatakan indeks array yang hilang ini sebagai "kosong".

var array = [0, 1, 2, 3]
delete array[2] // [0, 1, empty, 3]

Perhatikan bahwa deletetidak pindah array[3]ke array[2].

Fungsi bawaan yang berbeda di JavaScript menangani array jarang.

  • for...in akan melewatkan indeks kosong sepenuhnya.

  • forLoop tradisional akan kembali undefineduntuk nilai pada indeks.

  • Setiap metode yang menggunakan Symbol.iteratorakan mengembalikan undefinednilai pada indeks.

  • forEach, mapdan reducehanya akan melewatkan indeks yang hilang.

Jadi, deleteoperator tidak boleh digunakan untuk kasus umum menghapus elemen dari array. Array memiliki metode khusus untuk menghapus elemen dan mengalokasikan kembali memori: Array#splice()dan Array#pop.

Array # splice (mulai [, deleteCount [, item1 [, item2 [, ...]]]])

Array#splicebermutasi array, dan mengembalikan indeks yang dihapus. deleteCountelemen dihapus dari indeks start, dan item1, item2... itemNdimasukkan ke dalam array dari indeks start. Jika deleteCountdihilangkan maka elemen dari startIndex dihapus ke akhir array.

let a = [0,1,2,3,4]
a.splice(2,2) // returns the removed elements [2,3]
// ...and `a` is now [0,1,4]

Ada juga bernama sama, tetapi berbeda, fungsi pada Array.prototype: Array#slice.

Array # slice ([begin [, end]])

Array#slicetidak merusak, dan mengembalikan array baru yang berisi indeks yang ditunjukkan dari startke end. Jika enddibiarkan tidak ditentukan, defaultnya ke akhir array. Jika endpositif, ini menentukan indeks non-inklusif berbasis nol untuk berhenti. Jika endnegatif, itu menentukan indeks untuk berhenti dengan menghitung kembali dari akhir array (mis. -1 akan menghilangkan indeks akhir). Jika end <= start, hasilnya adalah array kosong.

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

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

Array # pop

Array#popmenghapus elemen terakhir dari array, dan mengembalikan elemen itu. Operasi ini mengubah panjang array.

Braden Best
sumber
12
Pendekatan ini tidak mengubah objek asli yang mungkin masih dirujuk di tempat lain. Ini mungkin atau mungkin tidak menjadi masalah tergantung pada bagaimana digunakan tetapi itu sesuatu yang perlu diingat.
Tamas Czinege
19
@ B1KMusic Ini cara untuk menghapus elemen dari Array: splice
wulftone
3
@wulftone nggak, yang membagi array dan tidak melakukan apa pun untuk menghapus nilai. Saya benar-benar berpikir cara terbaik untuk menghapus dari array di mana nilai-nilai spesifik yang perlu dihapus adalah menggunakan deletedan membuat fungsi Pengumpulan Sampah untuk membersihkannya.
Braden Best
5
Saya tidak melihat splicedalam suntingan Anda, tetapi removeseharusnyaArray.prototype.remove = function(index) { this.splice(index, 1); };
Ry-
1
Artikel ini penuh dengan banteng 1. Tidak membahas Pertanyaan! 2. Ini adalah contoh penyalahgunaan bahasa dan keluhan bahwa "itu tidak berhasil!" 3. Jangan salahkan operator penghapusan JavaScript untuk kesalahan istimewa Crockford tentang menempatkan null untuk indeks array kosong. Dia tidak mengerti arti dari nol - dia pikir itu kesalahan. Kesalahannya adalah miliknya sendiri dan sendirian - tidak ada nol dalam nilai yang dihapus dari indeks array yang diberikan. Tidak ada "lubang" dalam array - itu indeks kosong. Benar-benar sah dan diharapkan.
Bekim Bacaj
195

Pertanyaan lama, jawaban modern. Menggunakan objek destructive, fitur ECMAScript 6 , sesederhana:

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

Atau dengan sampel pertanyaan:

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

Anda dapat melihatnya beraksi di editor uji coba Babel.


Edit:

Untuk menetapkan kembali ke variabel yang sama, gunakan let:

let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);
Koen.
sumber
6
Mungkin karena tujuannya adalah untuk menghapus properti dari objek, bukan untuk membuat yang baru tanpa properti ... meskipun, solusi Anda adalah favorit saya, karena saya lebih suka cara yang tidak berubah.
Vingt_centimes
8
Pertanyaannya menyatakan "berakhir dengan myObject baru ".
Koen.
1
Menambahkan Menggarisbawahi untuk menghapus properti kehendak sampah proyek Anda :) Daripada harus tersedia sebagai regexAnda juga bisa menetapkan ke variabel lain, misalnya _, apa yang digunakan dalam bahasa seperti Go untuk membuang hasilnya: const { regex: _, ...newObject } = myObject;.
Koen.
2
@PranayKumar Saya berharap sintaks ini akan bekerja; const { [key], ...newObject } = myObject;tetapi tidak, jadi saya tidak berpikir itu mungkin dengan merusak.
Koen.
2
Dengan objek freeze()'d dan seal()' d, Anda tidak bisa hanya deleteproperti. Jadi ini adalah alternatif yang bagus. Meskipun dalam kebanyakan kasus, mungkin tidak masuk akal untuk menghapus properti dari objek yang dibekukan / disegel, mengingat seluruh intinya adalah untuk membuat jaminan tertentu tentang struktur data Anda, yang pola ini akan merusak. Untuk kasus-kasus di mana Anda perlu secara non-destruktif menipu objek tetapi tanpa beberapa propertinya, ini sempurna
Braden Best
119

Sintaks Penyebaran (ES6)

Untuk siapa pun yang membutuhkannya ...

Untuk menyelesaikan @Koen jawaban di utas ini, jika Anda ingin menghapus variabel dinamis menggunakan sintaksis spread, Anda dapat melakukannya seperti:

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

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

* fooakan menjadi variabel baru dengan nilai a(yaitu 1).


JAWABAN YANG DIPERPANJANG 😇
Ada beberapa cara umum untuk menghapus properti dari objek.
Masing-masing memiliki kelebihan dan kekurangannya sendiri ( periksa perbandingan kinerja ini ):

Hapus Operator
Dapat dibaca dan pendek, namun, itu mungkin bukan pilihan terbaik jika Anda beroperasi pada sejumlah besar objek karena kinerjanya tidak dioptimalkan.

delete obj[key];


Penugasan Kembali
Lebih dari 2X lebih cepat daridelete, namun propertitidakdihapus dan dapat diulang.

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


Penyebar Operator Operator
iniES6memungkinkan kami untuk mengembalikan objek baru, tidak termasuk properti apa pun, tanpa mengubah objek yang ada. The downside adalah bahwa ia memiliki kinerja yang lebih buruk di atas dan tidak disarankan untuk digunakan ketika Anda harus menghapus banyak properti sekaligus.

{ [key]: val, ...rest } = obj;
Lior Elrom
sumber
2
Saya pikir sintaks spread / rest untuk literal objek hanya termasuk dalam ES2018 (ES9), bukan ES6, meskipun beberapa mesin JS sudah mengimplementasikannya.
trincot
2
@trincot Pertama kali diperkenalkan pada tahun 2014 ( github.com/tc39/proposal-object-rest-spread ) dan ini adalah fitur ES6 (ECMAScript 2015 alias ECMAScript 6th Edition). Namun, bahkan jika saya salah, saya tidak berpikir itu membuat perbedaan untuk konteks jawaban.
Lior Elrom
2
Tautan mengacu pada ES6 di mana memang sintaks penyebaran diperkenalkan untuk array, tetapi kemudian terus mengusulkan sesuatu yang serupa untuk objek literal. Bagian kedua itu hanya tergabung dalam ES9 jika saya tidak salah.
trincot
98

Alternatif lain adalah dengan menggunakan perpustakaan Underscore.js .

Perhatikan bahwa _.pick()dan _.omit()keduanya mengembalikan salinan objek dan tidak secara langsung memodifikasi objek asli. Menugaskan hasil ke objek asli harus melakukan trik (tidak ditampilkan).

Referensi: tautan _.pick (objek, * kunci)

Kembali salinan objek, difilter untuk hanya memiliki nilai untuk kunci yang masuk daftar putih (atau array kunci yang valid).

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

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

Referensi: tautan _.omit (objek, * kunci)

Kembalikan salinan objek, disaring untuk menghilangkan kunci daftar hitam (atau array kunci).

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

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

Untuk array, _.filter()dan _.reject()dapat digunakan dengan cara yang sama.

Thaddeus Albers
sumber
4
Ingatlah bahwa jika kunci objek Anda berupa angka, Anda mungkin perlu_.omit(collection, key.toString())
Jordan Arseno
Hmmmmm .... Garis bawah adalah ~ 100x lebih lambat dari delete obj[prop]~ 100x lebih lambat dari obj[prop] = undefined.
Jack Giffin
52

Istilah yang Anda gunakan dalam judul pertanyaan Anda Remove a property from a JavaScript object, dapat diartikan dengan beberapa cara berbeda. Yang satu adalah menghapusnya untuk seluruh memori dan daftar kunci objek atau yang lain hanya untuk menghapusnya dari objek Anda. Seperti yang telah disebutkan dalam beberapa jawaban lain, deletekata kunci adalah bagian utama. Katakanlah Anda memiliki objek seperti:

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

Jika kamu melakukan:

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

hasilnya adalah:

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

Anda dapat menghapus kunci spesifik itu dari kunci objek Anda seperti:

delete myJSONObject["regex"];

Maka kunci obyek yang Anda gunakan Object.keys(myJSONObject)adalah:

["ircEvent", "method"]

Tetapi intinya adalah jika Anda peduli dengan memori dan Anda ingin seluruh objek dihapus dari memori, disarankan untuk mengaturnya menjadi nol sebelum Anda menghapus kunci:

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

Poin penting lainnya di sini adalah berhati-hati tentang referensi Anda yang lain ke objek yang sama. Misalnya, jika Anda membuat variabel seperti:

var regex = myJSONObject["regex"];

Atau tambahkan sebagai pointer baru ke objek lain seperti:

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

Kemudian bahkan jika Anda menghapusnya dari objek Anda myJSONObject, objek tertentu itu tidak akan dihapus dari memori, karena regexvariabel dan myOtherObject["regex"]masih memiliki nilainya. Lalu bagaimana kita bisa menghapus objek dari memori?

Jawabannya adalah untuk menghapus semua referensi yang Anda miliki dalam kode Anda, menunjuk ke objek itu dan juga tidak menggunakan varpernyataan untuk membuat referensi baru ke objek itu . Poin terakhir tentang varpernyataan ini, adalah salah satu masalah paling krusial yang biasanya kita hadapi, karena menggunakan varpernyataan akan mencegah objek yang dibuat agar tidak dihapus.

Yang berarti dalam hal ini Anda tidak akan dapat menghapus objek itu karena Anda telah membuat regexvariabel melalui varpernyataan, dan jika Anda melakukannya:

delete regex; //False

Hasilnya adalah false, yang berarti bahwa pernyataan penghapusan Anda belum dieksekusi seperti yang Anda harapkan. Tetapi jika Anda belum membuat variabel itu sebelumnya, dan Anda hanya memiliki myOtherObject["regex"]referensi terakhir yang ada, Anda bisa melakukan ini hanya dengan menghapusnya seperti:

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

Dengan kata lain, objek JavaScript terbunuh segera setelah tidak ada referensi tersisa di kode Anda yang menunjuk ke objek itu.


Pembaruan: Terima kasih kepada @ AgentME:

Menyetel properti menjadi nol sebelum menghapusnya tidak menghasilkan apa-apa (kecuali objek telah disegel oleh Object.seal dan penghapusannya gagal. Itu biasanya tidak terjadi kecuali Anda secara khusus mencoba).

Untuk mendapatkan info lebih lanjut tentang Object.seal: Object.seal ()

Mehran Hatami
sumber
Anda salah - hanya objek yang dilewatkan dengan referensi dalam JavaScript, jadi jika myJSONObject.regexnilai adalah string dan Anda menetapkannya ke beberapa objek lain, objek lain memiliki salinan nilai ini.
Michał Perłakowski
Anda benar dan ini kutipan: "untuk berhati-hati dengan referensi Anda yang lain untuk objek yang sama."
Mehran Hatami
43

ECMAScript 2015 (atau ES6) hadir dengan objek Reflect bawaan . Dimungkinkan untuk menghapus properti objek dengan memanggil fungsi Reflect.deleteProperty () dengan objek target dan kunci properti sebagai parameter:

Reflect.deleteProperty(myJSONObject, 'regex');

yang setara dengan:

delete myJSONObject['regex'];

Tetapi jika properti objek tidak dapat dikonfigurasi itu tidak dapat dihapus baik dengan fungsi deleteProperty maupun operator hapus:

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

Object.freeze () membuat semua properti objek tidak dapat dikonfigurasi (selain hal-hal lain). deletePropertyfungsi (serta menghapus operator ) kembali falseketika mencoba untuk menghapus salah satu propertinya. Jika properti dapat dikonfigurasi, ia kembali true, bahkan jika properti tidak ada.

Perbedaan antara deletedan deletePropertysaat menggunakan mode ketat:

"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
madox2
sumber
1
@ Gotdo memiliki lebih banyak manfaat, terutama ketika Anda perlu melakukan beberapa hal fungsional. Misalnya Anda dapat menetapkan fungsi untuk variabel, lulus sebagai argumen atau penggunaan apply, call, bindfungsi ...
madox2
41

Misalkan Anda memiliki objek yang terlihat seperti ini:

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

Menghapus properti objek

Jika Anda ingin menggunakan seluruh staffarray, cara yang tepat untuk melakukan ini, adalah dengan melakukan ini:

delete Hogwarts.staff;

Atau, Anda juga bisa melakukan ini:

delete Hogwarts['staff'];

Demikian pula, menghapus seluruh susunan siswa akan dilakukan dengan memanggil delete Hogwarts.students;atau delete Hogwarts['students'];.

Menghapus indeks array

Sekarang, jika Anda ingin menghapus satu anggota staf atau siswa, prosedurnya sedikit berbeda, karena kedua properti adalah array itu sendiri.

Jika Anda mengetahui indeks anggota staf Anda, Anda bisa melakukan ini:

Hogwarts.staff.splice(3, 1);

Jika Anda tidak tahu indeksnya, Anda juga harus melakukan pencarian indeks:

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

Catatan

Meskipun secara teknis Anda dapat menggunakan deleteuntuk array, menggunakannya akan menghasilkan hasil yang salah ketika memanggil misalnya Hogwarts.staff.lengthnanti. Dengan kata lain, deleteakan menghapus elemen, tetapi tidak akan memperbarui nilai lengthproperti. Menggunakan deletejuga akan mengacaukan pengindeksan Anda.

Jadi, saat menghapus nilai dari suatu objek, selalu pertimbangkan dulu apakah Anda berurusan dengan properti objek atau apakah Anda berurusan dengan nilai array, dan pilih strategi yang tepat berdasarkan itu.

Jika Anda ingin bereksperimen dengan ini, Anda dapat menggunakan Fiddle ini sebagai titik awal.

John Slegers
sumber
Saya pikir Anda harus selalu menggunakan splicearray bukan delete.
Joel Trauger
@ JoelTrauger: Itulah yang saya katakan ;-)
John Slegers
Iya. Komentar saya adalah bahwa itu deleteseharusnya tidak boleh apa-apa. Inilah yang splicedicari OP.
Joel Trauger
1
@ JoelTrauger: Ketika saya mencoba menjelaskan, deleteharus digunakan untuk properti objek dan spliceelemen array.
John Slegers
Sambungan sangat lambat. Meskipun harus digunakan alih-alih deletepada array, akan lebih bijaksana untuk tidak membuat kode yang berpusat di sekitarnya sama sekali.
Jack Giffin
39

Menggunakan ES6:

(Destrukturisasi + operator Spread)

const myObject = {
    regex: "^http://.*",
    b: 2,
    c: 3
};
const { regex, ...noRegex } = myObject;
console.log(noRegex); // => { b: 2, c: 3 }
Srinivas
sumber
Saya tidak berpikir ini adalah fitur ES6, tetapi yang hanya termasuk dalam ES9.
trincot
Jadi sebenarnya Anda tidak menggunakan ES6, seperti yang Anda tulis, tetapi ES9 ... ;-)
trincot
2
Ini tidak menghapus properti dari objek tetapi membuat objek baru tanpa properti itu.
Jordi Nebot
32

Saya pribadi menggunakan Underscore.js atau Lodash untuk manipulasi objek dan array:

myObject = _.omit(myObject, 'regex');
Emil
sumber
31

The Operator delete adalah cara terbaik untuk melakukannya.

Contoh langsung untuk ditampilkan:

var foo = {bar: 'bar'};
delete foo.bar;
console.log('bar' in foo); // Logs false, because bar was deleted from foo.
Tarun Nagpal
sumber
Mungkin perlu dicatat bahwa meskipun menggunakan deleteoperator itu sehat dalam hal pengumpulan sampah , bisa tiba - tiba lambat , tidak sedikit untuk alasan yang sama.
John Weisz
29

Untuk mengkloning objek tanpa properti:

Sebagai contoh:

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

Dan kita perlu menghapus 'a'.

1. Dengan kunci prop eksplisit:

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

2. Dengan kunci prop variabel:

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

3.Fungsi panah dingin 😎:

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

object = removePropery('a', object);

4. Untuk beberapa properti

const removeProperties = (object, ...keys) => Object.entries(object).reduce((prev, [key, value]) => ({...prev, ...(!keys.includes(key) && { [key]: value }) }), {})

Pemakaian

object = removeProperties(object, 'a', 'b') // result => { c: 3 }

Atau

    const propsToRemove = ['a', 'b']
    object = removeProperties(object, ...propsToRemove) // result => { c: 3 }
YairTawil
sumber
1
Fungsi panah apik!
JSilv
27

Menggunakan metode delete adalah cara terbaik untuk melakukan itu, sesuai deskripsi MDN, operator delete menghapus properti dari objek. Jadi Anda cukup menulis:

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

Operator hapus menghapus properti yang diberikan dari objek. Pada penghapusan yang sukses, itu akan mengembalikan true, jika tidak false akan dikembalikan. Namun, penting untuk mempertimbangkan skenario berikut:

  • Jika properti yang Anda coba hapus tidak ada, hapus tidak akan berpengaruh apa pun dan akan mengembalikan true

  • Jika properti dengan nama yang sama ada di rantai prototipe objek, maka, setelah penghapusan, objek akan menggunakan properti dari rantai prototipe (dengan kata lain, delete hanya berpengaruh pada properti sendiri).

  • Properti apa pun yang dideklarasikan dengan var tidak dapat dihapus dari lingkup global atau dari lingkup fungsi.

  • Dengan demikian, hapus tidak dapat menghapus fungsi apa pun dalam lingkup global (apakah ini merupakan bagian dari definisi fungsi atau fungsi (ekspresi).

  • Fungsi yang merupakan bagian dari objek (terlepas dari
    lingkup global) dapat dihapus dengan menghapus.

  • Setiap properti yang dideklarasikan dengan membiarkan atau const tidak dapat dihapus dari ruang lingkup di mana mereka didefinisikan. Properti yang tidak dapat dikonfigurasi tidak dapat dihapus. Ini termasuk properti dari objek bawaan seperti Math, Array, Object dan properti yang dibuat sebagai tidak dapat dikonfigurasi dengan metode seperti Object.defineProperty ().

Cuplikan berikut memberikan contoh sederhana lain:

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

Untuk info lebih lanjut tentang dan melihat lebih banyak contoh, kunjungi tautan di bawah:

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

Alireza
sumber
22

Solusi lain, menggunakan Array#reduce.

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);

Namun, itu akan bermutasi objek asli. Jika Anda ingin membuat objek baru tanpa kunci yang ditentukan, cukup tetapkan fungsi pengurangan ke variabel baru, misalnya:

(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);

pengguna yang baik
sumber
21

Posting ini sangat lama dan saya merasa sangat membantu jadi saya memutuskan untuk berbagi fungsi tidak disetel yang saya tulis seandainya ada orang lain yang melihat posting ini dan berpikir mengapa itu tidak sesederhana seperti pada fungsi PHP tidak disetel.

Alasan untuk menulis unsetfungsi baru ini , adalah untuk menjaga indeks semua variabel lain dalam hash_map ini. Lihatlah contoh berikut, dan lihat bagaimana indeks "test2" tidak berubah setelah menghapus nilai dari hash_map.

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"}
taliboni
sumber
20

Ada banyak jawaban bagus di sini, tetapi saya hanya ingin mengatakan bahwa ketika menggunakan delete untuk menghapus properti di JavaScript, sering kali bijak untuk memeriksa dulu apakah properti itu ada untuk mencegah kesalahan.

Misalnya

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

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

Karena sifat dinamis JavaScript sering ada kasus di mana Anda tidak tahu apakah properti itu ada atau tidak. Memeriksa apakah obj ada sebelum && juga memastikan Anda tidak melakukan kesalahan karena memanggil fungsi hasOwnProperty () pada objek yang tidak ditentukan.

Maaf jika ini tidak menambah use case khusus Anda, tetapi saya yakin ini adalah desain yang bagus untuk beradaptasi ketika mengelola objek dan propertinya.

Willem
sumber
2
delete foo.bar berfungsi bahkan jika bilah tidak ada, jadi pengujian Anda terlalu banyak, IMHO.
PhiLho
@ Philho yang tergantung di mana Anda menjalankan JavaScript. Di Node.js saya percaya ini menyebabkan server Anda mogok.
Willem
2
delete foo.bar;hanya melempar pengecualian jika foo falsy, atau jika Anda dalam mode ketat dan foo adalah objek dengan properti bar yang tidak dapat dikonfigurasi.
Macil
Saya tidak ingat persis masalah yang saya alami dengan ini tetapi saya pikir masalahnya mungkin muncul ketika foo itu sendiri tidak ada dan Anda mencoba untuk menghapus properti itu.
Willem
Ya, Anda harus menguji apakah ada foo, jika tidak foo.bar akan mengeluarkan pengecualian, tetapi Anda tidak perlu memeriksa keberadaan bilah sebelum menghapusnya. Itulah bagian "terlalu banyak" dari komentar saya. :-)
PhiLho
16

Menggunakan ramda # dissoc Anda akan mendapatkan objek baru tanpa atribut regex:

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

Anda juga dapat menggunakan fungsi lain untuk mencapai efek yang sama - menghilangkan, memilih, ...

Amio.io
sumber
15

Coba metode berikut. Tetapkan nilai Objectproperti ke undefined. Lalu stringifyobjek dan parse.

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

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

console.log(myObject);

Mohammed Safeer
sumber
1
JugaJSON.parse(JSON.stringify({ ...myObject, regex: undefined }))
noisypixy
12

Jika Anda ingin menghapus properti yang bersarang dalam objek maka Anda dapat menggunakan fungsi rekursif berikut dengan path ke properti sebagai argumen kedua:

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;
    }
};

Contoh:

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

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

//Prints {level1: {level2: {}}}
ayushgp
sumber
Fungsi ini berfungsi seperti mantra, tetapi mengapa kita perlu mengembalikan true dan return false? Versi kode saya: codepen.io/anon/pen/rwbppY . Apakah versi saya gagal untuk kasus apa pun?
theusual
@ witty2017 itu tidak akan gagal. Tempat di mana saya menggunakan fungsi juga perlu memeriksa apakah properti sudah ada atau belum. jika properti tidak ada, itu akan kembali salah. Jika menemukan properti dan menghapusnya, itu akan mengembalikan true.
ayushgp
8

Anda cukup menghapus properti apa pun dari suatu objek menggunakan deletekata kunci.

Sebagai contoh:

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

Untuk menghapus properti apa pun, katakanlah key1, gunakan deletekata kunci seperti ini:

delete obj.key1

Atau Anda juga dapat menggunakan notasi seperti array:

delete obj[key1]

Ref: MDN .

Kalpesh Patel
sumber
8

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"];
        }
    }
);

xgqfrms-gildata
sumber
7

Pernyataan Dan bahwa 'hapus' sangat lambat dan patokan yang dia posting diragukan. Jadi saya melakukan tes sendiri di Chrome 59. Tampaknya 'hapus' sekitar 30 kali lebih lambat:

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

Perhatikan bahwa saya sengaja melakukan lebih dari satu operasi 'hapus' dalam satu siklus untuk meminimalkan efek yang disebabkan oleh operasi lain.

Chong Lip Phang
sumber
7

Pertimbangkan untuk membuat objek baru tanpa "regex"properti karena objek asli selalu dapat dirujuk oleh bagian lain dari program Anda. Dengan demikian Anda harus menghindari memanipulasi itu.

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

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

console.log(newMyObject);

ideaboxer
sumber
SyntaxError: Unexpected token '...'. Expected a property name.?
Krzysztof Przygoda
Cobalah dengan peramban modern seperti Firefox, Chromium atau Safari. Dan saya berharap ini bekerja dengan Edge juga.
ideaboxer
Sebagai alternatif, jika pelanggan Anda memaksa Anda untuk mendukung browser yang sudah ketinggalan zaman, Anda dapat mempertimbangkan untuk menggunakan TypeScript yang mengubah kode Anda menjadi sintaksis lama (+ memberi Anda manfaat keamanan tipe statis).
ideaboxer
7

Penghapusan Properti dalam JavaScript

Ada banyak opsi berbeda yang disajikan pada halaman ini, bukan karena sebagian besar pilihannya salah — atau karena jawabannya adalah duplikat — tetapi karena teknik yang tepat tergantung pada situasi Anda dan tujuan tugas yang Anda dan / atau Anda lakukan. Tim berusaha untuk memenuhi. Untuk menjawab pertanyaan Anda dengan tegas, Anda perlu tahu:

  1. Versi ECMAScript yang Anda targetkan
  2. Rentang jenis objek yang ingin Anda hapus properti dan jenis nama properti yang harus Anda hilangkan (Strings saja? Simbol? Lemah referensi yang dipetakan dari objek arbitrer? Ini semua telah menjadi jenis pointer properti di JavaScript selama bertahun-tahun sekarang) )
  3. Etos / pola pemrograman yang Anda dan tim Anda gunakan. Apakah Anda menyukai pendekatan fungsional dan mutasi adalah verboten di tim Anda, atau apakah Anda menggunakan teknik berorientasi objek mutatif barat liar?
  4. Apakah Anda ingin mencapai ini dalam JavaScript murni atau apakah Anda bersedia & mampu menggunakan perpustakaan pihak ke-3?

Setelah keempat pertanyaan itu dijawab, pada dasarnya ada empat kategori "penghapusan properti" dalam JavaScript untuk dipilih untuk memenuhi tujuan Anda. Mereka:

Penghapusan properti objek mutatif, tidak aman

Kategori ini adalah untuk beroperasi pada objek literal atau instance objek ketika Anda ingin mempertahankan / terus menggunakan referensi asli dan tidak menggunakan prinsip-prinsip fungsional stateless dalam kode Anda. Contoh sintaks dalam kategori ini:

'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

Kategori ini adalah kategori penghapusan properti tertua, paling mudah & paling banyak didukung. Ini mendukung Symbol& array indeks selain string dan berfungsi di setiap versi JavaScript kecuali untuk rilis pertama. Namun, itu mutatif yang melanggar beberapa prinsip pemrograman dan memiliki implikasi kinerja. Ini juga dapat menghasilkan pengecualian tanpa tertangkap ketika digunakan pada properti yang tidak dapat dikonfigurasi dalam mode ketat .

Penghilangan properti string berbasis istirahat

Kategori ini untuk operasi pada objek objek atau array contoh dalam rasa ECMAScript yang lebih baru ketika pendekatan non-mutatif diinginkan dan Anda tidak perlu memperhitungkan kunci Simbol:

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 :(

Penghapusan properti objek mutatif, aman

Kategori ini untuk operasi pada objek literal atau instance objek ketika Anda ingin mempertahankan / terus menggunakan referensi asli sambil menjaga terhadap pengecualian yang dilemparkan pada properti yang tidak dapat dikonfigurasi:

'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

Selain itu, sementara bermutasi objek di tempat bukan stateless, Anda dapat menggunakan sifat fungsional Reflect.deletePropertyuntuk melakukan aplikasi parsial dan teknik fungsional lainnya yang tidak mungkin dengan deletepernyataan.

Penghilangan properti string berbasis sintaksis

Kategori ini untuk operasi pada objek objek atau array contoh dalam rasa ECMAScript yang lebih baru ketika pendekatan non-mutatif diinginkan dan Anda tidak perlu memperhitungkan kunci Simbol:

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 :(

Penghilangan properti berbasis perpustakaan

Kategori ini secara umum memungkinkan fleksibilitas fungsional yang lebih besar, termasuk akuntansi untuk Simbol & menghilangkan lebih dari satu properti dalam satu pernyataan:

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"
james_womack
sumber
var keyname = "KeyName"; hapus myObject [keyname];
Vikash Chauhan
7

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

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

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

xiang
sumber
@ CoddWrench Maaf, saya tidak memperhatikan melihat jawaban itu. Saya menjawabnya segera setelah melihat delete myObject.regex;.
xiang
7

Anda dapat menggunakan destruksi ES6 dengan operator lainnya.

Properti dapat dihilangkan menggunakan Destrukturisasi dalam kombinasi dengan operator lainnya . Dalam contoh Anda, regex dirusak (diabaikan) dan sisa properti dikembalikan sebagai istirahat.

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

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

Atau Anda dapat secara dinamis mengecualikan properti seperti ini,

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://.*" }
Bhargav Patel
sumber
7

Kami dapat menghapus properti apa pun dari objek javascript dengan menggunakan berikut ini:

  1. hapus object.property
  2. hapus objek ['properti']

contoh:

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

console.log(myObject);

delete myObject.regex;
console.log('=================');
console.log(myObject);
delete myObject['method'];
console.log('=================');
console.log(myObject);

Ravi Ranjan
sumber
6

Coba ini

delete myObject['key'];
codemirror
sumber