Bir özelliği bir JavaScript nesnesinden nasıl kaldırabilirim?


6141

Diyelim ki aşağıdaki gibi bir nesne oluşturuyorum:

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

Aşağıdaki gibi regexyenileriyle sonuçlanacak mülkü kaldırmanın en iyi yolu nedir myObject?

let myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};


@EscapeNetscape Bu davranışla ilgili bir soru, bu yüzden bir kıyaslama yanlış resmi boyar. Elbette deleteen yavaş seçenek olurdu, çünkü sadece basit atamalar olan diğer ikisinden ziyade gerçek bir işlemdir. Ancak meselenin özü, özelliğin nesneye atanması nullveya undefinedaslında nesneden kaldırılmaması, bunun yerine bu özelliği belirli bir sabit değere eşit olarak ayarlamasıdır. (Aşağıdaki cevaplar bunun önemli bir fark olmasının nedenlerini vermektedir.)
Abion47

Yanıtlar:


8303

Bunun gibi:

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

gösteri

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

console.log(myObject);

Bu konuda daha fazla okumak isteyen herkes için Stack Overflow kullanıcısı kanguru , blogundaki deleteifade silme hakkında ifade hakkında inanılmaz derecede derin bir blog yazısı yazdı . Şiddetle tavsiye edilir.


47
İşaretlendi, ayrıca "delete myJSONObject ['regex'];" Bakınız: developer.mozilla.org/tr/Core_JavaScript_1.5_Reference/…
johnstok

109
Yukarıdaki "anlama silme" bağlantısındaki gözlemlerden birinin bir sonucu olarak, bir değişkeni değil, yalnızca nesne özelliklerini mutlaka silemeyeceğinizden, bu nedenle bir nesne özelliğini "başvuru ile" silemezsiniz - var value = obj [ 'deki']; değeri sil // çalışmıyor
Dexygen

27
Yani gerçekten silmiyor mu? Sadece tanımsız hale geliyor, ama anahtar hala var mı? Bir şey mi kaçırıyorum?
Doug Molineux

151
@Pete hayır, kaldırır. Verilen: var x = {a : 'A', b : 'B'};Karşılaştır: delete x.a; typeof x.a; /* "undefined" */ x.hasOwnProperty('a'); /* false */içinx.b = undefined; typeof x.b; /* "undefined" */; x.hasOwnProperty('b'); /* true */
nickf

16
@ KristopherPfohl benim için çalışıyor. Dediğim gibi, aslında oldukça derin, bu yüzden özetlemek biraz zor. Yukarıdaki cevabın temel yanıtı hemen hemen tüm vakalar için yeterlidir, blog daha fazla vakaya ve bu vakaların nedenlerine girer.
nickf

952

JavaScript'teki nesneler, anahtarlar ve değerler arasında harita olarak düşünülebilir. deleteOperatör daha çok nesne özellikleri, bir seferde birisi olarak da adlandırılan bu anahtarlar kaldırmak için kullanılır.

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

deleteOperatör doğrudan boş hafıza yapar ve sadece bir değer atama farklıdırnull ya da undefinedözelliği olup, bir özelliğine kendisi nesne kaldırılır. Eğer Not değeri kendisine yapılan tüm başvurular bulana kadar silinmiş bir özelliğinin bir başvuru türü (bir nesne) ve programın başka bir parçasıydı hala o nesneye başvuruyu tutar, daha sonra bu nesne, tabii ki, değil çöp toplanacak kayboldu.

delete yalnızca tanımlayıcısı bunları yapılandırılabilir olarak işaretleyen özellikler üzerinde çalışır.


43
undefined öğesine atanmış bir özellik yine de bir nesnenin özelliğidir, bu nedenle son paragrafınızı yanlış okumadıkça GC tarafından kaldırılmaz.
Lance

8
Burada GC'nin temasına dokunmak yanlıştı. Her iki yöntem de GC için aynı sonuca sahiptir: anahtara bağlı değeri kaldırırlar. Bu değer başka bir nesneye son başvuru olsaydı, o nesne temizlenirdi.
Dan

15
undefined öğesine atanan bir özellik yine de bir nesnenin özelliğidir, bu nedenle GC tarafından kaldırılmaz GC özellikler hakkında hiçbir şey yönetmez. Değerleri toplar ve kaldırır. Artık hiçbir şey bir değere (nesne, dize vb.) Gönderme yapmadığı sürece GC değeri bellekten kaldırır.
meandre

8
BTW, Javascript nesnesinde bir özelliğin var olup olmadığını kontrol etmek için çift problemdir. Kullanılması halinde operatörü güvenilir ama yavaş. Özelliğin tanımlanmadığını kontrol edin "doğru cevap değil" ama daha hızlı bir yol. check
rdllopes

8
Bu cevap hala geçerli mi? jsperf şu anda çalışmıyor, ancak bu kriter hız farkı hiçbir yerde sadece% 25 olduğunu gösteriyor gibi görünüyor yakın için "~ 100 kat daha yavaş" bu cevap.
Cerbrus

248

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

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

Bu Firefox ve Internet Explorer'da çalışıyor ve sanırım diğer tüm sistemlerde çalışıyor.


216

deleteOperatör nesnelerinden özelliklerini uzaklaştırmak için kullanılır.

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

Diziler için bunun bir öğeyi kaldırmakla aynı olmadığını unutmayın . Bir diziden öğe kaldırmak için Array#spliceveya tuşunu kullanın Array#pop. Örneğin:

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

ayrıntılar

deleteJavaScript C ve C ++ anahtar kelimesinden farklı bir işlevi vardır: doğrudan bellek serbest değildir. Bunun yerine, tek amacı nesneleri nesnelerden kaldırmaktır.

Diziler için, bir dizine karşılık gelen bir özelliği silmek seyrek bir dizi (yani içinde "delik" bulunan bir dizi) oluşturur. Çoğu tarayıcı bu eksik dizi indekslerini "boş" olarak gösterir.

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

Not deletetaşınmaya gelmez array[3]içine array[2].

JavaScript'teki farklı yerleşik işlevler, seyrek dizileri farklı şekilde işler.

  • for...in boş dizini tamamen atlayacaktır.

  • forDizindeki undefineddeğer için geleneksel bir döngü döndürülür .

  • Kullanarak herhangi bir yöntem dizindeki değer için Symbol.iteratordöner undefined.

  • forEach, mapVe reducesadece eksik endeksi atlayacak.

Bu nedenle, deleteoperatör, bir diziden eleman çıkarmanın ortak kullanım durumu için kullanılmamalıdır. Diziler, öğeleri kaldırmak ve belleği yeniden ayırmak için özel bir yöntem kullanır: Array#splice()ve Array#pop.

Dizi # eki (start [, deleteCount [, öğe1 [, öğe2 [, ...]]]])

Array#splicediziyi değiştirir ve kaldırılan tüm dizinleri döndürür. deleteCountelemanları dizinden kaldırılır startve item1, item2... itemNdizinden diziye yerleştirilir start. Eğer deleteCountgöz ardı edilir startIndex'ten gelen elemanlar dizisinin sonuna kaldırılır.

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

Benzer adlı, ancak farklı, fonksiyon üzerinde de vardır Array.prototype: Array#slice.

Dizi # dilim ([başlangıç ​​[, bitiş]])

Array#slicetahribatsız ve, gösterilen endeksleri içeren yeni bir dizi döner startiçin end. Eğer endis dizinin sonuna belirtilmemiş, varsayılan bıraktı. Eğer endolumlu, sıfır tabanlı belirten dahil olmayan durmak endeksi. Eğer endnegatif, bu dizinin sonundaki geri sayım en durağı indisi (örn. -1 Son dizini ihmal edecek). Eğer end <= start, sonuç boş bir dizidir.

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]

Dizi # pop

Array#popbir dizideki son öğeyi kaldırır ve o öğeyi döndürür. Bu işlem dizinin uzunluğunu değiştirir.


12
Bu yaklaşım, başka bir yerde hala başvurulabilecek orijinal nesneyi değiştirmez. Bu, nasıl kullanıldığına bağlı olarak bir sorun olabilir veya olmayabilir, ancak akılda tutulması gereken bir şeydir.
Tamas Czinege

19
@ B1KMusic Bir Diziden bir öğeyi silmenin yolu: splice
wulftone

3
@wulftone hayır, diziyi böler ve bir değeri silmek için hiçbir şey yapmaz. Gerçekten belirli değerleri silinmesi gereken bir dizi silmek için en iyi yolu kullanmak deleteve temizlemek için bir Çöp Toplama işlevi yapmak olduğunu düşünüyorum.
Braden En İyi

5
spliceDüzenlemenizde görmüyorum , ama öyle removeolmalıyımArray.prototype.remove = function(index) { this.splice(index, 1); };
Ry-

1
Bu makale boğa 1 ile dolu. Soruyu ele almıyor! 2. Dilin örnek bir kötüye kullanımı ve "işe yaramaz!" 3. Do JavaScript suçlamıyorum silme koyma Crockford en kendine has hata için operatöre null adlı boş bir dizi indeksi için. Null'un anlamını anlamıyor - bunun bir hata olduğunu düşünüyor. Hata kendi başına ve tek başınadır - belirli bir dizi dizininin silinen değerinde boş yoktur. Dizide "delik" yok - bu boş bir dizin. Kesinlikle meşru ve beklenen.
Bekim Bacaj

195

Eski soru, modern cevap. Bir ECMAScript 6 özelliği olan nesne yok etme özelliğini kullanmak, bu kadar basit:

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

Veya soru örneği ile:

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

Babil deneme editöründe çalışırken görebilirsiniz.


Düzenle:

Aynı değişkene yeniden atamak için a kullanın let:

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

6
Belki de amaç, bir özelliği bir nesneden kaldırmak, özellik olmadan yeni bir tane oluşturmak değil ... ... ancak, değişmez yolu tercih ettiğim için çözümünüz benim favorim.
Vingt_centimes

8
Soru " yeni myObject ile sonuçlanacak " dedi.
Koen.

1
Bir özellik irade çöp çıkarmadan proje :) Yerine kullanılabilir olarak sahibi olmak için alt çizgi ekleme regexda başka herhangi bir değişkenin, örneğin atamak olabilir _bir sonuç atmak git gibi diller kullanılır ne: const { regex: _, ...newObject } = myObject;.
Koen.

2
@PranayKumar Bu sözdiziminin işe yarayacağını umuyordum; const { [key], ...newObject } = myObject;ama öyle değil, bu yüzden yıkımın mümkün olduğunu düşünmüyorum.
Koen.

2
İle freeze()'d ve seal()' d nesneler, sadece olamaz deletebir özellik. Yani bu mükemmel bir alternatif. Her ne kadar çoğu durumda, donmuş / mühürlü bir nesneden bir özelliği silmek yine de mantıklı gelmez, ancak tüm mesele, bu modelin zarar göreceği veri yapılarınız hakkında belirli garantiler yapmaktır. Bir nesneyi tahribatsız bir şekilde kopyalamanız gereken ancak bazı özellikleri olmadan bu durumlar için mükemmel
Braden Best

118

Sözdizimini Yay (ES6)

İhtiyacı olanlara ...

Bu iş parçacığında @Koen yanıtını tamamlamak için, yayılma sözdizimini kullanarak dinamik değişkeni kaldırmak istiyorsanız, bunu şu şekilde yapabilirsiniz:

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

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

* foodeğeri a1 olan yeni bir değişken olacaktır .


GENİŞLETİLMİŞ CEVAP an
Bir özelliği bir nesneden kaldırmanın birkaç yaygın yolu vardır.
Her birinin kendi artıları ve eksileri vardır ( bu performans karşılaştırmasını kontrol edin ):

Operatörü Sil
Okunabilir ve kısa, ancak performansı optimize edilmediğinden çok sayıda nesne üzerinde çalışıyorsanız en iyi seçim olmayabilir.

delete obj[key];


Yeniden Atama
daha hızlı 2X daha fazladeleteancak mülkiyet edilirdeğilsilinir ve iterated.

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


Spread Operator
BuES6operatör, mevcut nesneyi değiştirmeden, herhangi bir özellik hariç, yepyeni bir nesne döndürmemize olanak tanır. Dezavantajı, yukarıdakilerden daha kötü performansa sahip olması ve bir seferde birçok özelliği kaldırmanız gerektiğinde kullanılması önerilmez.

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

2
Birkaç JS motoru zaten uygulamış olsa bile, nesne değişmezleri için yayılma / dinlenme sözdizimi ES6 değil, sadece ES2018 (ES9) dahil olduğunu düşünüyorum.
trincot

2
@trincot İlk olarak 2014 yılında tanıtıldı ( github.com/tc39/proposal-object-rest-spread ) ve bu bir ES6 (ECMAScript 2015 aka ECMAScript 6. Baskı) özelliğidir. Ancak, yanılsam bile, bunun cevabın bağlamında bir fark yarattığını düşünmüyorum.
Lior Elrom

2
Bağlantı, diziler için gerçekten yayılmış sözdiziminin eklendiği ES6'ya atıfta bulunur, ancak daha sonra nesne değişmezleri için benzer bir şey önermeye devam eder. Bu ikinci bölüm sadece yanılmıyorsam ES9'a dahil edildi.
trincot

98

Başka bir alternatif, Underscore.js kitaplığını kullanmaktır .

Unutmayın _.pick()ve_.omit() doğrudan orijinal nesneyi değişiklik yapmayın de dönüp nesnenin bir kopyasını ve. Sonucu orijinal nesneye atamak hile yapmalıdır (gösterilmemiştir).

Referans: bağlantı _.pick (nesne, * anahtarlar)

Yalnızca beyaz listedeki anahtarlar (veya geçerli anahtar dizisi) için değerlere sahip olacak şekilde filtrelenen nesnenin bir kopyasını döndürün.

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

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

Referans: bağlantı _.omit (nesne, * anahtarlar)

Kara listeye alınan anahtarları (veya anahtar dizisini) atlamak için filtrelenen nesnenin bir kopyasını döndürün.

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

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

Diziler için _.filter()ve _.reject()benzer bir şekilde kullanılabilir.


4
Nesnenin anahtarları sayı ise, yapmanız gerekebileceğini unutmayın_.omit(collection, key.toString())
Jordan Arseno

Hmmmmm .... Alt çizgi ~ 100x daha yavaş delete obj[prop], ~ 100x daha yavaş obj[prop] = undefined.
Jack Giffin

52

Soru başlığınızda kullandığınız terim Remove a property from a JavaScript object, bazı farklı şekillerde yorumlanabilir. Biri tüm belleği kaldırmak için ve nesne anahtarlarının listesi ya da diğeri sadece nesnenizden kaldırmaktır. Diğer bazı cevaplarda da belirtildiği gibi, deleteanahtar kelime ana kısımdır. Diyelim ki nesneniz şöyle:

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

Yaparsan:

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

sonuç şöyle olur:

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

Söz konusu anahtarı nesne anahtarlarınızdan aşağıdaki gibi silebilirsiniz:

delete myJSONObject["regex"];

Sonra nesneleri anahtar kullanarak Object.keys(myJSONObject)olacaktır:

["ircEvent", "method"]

Ancak önemli olan, hafızayı önemsiyorsanız ve nesnenin hafızadan kaldırılmasını istiyorsanız, anahtarı silmeden önce null değerine ayarlamanız önerilir:

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

Buradaki diğer önemli nokta, aynı nesneye yapılan diğer referanslarınız konusunda dikkatli olmaktır. Örneğin, şöyle bir değişken oluşturursanız:

var regex = myJSONObject["regex"];

Veya aşağıdaki gibi başka bir nesneye yeni bir işaretçi olarak ekleyin:

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

Sonra nesnenizden kaldırsanız bile myJSONObject , belirli bir nesne bellekten silinmez, çünkü regexdeğişken vemyOtherObject["regex"] hala değerlerine sahiptir. O zaman nesneyi bellekten nasıl kaldırabiliriz?

Cevap , kodunuzdaki tüm referansları silmek, o nesneyi işaret etmek ve kullanmak istememek olacaktır.var o nesneye yeni referanslar oluşturmak ifadeler olacaktır . varİfadelerle ilgili bu son nokta , genellikle karşılaştığımız en önemli konulardan biridir, çünküvar ifadeler oluşturulan nesnenin kaldırılmasını engelleyecektir.

Diğer bir deyişle, bu durumda regexdeğişkeni birvar deyim ve yaptığınız takdirde, :

delete regex; //False

Sonuç false, silme ifadenizin beklediğiniz gibi yürütülmediği anlamına gelir. Ama daha önce bu değişkeni siz oluşturmadıysanız vemyOtherObject["regex"] son mevcut referansınız olarak yapsaydınız, bunu aşağıdaki gibi kaldırarak yapmış olabilirsiniz:

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

Başka bir deyişle, kodunuzda o nesneye işaret eden referans kalmaz JavaScript nesnesi öldürülür.


Güncelleme: @AgentME sayesinde:

Bir özelliği silmeden önce null değerine ayarlamak hiçbir şey başaramaz (nesne Object.seal tarafından mühürlenmediyse ve silme işlemi başarısız olursa. Özellikle denemediğiniz sürece genellikle böyle olmaz).

Daha fazla bilgi için Object.seal: Object.seal ()


Yanılıyorsunuz - JavaScript'te yalnızca nesneler başvuru ile iletilir, bu nedenle myJSONObject.regex'değeri bir dize ise ve başka bir nesneye atarsanız, diğer nesnenin bu değerin bir kopyası vardır.
Michał Perłakowski

Haklısınız ve bu bir alıntı: "aynı nesneye yapılan diğer referanslarınız konusunda dikkatli olmak."
Mehran Hatami

43

ECMAScript 2015 (veya ES6) yerleşik Yansıtma nesnesi ile birlikte geldi . Hedef nesne ve özellik anahtarıyla birlikte Reflect.deleteProperty () işlevini parametre olarak çağırarak nesne özelliğini silmek mümkündür :

Reflect.deleteProperty(myJSONObject, 'regex');

eşdeğer:

delete myJSONObject['regex'];

Ancak nesnenin özelliği yapılandırılamazsa, ne deleteProperty işlevi ne de delete operatörü ile silinemez:

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

Object.freeze () , nesnenin tüm özelliklerini yapılandırılamaz (diğer şeylerin yanı sıra). deletePropertyfunction (ve delete operatörü ) falseözelliklerinden herhangi birini silmeye çalıştığında geri döner . Özellik yapılandırılabilirse true, özellik olmasa bile geri döner .

Sıkı modu kullanırken deleteve arasındaki fark deleteProperty:

"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

1
@Gothdo, özellikle bazı fonksiyonel şeyler yapmanız gerektiğinde daha fazla faydaya sahiptir. Örneğin sen, değişkene işlev atamak bağımsız değişken veya kullanımı gibi geçebilir apply, call, bind... fonksiyonları
madox2

41

Bunun gibi görünen bir nesneniz olduğunu varsayalım:

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

Bir nesne özelliğini silme

Tüm staffdiziyi kullanmak istiyorsanız , bunu yapmanın uygun yolu bunu yapmak olacaktır:

delete Hogwarts.staff;

Alternatif olarak, bunu da yapabilirsiniz:

delete Hogwarts['staff'];

Benzer şekilde, tüm öğrenci dizisinin kaldırılması delete Hogwarts.students;veyadelete Hogwarts['students']; .

Dizi dizinini silme

Şimdi, tek bir personel veya öğrenciyi kaldırmak istiyorsanız, prosedür biraz farklıdır, çünkü her iki özellik de dizilerdir.

Personel üyelerinizin dizinini biliyorsanız, bunu kolayca yapabilirsiniz:

Hogwarts.staff.splice(3, 1);

Dizini bilmiyorsanız, bir dizin araması da yapmanız gerekir:

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

Not

deleteBir dizi için teknik olarak kullanabileceğiniz gibi , diziyi kullanmak, örneğin Hogwarts.staff.lengthdaha sonra çağırırken yanlış sonuçlar almanıza neden olur . Başka bir deyişle, deleteöğeyi kaldırır, ancak lengthmülkün değerini güncellemez . Kullanmak deleteda indekslemenizi bozar.

Bu nedenle, bir nesneden değerleri silerken, her zaman önce nesne özellikleriyle veya dizi değerleriyle ilgilenip ilgilenmediğinizi düşünün ve buna göre uygun stratejiyi seçin.

Bunu denemek istiyorsanız, bu Fiddle'ı başlangıç ​​noktası olarak kullanabilirsiniz .


Her zaman spliceyerine bir dizi kullanmak gerektiğini düşünürdüm delete.
Joel Trauger

@JoelTrauger: Ben de bunu söylüyorum ;-)
John Slegers

Evet. Benim yorumum, bunun deletebir şey bile olmaması gerektiğidir. Bu var spliceOP arıyordu budur.
Joel Trauger

1
@JoelTrauger: Açıklamaya çalıştığım gibi, deletenesne özellikleri ve splicedizi elemanları için kullanılmalıdır .
John Slegers

Splice gerçekten yavaş. deleteDiziler yerine kullanılmalı olsa da, çevresinde ortalanmış kod oluşturmamak en akıllıca olacaktır.
Jack Giffin

39

ES6'yı kullanma:

(Yıkıcı + Forma operatörü)

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

Bunun bir ES6 özelliği olduğunu düşünmüyorum, ancak sadece ES9'da bulunan bir özellik.
trincot

Yani aslında yazarken ES6 kullanmıyorsunuz, ama ES9 ... ;-)
trincot

2
Bu, bir özelliği bir nesneden kaldırmaz, ancak bu özellik olmadan yeni bir nesne oluşturur.
Jordi Nebot



29

Özelliği olmayan nesneyi klonlamak için:

Örneğin:

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

Ve 'a' yı silmemiz gerekiyor.

1. açık prop tuşu ile:

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

2. değişken prop tuşu ile:

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

3. serin ok fonksiyonu 😎:

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

object = removePropery('a', object);

4. Birden fazla özellik için

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

kullanım

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

Veya

    const propsToRemove = ['a', 'b']
    object = removeProperties(object, ...propsToRemove) // result => { c: 3 }

1
Kaygan ok işlevi!
JSilv

27

Silme yöntemini kullanmak bunu yapmanın en iyi yoludur, MDN açıklamasına göre silme işleci bir nesneyi bir özellikten kaldırır. Böylece şunları yazabilirsiniz:

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

Delete operatörü belirli bir özelliği bir nesneden kaldırır. Başarılı bir silme işleminde, doğru döner, aksi takdirde yanlış döndürülür. Ancak, aşağıdaki senaryoları dikkate almak önemlidir:

  • Silmeye çalıştığınız özellik yoksa, silme işleminin bir etkisi olmaz ve true değerini döndürür

  • Nesnenin prototip zincirinde aynı ada sahip bir özellik varsa, silindikten sonra nesne, prototip zincirindeki özelliği kullanır (başka bir deyişle, silme yalnızca kendi özellikleri üzerinde bir etkiye sahiptir).

  • Var ile bildirilen hiçbir özellik genel kapsamdan veya bir işlevin kapsamından silinemez.

  • Bu nedenle, delete genel kapsamdaki hiçbir işlevi silemez (bu bir işlev tanımından mı yoksa bir işlevden mi (ifade) olsun).

  • Bir nesnenin parçası olan işlevler (
    genel kapsam dışında ) delete ile silinebilir.

  • Let veya const ile bildirilen hiçbir özellik, tanımlandıkları kapsamdan silinemez. Yapılandırılamayan özellikler kaldırılamaz. Bu, Math, Array, Object gibi yerleşik nesnelerin özelliklerini ve Object.defineProperty () gibi yöntemlerle yapılandırılamayan olarak oluşturulan özellikleri içerir.

Aşağıdaki kod parçası basit bir örnek daha veriyor:

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

Hakkında daha fazla bilgi ve daha fazla örnek görmek için aşağıdaki bağlantıyı ziyaret edin:

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


22

Kullanarak başka bir çözüm 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);

Ancak, olacak mutasyona orijinal nesneyi. Belirtilen anahtar olmadan yeni bir nesne oluşturmak istiyorsanız , azaltma işlevini yeni bir değişkene atamanız yeterlidir, örneğin:

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


21

Bu yazı çok eski ve ben çok yararlı buldum bu yüzden başkası bu yazı görmek ve neden PHP unset fonksiyonu kadar basit olmadığını düşünüyorum yazdı unset fonksiyonunu paylaşmaya karar verdi.

Bu yeni unsetişlevi yazmanın nedeni , bu hash_map içindeki diğer tüm değişkenlerin dizinini tutmaktır. Aşağıdaki örneğe bakın ve hash_map öğesinden bir değer kaldırıldıktan sonra "test2" dizininin nasıl değişmediğine bakın.

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

20

Burada çok iyi yanıtlar var ama JavaScript'te bir özelliği kaldırmak için delete kullanırken, genellikle ilk önce bu özelliğin hataları önlemek için var olup olmadığını kontrol etmek akıllıca olacaktır.

Örneğin

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

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

JavaScript'in dinamik yapısı nedeniyle, genellikle mülkün var olup olmadığını bilmediğiniz durumlar vardır. && öğesinden önce obj olup olmadığını kontrol etmek, tanımlanmamış bir nesneye hasOwnProperty () işlevinin çağrılması nedeniyle hata atmamanızı da sağlar.

Bu, özel kullanım durumunuza eklenmediyse üzgünüm, ancak nesneleri ve özelliklerini yönetirken uyum sağlamak için iyi bir tasarım olduğuna inanıyorum.


2
delete foo.bar, çubuk olmasa bile çalışır, bu nedenle testiniz biraz fazla IMHO.
PhiLho

@PhiLho, nerede JavaScript kullandığınıza bağlıdır. Node.js'de bunun sunucunuzun çökmesine neden olduğuna inanıyorum.
Willem

2
delete foo.bar;sadece foo falsy ise veya katı moddaysanız ve foo yapılandırılamaz bir bar özelliğine sahip bir nesne ise bir istisna atar.
Macil

Ben bu konuda yaşadım kesin hatırlamıyorum ama foo kendisi yok ve bu özelliği silmeye çalıştığınızda sorun ortaya çıkabilir düşünüyorum.
Willem

Evet, foo'nun var olup olmadığını test etmeniz gerekir, aksi halde foo.bar bir istisna atar, ancak silmeden önce bar için varlığını kontrol etmeniz gerekmez. Bu benim yorumumun "çok fazla" kısmı. :-)
PhiLho

16

Ramda # dissoc komutunu kullanarak yeni bir nesne alırsınız regex:

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

Aynı efekti elde etmek için diğer işlevleri de kullanabilirsiniz - atla, seç, ...


15

Aşağıdaki yöntemi deneyin. ObjectÖzellik değerini olarak atayın undefined. Sonra stringifynesne ve parse.

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

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

console.log(myObject);


1
AyrıcaJSON.parse(JSON.stringify({ ...myObject, regex: undefined }))
noisypixy

12

Nesnede derinden iç içe yerleştirilmiş bir özelliği silmek istiyorsanız, ikinci bağımsız değişken olarak özelliğin yolunu içeren aşağıdaki özyinelemeli işlevi kullanabilirsiniz:

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

Misal:

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

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

//Prints {level1: {level2: {}}}

Bu işlev bir cazibe gibi çalışır, ancak neden doğru ve yanlış döndürmeye ihtiyacımız var? Kodun sürümüm : codepen.io/anon/pen/rwbppY . Sürümüm herhangi bir durumda başarısız olacak mı?
Olağandışı

@ witty2017 başarısız olmaz. Bu işlevi kullandığım yer de özelliğin zaten var olup olmadığını kontrol etmek gerekiyordu. özellik yoksa, false değerini döndürür. Mülkü bulup silerse, true değerini döndürür.
ayushgp

8

Bir nesneyi herhangi bir özelliğini deleteAnahtar kelimeyi .

Örneğin:

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

Herhangi bir mülkü kaldırmak için, örneğin key1, deleteanahtar kelimeyi şöyle kullanın :

delete obj.key1

Veya dizi benzeri gösterimi de kullanabilirsiniz:

delete obj[key1]

Ref: MDN .


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


7

Dan'ın 'silme' iddiası çok yavaş ve yayınladığı kıyaslamadan şüphe ediliyordu. Bu yüzden testi kendim Chrome 59'da gerçekleştirdim. Görünüşe göre 'sil' işlemi yaklaşık 30 kat daha yavaş:

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

Diğer işlemlerin neden olduğu etkiyi en aza indirmek için bir döngü döngüsünde bilerek birden fazla 'silme' işlemi gerçekleştirdiğimi unutmayın.


7

"regex"Orijinal nesneye her zaman programınızın diğer bölümleri tarafından başvurulabileceğinden , özellik olmadan yeni bir nesne oluşturmayı düşünün . Böylece onu manipüle etmekten kaçınmalısınız.

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

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

console.log(newMyObject);


SyntaxError: Unexpected token '...'. Expected a property name.?
Krzysztof Przygoda

Firefox, Chromium veya Safari gibi modern bir tarayıcıyla deneyin. Edge ile de çalışmasını bekliyorum.
ideaboxer

Alternatif olarak, müşterileriniz sizi eski tarayıcıları desteklemeye zorlarsa, kodunuzu eski sözdizimine aktaran TypeScript kullanmayı düşünebilirsiniz (+ size statik tür güvenliği avantajı sağlar).
ideaboxer

7

JavaScript'te Mülk Kaldırma

Bu sayfada sunulan birçok farklı seçenek vardır, seçeneklerin çoğu yanlış olduğu için veya cevaplar kopya olduğu için değil, uygun teknik bulunduğunuz duruma ve sizin ve / veya sizin görevlerin hedeflerine bağlıdır. ekibi yerine getirmeye çalışıyor. Sorunuzu kesin olarak cevaplamak için aşağıdakileri bilmeniz gerekir:

  1. Hedeflediğiniz ECMAScript sürümü
  2. Özelliklerini kaldırmak istediğiniz nesne türleri ve atlayabilmeniz gereken özellik adlarının türü (yalnızca dizeler? Semboller? Rastgele nesnelerden eşlenen zayıf başvurular mı?) Bunların tümü yıllardır JavaScript'te özellik işaretçisi türleri olmuştur )
  3. Sizin ve ekibinizin kullandığı programlama ahlakı / kalıpları. Fonksiyonel yaklaşımları tercih ediyor musunuz ve mutasyon ekibinizde verboten mi, yoksa vahşi batı mutasyonel nesne yönelimli teknikler kullanıyor musunuz?
  4. Bunu saf JavaScript'te başarmak mı istiyorsunuz yoksa üçüncü taraf bir kütüphane kullanmak istiyor musunuz?

Bu dört sorgu yanıtlandıktan sonra, JavaScript'te hedeflerinize ulaşmak için seçebileceğiniz dört "mülk kaldırma" kategorisi vardır. Onlar:

Değişken nesne özelliklerinin silinmesi, güvensiz

Bu kategori, orijinal başvuruyu korumak / kullanmaya devam etmek istediğinizde ve kodunuzda durum bilgisi olmayan işlev ilkeleri kullanmadığınızda nesne değişmezleri veya nesne örnekleri üzerinde çalışmak içindir. Bu kategorideki bir sözdizimi örneği:

'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

Bu kategori en eski, en basit ve en yaygın olarak desteklenen mülk kaldırma kategorisidir. SymbolDizelere ek olarak dizi dizinlerini destekler ve ilk sürüm hariç JavaScript'in her sürümünde çalışır. Bununla birlikte, bazı programlama prensiplerini ihlal eden ve performans sonuçları olan değişkendir. Ayrıca katı modda yapılandırılamayan özelliklerde kullanıldığında yakalanmamış istisnalara neden olabilir .

Dinlenme tabanlı dize özelliği ihmali

Bu kategori, değişken olmayan bir yaklaşım istendiğinde ve Sembol anahtarlarını hesaba katmanız gerekmediğinde yeni ECMAScript lezzetlerinde düz nesne veya dizi örnekleri üzerinde çalışmak içindir:

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

Değişken nesne özelliklerinin silinmesi, güvenli

Bu kategori, yapılandırılamayan özelliklerde atılan istisnalara karşı korunurken orijinal başvuruyu korumak / kullanmaya devam etmek istediğinizde nesne değişmezleri veya nesne örnekleri üzerinde çalışmak içindir:

'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

Ayrıca, nesneleri yerinde değiştirmek vatansız olmasa da, Reflect.deletePropertykısmi uygulama ve mümkün olmayan diğer işlevsel teknikleri yapmak için işlevsel doğasını kullanabilirsiniz.delete ifadelerle .

Sözdizimi tabanlı dize özelliği ihmali

Bu kategori, değişken olmayan bir yaklaşım istendiğinde ve Sembol anahtarlarını hesaba katmanız gerekmediğinde yeni ECMAScript lezzetlerinde düz nesne veya dizi örnekleri üzerinde çalışmak içindir:

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

Kütüphane tabanlı mülk ihmali

Bu kategori genellikle Sembollerin hesaplanması ve bir ifadede birden fazla mülkün ihmal edilmesi dahil olmak üzere daha fazla işlevsel esnekliğe izin verir:

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"

var keyname = "AnahtarAdı"; myObject [anahtar adı] 'yı sil;
Vikash Chauhan

7

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

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

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


@CoddWrench Üzgünüm, bu cevabı görmeye dikkat etmedim. Gördükten hemen sonra cevaplıyorum delete myObject.regex;.
xiang

7

Dinlenme operatörü ile ES6 yıkımını kullanabilirsiniz.

Özellikler , geri kalan operatörle birlikte yıkım kullanılarak kaldırılabilir . Örneğinizde normal ifade yok edilir (yoksayılır) ve özelliklerin geri kalanı dinlenme olarak döndürülür.

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

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

Veya bunun gibi özellikleri dinamik olarak hariç tutabilirsiniz,

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

7

Aşağıdaki özellikleri kullanarak herhangi bir özelliği bir javascript nesnesinden kaldırabiliriz:

  1. object.property'yi sil
  2. nesneyi sil ['özellik']

misal:

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


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.