Diyelim ki aşağıdaki gibi bir nesne oluşturdum:
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
Aşağıdaki gibi yeni myObject
ile sonuçlanmak için regex
özelliğini kaldırmanın en iyi yolu nedir?
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI"
};
Bunun gibi:
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);
Bu konuda daha fazla bilgi edinmek isteyenler için Stack Overflow kullanıcısı kangax, Understanding delete adlı blogunda delete
deyimi hakkında inanılmaz derecede derinlemesine bir blog yazısı yazmıştır. Şiddetle tavsiye edilir.
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ğerlerinde de çalışıyor.
Güncelleme 2018-07-21: Uzun zamandır bu cevaptan utanıyordum, bu yüzden biraz rötuş yapmanın zamanı geldi diye düşünüyorum. Bu cevabın gereksiz yere uzun ve karmaşık kısımlarının okunmasını hızlandırmaya yardımcı olmak için sadece küçük bir yorum, açıklama ve biçimlendirme.
obj // {"foo": "bar"}
delete obj["foo"]
obj // {}
obj["foo"] // undefined
Bir diziden silme
yapmayın. Bunun yerine Array.prototype.splice
kullanın.
arr // [1,2,3,4,5]
arr.splice(3,1); // 4
arr // [1,2,3,5]
var array = [1, 2, 3, 4];
delete array[2];
/* Expected result --> [1, 2, 4]
* Actual result --> [1, 2, null, 4]
*/
Gördüğünüz gibi, delete
her zaman beklenildiği gibi çalışmaz. Değerin üzerine yazılır, ancak bellek yeniden tahsis edilmez. Yani, dizi[4]
değeri dizi[3]
değerine taşınmaz. Bu, dizinin başına bir eleman ekleyen ve her şeyi yukarı kaydıran Array.prototype.unshift
ile tezat oluşturur (array[0]
, array[1]
olur, vb.)
Dürüst olmak gerekirse, undefined
yerine null
olarak ayarlanması dışında - ki bu yasal olarak gariptir - bu davranış şaşırtıcı olmamalıdır, çünkü delete
, typeof
gibi, dilde zor kaynatılan ve üzerinde kullanıldığı nesnenin türünü önemsememesi gereken tek değişkenli bir operatördür, oysa Array
, dizilerle çalışmak için özel olarak tasarlanmış yöntemlere sahip bir Object
alt sınıfıdır. Bu yüzden delete
metodunun diziyi yeniden kaydırmak için özel bir duruma sahip olması için iyi bir neden yoktur, çünkü bu sadece gereksiz işlerle işleri yavaşlatacaktır. Geriye dönüp baktığımda, beklentilerimin gerçekçi olmadığını görüyorum.
Tabii ki, bu beni şaşırttı. Çünkü bunu "null garbage"'a karşı haçlı seferimi haklı çıkarmak için yazdım:
null
un doğasında olan tehlikeleri ve sorunları ve boşa harcanan alanı göz ardı edersek, dizinin kesin olması gerekiyorsa bu sorunlu olabilir. Bu,null
lardan kurtulmak için korkunç bir gerekçedir -null
yalnızca yanlış kullanıldığında tehlikelidir ve "hassasiyet" ile hiçbir ilgisi yoktur. Bir dizidensilme
yapmamanızın gerçek nedeni, çöp dolu ve dağınık veri yapılarını etrafta bırakmanın özensiz ve hata eğilimli olmasıdır. Aşağıda anlatılanlar oldukça uzun soluklu bir senaryodur, bu nedenle isterseniz Çözüm bölümüne geçebilirsiniz. Bu bölümü bırakmamın tek nedeni, bazı insanların muhtemelen bunun komik olduğunu düşündüğünü düşünmem ve "komik" bir cevap yayınlayan ve daha sonra "komik" olan her şeyi silen "o adam" olmak istemememdir. ...Bu aptalca, biliyorum.Yapmacık ve uzun soluklu PDP-11 senaryosu
Örneğin, 'tabs' için kullanılan bir diziyi bir dizede (bu durumda,
localStorage
) saklamak için JSON serileştirme kullanan bir web uygulaması oluşturduğunuzu varsayalım. Ayrıca, kodun ekrana çizim yaparken "title" için dizi'üyelerinin sayısal indekslerini kullandığını varsayalım. Neden sadece "başlığı" da saklamak yerine bunu yapıyorsunuz? Çünkü... nedenler. Tamam, diyelim ki 1960'lardan kalma UNIX çalıştıran bir PDP-11 mini bilgisayar kullanan ve X11 söz konusu olmadığı için kendi Elinks tabanlı, JavaScript uyumlu, satır yazıcı dostu tarayıcısını yazan bu bir kullanıcının isteği üzerine bellekten tasarruf etmeye çalışıyorsunuz. Giderek aptallaşan uç durum senaryosu bir yana, söz konusu dizi üzerindedelete
kullanmaknull
un diziyi kirletmesine ve muhtemelen daha sonra uygulamada hatalara neden olacaktır. Ve eğernull
olup olmadığını kontrol ederseniz, sekmelerin[1][2][4][5] ...
gibi görünmesine neden olan sayıları doğrudan atlayacaktır. if (array[index] == null) devam et; else title = (index + 1).toString(); /* 0 -> "1"
- 1 -> "2"
- 2 -> (hiçbir şey)
- 3 -> "4" */ Evet, kesinlikle istediğin bu değildi. Şimdi, sadece diziden geçerli değerler okunduğunda artırmak için
j
gibi ikinci bir yineleyici tutabilirsiniz. Ancak bunull
sorununu tam olarak çözmez ve hala otrollPDP-11 kullanıcısını memnun etmeniz gerekir. Ne yazık ki, onun bilgisayarında son tamsayıyı tutacak kadar bellek yok (değişken genişlikli bir diziyi nasıl idare ettiğini sormayın...). Bu yüzden size öfkeyle bir e-posta gönderir: Hey, web uygulamanız tarayıcımı bozdu! Aptal kodunuz tarayıcımı segfault yaptıktan sonra localStorage veritabanımı kontrol ettim ve bunu buldum:"tabs:['Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ... ]" Değerli verilerimi temizledikten sonra tekrar segfault verdi ve bir backtrace yaptım ve ne buldum? NE BULDUM!? ÇOK FAZLA DEĞIŞKEN KULLANIYORSUN! var i = index; var j = 1; Grr, şimdi sinirliyim. -Troll Davidson Şu anda aklınız başınızdan gitmiş durumda. Bu adam uygulamanız hakkında durmadan şikayet ediyor ve siz de ona çenesini kapamasını ve gidip daha iyi bir bilgisayar almasını söylemek istiyorsunuz.
Çözüm:
Array.prototype.splice
Neyse ki, diziler * indisleri silmek ve belleği yeniden tahsis etmek için özel bir yönteme sahiptir:
Array.prototype.splice()
. Bunun gibi bir şey yazabilirsiniz:
Array.prototype.remove = function(index){
this.splice(index,1);
}
...
array = [1, 2, 3, 4];
array.remove(2);
// Result -> [1, 2, 4]
Ve böylece Bay PDP-11'i memnun etmiş oldunuz. Yaşasın! (Ben yine de onu azarlardım...)
Bu iki benzer isimli fonksiyon arasındaki farkı belirtmenin önemli olduğunu düşünüyorum, çünkü her ikisi de çok kullanışlıdır.
.splice()diziyi değiştirir ve kaldırılan indisleri döndürür. Dizi
startindisinden başlayarak dilimlenir ve
neleman dilimlenir. Eğer n belirtilmemişse,
startdizisinden sonraki tüm dizi dilimlenir (
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]
.slice()yıkıcı değildir ve
startile
endarasında belirtilen indisleri içeren yeni bir dizi döndürür. Eğer
endbelirtilmemişse, davranış
.splice()ile aynıdır (
end = array.length). Davranış biraz karmaşıktır, çünkü bazı nedenlerden dolayı
end0 yerine 1
den indis alır. Bunu neden yaptığını bilmiyorum, ama böyle. Ayrıca, eğer end <= start
ise, sonuç boş bir dizidir.
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]
Aslında olan şey bu değil, ama bu şekilde düşünmek daha kolay. MDN'ye göre, gerçekte olan şu:
// 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
endile belirtilen dizin basitçe dilimden çıkarılır. Parantez içindeki indisler neyin dilimleneceğini gösterir. Her iki durumda da, davranış sezgisel değildir ve bire bir hataların adil payına neden olması kaçınılmazdır, bu nedenle
.splice()` davranışını daha yakından taklit etmek için bir sarmalayıcı işlev yapmayı yararlı bulabilirsiniz:
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);
}
Sarmalayıcı işlevin türler konusunda çok katı olacak şekilde tasarlandığını ve herhangi bir şey yanlışsa null
döndüreceğini unutmayın. Buna "3"
gibi bir dize koymak da dahildir. Türler konusunda özenli olmak programcıya bırakılmıştır. Bu, iyi programlama uygulamalarını teşvik etmek içindir.
is_array()
ile ilgili güncellemeBu (artık kaldırılmış olan) parçacıkla ilgilidir:
function is_array(array){
return array !== null
&& typeof array === "object"
&& typeof array.length !== "undefined"
&& array.__proto__ === Array.prototype;
}
Görünüşe göre, bir dizinin gerçekten bir dizi olup olmadığını anlamanın yerleşik bir yolu var ve bu da ECMAScript 5'te (Aralık 2009) tanıtılan Array.isArray()
. Bunu, dizileri nesnelerden ayırmakla ilgili bir soru olup olmadığına bakarken, benimkinden daha iyi bir çözüm olup olmadığını görmek ya da yoksa benimkini eklemek için buldum. Eğer ECMA 5'ten daha eski bir JavaScript sürümü kullanıyorsanız, işte size polyfill. Ancak, benim is_array()
fonksiyonumu kullanmamanızı şiddetle tavsiye ederim, çünkü JavaScript'in eski sürümlerini desteklemeye devam etmek, onları uygulayan eski tarayıcıları desteklemeye devam etmek anlamına gelir, bu da güvensiz yazılım kullanımını teşvik etmek ve kullanıcıları kötü amaçlı yazılım riski altına sokmak anlamına gelir. Bu yüzden lütfen Array.isArray()
fonksiyonunu kullanın. letve
constkullanın. Dile eklenen yeni özellikleri kullanın. *Satıcı öneklerini kullanmayın. *IE polyfill saçmalığını web sitenizden silin. XHTML
<!CDATA[[...` saçmalığını da silin - HTML5'e 2014 yılında geçtik. Herkes bu eski/ezoterik tarayıcılardan desteğini ne kadar çabuk çekerse, tarayıcı üreticileri de web standardını o kadar çabuk takip edip yeni teknolojiyi benimseyecek ve daha güvenli bir web'e o kadar çabuk geçebileceğiz.