Soru JavaScript'te Nesneleri Silme


JavaScript'lerle biraz kafam karıştı delete Şebeke. Aşağıdaki kod parçasını alın:

var obj = {
    helloText: "Hello World!"
};

var foo = obj;

delete obj;

Bu kod parçası yürütüldükten sonra, obj olduğu null, fakat foo hala tam olarak bir nesneyi ifade eder obj. Sanırım bu nesne aynı nesne foo işaret etti.

Bu beni şaşırtıyor, çünkü yazmayı bekledim delete obj nesneyi sildi obj bellekte işaret ediyordu - sadece değişken değil obj.

Bunun nedeni, JavaScript'in Çöp Toplayıcı'sının tutma / bırakma temelinde çalıştığı için, nesneye işaret eden başka değişkenler yoksa olur hafızadan kaldırılsın mı?

(Bu arada, testlerim Safari 4'te yapıldı.)


332
2018-04-12 23:18


Menşei


Senin referansın için. developer.mozilla.org/en/Core_JavaScript_1.5_Reference/... - Daniel A. White
Silme anahtar kelimesinin tam makalesi webcache.googleusercontent.com/... - Vitim.us
Yukarıdaki bağlantı şöyle olmalıdır: perfectionkills.com/understanding-delete - johnmdonahue
@Steve Harrison silme, javascript'te bir nesneyi silmek için değildir. Davanızdaki bir nesne anahtarını kaldırmak için kullanın var obj = { helloText: "Hello World!" }; var foo = obj; delete obj; nesne silinmez çek obj kullanımı sil: delete obj.helloText ve sonra kontrol et foo now foo is an empty object - Umair Ahmed
@UmairAhmed, Ücretsiz çeviri: "" " delete javascript'te nesneleri silmek için değil. delete bir nesne anahtarını kaldırmak için kullanılır. Senin durumunda var obj = { helloText: "Hello World!" }; var foo = obj; delete obj;Nesne silinmez. Kontrol obj. Ardından koş delete obj.helloText ve bunu görebilirsiniz foo şimdi boş bir nesneyi işaret ediyor. """ - Pacerier


Cevaplar:


Silme operatörü, sadece bir referansı silmez, hiçbir zaman bir nesnenin kendisini silmez. Nesnenin kendisini sildiyse, kalan diğer referanslar C ++ silme gibi sallanır. (Ve bunlardan birine erişmek bir çarpışmaya neden olur. Onları boşa döndürmek için, her nesne için silme veya fazladan bellekte ekstra çalışma olması anlamına gelir.)

Javascript toplanan çöp olduğundan, nesneleri kendileri silmenize gerek yoktur - artık onlara başvurmanın bir yolu olmadığında kaldırılacaklar.

Onlarla işiniz bittiğinde bir nesneye yapılan referansları silmek faydalı olabilir, çünkü bu, çöp toplayıcısına neyin geri alınabileceğine dair daha fazla bilgi verir. Referanslar büyük bir nesnede kalıyorsa, bu, programınızın geri kalanı aslında bu nesneyi kullanmasa bile, bunun iptal edilmesine neden olabilir.


419
2018-04-12 23:59



delete anahtar kelime, yalnızca bir nesnenin özelliklerine değil, değişkenlere yönelik çalışır. perfectionkills.com/understanding-delete - AlexJM
@AlexJM Evet, Guffa'dan gelen bir sonraki cevap (ve yorumları) bunu biraz ayrıntılı olarak tartışıyor. - Jesse Rusak
Bir nesnenin bir özelliği başka bir nesne olabilir. Örneğin; var obj = {a: {}}; delete obj.a; - AlexJM
Ama ... aslında değişkenler değildir window? - Soaku
@Soaku yerel değişkenler değil. (örneğin, var) - Jesse Rusak


delete Komutun normal değişkenler üzerinde sadece bir etkisi yoktur. Sonra delete emrinde mülkün değeri yok null, hiç mevcut değil.

Özellik bir nesne başvurusuysa, delete komut, nesneyi siler, ancak nesneyi siler. Çöp toplayıcı, başka bir referansı yoksa, nesneye dikkat edecektir.

Örnek:

var x = new Object();
x.y = 42;

alert(x.y); // shows '42'

delete x; // no effect
alert(x.y); // still shows '42'

delete x.y; // deletes the property
alert(x.y); // shows 'undefined'

(Firefox'ta test edilmiştir.)


150
2018-04-12 23:39



Bu, küresel kapsamda yürütülürse, x değişkeni sadece küresel bir özellik haline gelir window nesne ve delete x; gerçekten kaldırır x değişken tamamen. - Crescent Fresh
@crescentfresh: Sadece örtülü olarak bildirilen bir özelliktir. Örnekte olduğu gibi açıkça belirtilmişse, genel bir değişkendir ve silinemez. - Guffa
@Tarynn: Anlıyorum, sorunun nerede olduğu. Bunu konsolda yaparsanız, nedense x bazı tarayıcılarda uygun bir değişken olmayacaktır, ancak window nesne. Bu elbette konsolda bir problemdir ve kodun normal olarak nasıl yürütüldüğünü yansıtmaz. - Guffa
@Guffa Bir grup araştırmanın ardından, oylama yapmak için yeterli sayıda temsilcim olmadığının muhtemelen iyi bir şey olduğunu kabul etmek zorundayım. En içten özür dilerim, ve bana neyin neşelendiğini göstermek için zaman ayırdığınız için teşekkürler ... İşte tam bir explinasyon: perfectionkills.com/understanding-delete/#firebug_confusion - Tarynn
@chao: Anladım. Tarynn ile aynı problemi yaşıyorsunuz (önceki yorumlara bakınız). Bunu konsolda yaptığınızda, gerçek koddaki gibi çalışmıyor. - Guffa


"örtük olarak bildirilen değişkenler", genel nesnenin özellikleridir, bu nedenle silme, herhangi bir özellikte çalıştığı gibi çalışır. Var ile bildirilen değişkenler zararsızdır.


50
2017-07-13 20:54



İyi bahşiş, daha önce hiç bakmadım ... - jason
Var'ı hiç bu kadar zorlamadım. - Gavin
Bu harika bir nokta ve bir JS yakaladı. İnsanlar pencere varyasyonlarını silmeye alışırlar ve yerel değişkenlerle neden aynı şeyi yapamayacağını merak ederler. - welbornio
Aynı şey için de geçerli let. - Pacerier


Mozilla Dokümantasyonundan gelince, "örtük olarak bildirilen değişkenleri silmek için silme işlecini kullanabilirsiniz, ancak var deyimiyle bildirilenleri değil."

Bağlantı burada: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Operators:Special_Operators:delete_Operator


23
2018-04-12 23:42





@Guffa'nın cevabına göre. Aşağıdaki yöntemin benim için çalıştığını buldum:

var obj = {
    helloText: "Hello World!"
};

obj = null;

delete obj;

Objeyi ayarlayarak null önce, tüm referansı kaldırdınız, daha sonra tamamen silebilirsiniz.

Onu başka bir tarayıcıda test etmedim, fakat bu telefon hafızasında çalışıyor. 1.7.0


6
2018-06-21 06:56



umm .. sadece silmiyor musun null İşte? - lambinator
Yanılmış olabilirim ama burada cevaplar null olarak ayarlanmanın yararlı bir şey yapmayacağını öne sür. - Jon Biz
Sanırım burada 2 şey oldu: 1. null referansı kayboldu, 2. obj tarafından başvurulan nesne referansı da kayboldu. Yani muhtemelen yakında GC için işaretlenecek, çünkü hiçbir yerde referans yok. - Cardin
@Bohr, "Önce nesneyi null olarak ayarlayarak, tüm referansı kaldırmışsınız" diyorsunuz. Sonra aşağıdaki satırı ekleyelim obj değişken beyanı: var obj1 = obj;. şimdi obj = null deyim belirsiz obj nesneden referans. Fakat obj1 hala nesneyi başvurur. Yani yanılıyorsun gibi gözüküyor. - gumkins
@Bohr, Bu cevap tamamen yanlış. Eklemek 'use strict' ilk satırdan önce ve göreceksiniz hata  Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. Silemezsin vars, dönem. Sıkı mod ile yapmak, sıkı olmayan modda yaparken istisna atar hiç birşey yapmıyor. - Pacerier


delete java Script'de bir nesneyi silmek için kullanılmaz.

delete bir kaldırmak için kullanılır object key Senin durumunda

var obj = { helloText: "Hello World!" }; 
var foo = obj;
delete obj;

nesne silinmez, yine de objeleri kontrol edin  kullanımı sil:

delete obj.helloText

ve sonra kontrol et obj, foo, ikisi de boş nesne.


4
2018-04-15 10:55





Sadece bir buldum jsperf Bu konunun ışığında ilginç düşünebilirsiniz. (resmi tamamlamak için etrafta tutmak kullanışlı olabilir)

Karşılaştırır silmek, ayar boş ve ayar Tanımsız.

Ancak, birçok kez özelliği sildiğinizde / ayarladığınızda durumun sınandığını unutmayın.


2
2018-02-12 17:17





GC sorularının yanı sıra, performans için tarayıcının arka planda gerçekleştirdiği optimizasyonları göz önünde bulundurmalısınız.

http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/

Referansı geçersiz kılmak, Chrome'un kullandığı perde arkasındaki 'sınıf' değişikliklerini değiştirebileceğinden daha iyi görünebilir.


2
2018-04-07 22:51





IE 5 ile 8 arasında, bir host nesnesinin (Pencere, Global, DOM vb.) Özelliklerinde silme kullanıldığında TypeError "nesnesinin bu eylemi desteklemediği" bir hata vardır.

var el=document.getElementById("anElementId");
el.foo = {bar:"baz"};
try{
    delete el.foo;
}catch(){
    //alert("Curses, drats and double double damn!");
    el.foo=undefined; // a work around
}

Daha sonra mülkün anlamı tam bir değer kullanımının olup olmadığını kontrol etmeniz gerekiyorsa el.foo !== undefined Çünkü "foo" in el  IE'de her zaman doğru döner.

Gerçekten gerçekten kaybolmak için mülke ihtiyacın varsa ...

function hostProxy(host){
    if(host===null || host===undefined) return host;
    if(!"_hostProxy" in host){
       host._hostproxy={_host:host,prototype:host};
    }
    return host._hostproxy;
}
var el=hostProxy(document.getElementById("anElementId"));
el.foo = {bar:"baz"};

delete el.foo; // removing property if a non-host object

Eğer host nesnesini host api ile kullanmanız gerekiyorsa ...

el.parent.removeChild(el._host);

1
2017-11-17 22:03



Çok teşekkür ederim! - Vinyl Windows


Aynı makaleyi aramamda bu yazının karşısına çıktım. Ne yaptım bittim sadece dışarı çıkıyorum obj.pop() Nesnemdeki tüm kayıtlı değerler / nesneler böylece nesneyi yeniden kullanabilirim. Bu kötü bir uygulama olup olmadığından emin değil. Bu teknik, Chrome Dev araçları veya FireFox Web Konsolu'nda kodumu test etmem için kullanışlı oldu.


0
2017-08-04 07:30