जावास्क्रिप्ट में वस्तुओं को हटाना


359

मैं जावास्क्रिप्ट deleteऑपरेटर के साथ थोड़ा भ्रमित हूं । निम्नलिखित कोड कोड लें:

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

var foo = obj;

delete obj;

कोड के इस टुकड़े के बाद निष्पादित किया गया है, objहै null, लेकिन fooअभी भी बिल्कुल उसी तरह एक वस्तु को संदर्भित करता है obj। मैं अनुमान लगा रहा हूं कि यह वस्तु वही वस्तु है जो fooइंगित की गई है।

यह मुझे भ्रमित करता है, क्योंकि मुझे उम्मीद है कि लेखन delete objने उस ऑब्जेक्ट को हटा दिया objथा जो स्मृति में इंगित कर रहा था - न कि केवल चर obj

इस वजह जावास्क्रिप्ट का कचरा कलेक्टर, एक बनाए रखने / रिलीज के आधार पर काम कर रहा है ताकि अगर मैं वस्तु की ओर इशारा करते किसी अन्य चर नहीं था, यह है होगा स्मृति से हटा दिया जाना?

(वैसे, मेरा परीक्षण सफारी 4 में किया गया था)



डिलीट कीवर्ड webcache.googleusercontent.com/…
Vitim.us

2
ऊपर लिंक होना चाहिए: perfectionkills.com/understanding-delete
johnmdonahue

1
@Sveve हैरिसन डिलीट एक वस्तु को हटाने के लिए नहीं है जावास्क्रिप्ट डिलीट यूज में किसी ऑब्जेक्ट को हटाने के लिए अपने केस में var obj = { helloText: "Hello World!" }; var foo = obj; delete obj;ऑब्जेक्ट को डिलीट न करें चेक objडिलीट का उपयोग: delete obj.helloTextऔर फिर चेक करेंfoo now foo is an empty object
उमैर अहमद

2
@UmairAhmed, नि: शुल्क अनुवाद: "" " deleteजावास्क्रिप्ट में वस्तुओं को हटाने के लिए नहीं है। deleteइसका उपयोग ऑब्जेक्ट कुंजी को हटाने के लिए किया जाता है। आपके मामले में var obj = { helloText: "Hello World!" }; var foo = obj; delete obj;, ऑब्जेक्ट हटा नहीं है। चेक करें obj। अगला, चलाएँ delete obj.helloTextऔर आप देख सकते हैं कि fooअब एक खाली बिंदु है। ऑब्जेक्ट। ""
पचेरियर

जवाबों:


448

डिलीट ऑपरेटर केवल एक संदर्भ को हटाता है, कभी भी ऑब्जेक्ट नहीं। यदि यह ऑब्जेक्ट को स्वयं हटा देता है, तो अन्य शेष संदर्भ लटक जाएंगे, जैसे कि C ++ डिलीट। (और उनमें से किसी एक को एक्सेस करने से दुर्घटना हो सकती है। उन सभी को शून्य करने का अर्थ होगा कि प्रत्येक वस्तु को हटाने या अतिरिक्त मेमोरी हटाने पर अतिरिक्त काम करना।)

चूंकि जावास्क्रिप्ट कचरा इकट्ठा किया जाता है, आपको ऑब्जेक्ट्स को स्वयं हटाने की आवश्यकता नहीं है - जब उन्हें अब संदर्भित करने का कोई तरीका नहीं है, तो उन्हें हटा दिया जाएगा।

किसी वस्तु के संदर्भों को हटाने के लिए यह उपयोगी हो सकता है यदि आप उनके साथ समाप्त हो गए हैं, क्योंकि इससे कचरा संग्रहकर्ता को पुनः प्राप्त करने में सक्षम होने के बारे में अधिक जानकारी मिलती है। यदि संदर्भ एक बड़ी वस्तु के लिए बने रहते हैं, तो इससे यह अप्राप्य हो सकता है - भले ही आपके कार्यक्रम के बाकी लोग वास्तव में उस वस्तु का उपयोग न करें।


23
deleteकीवर्ड केवल एक वस्तु का गुण, नहीं चर के लिए काम करता है। perfectionkills.com/understanding-delete
एलेक्स मुंड

1
@AlexJM हां, गुफ़ा (और इसकी टिप्पणी) से अगला उत्तर कुछ विस्तार से इस पर चर्चा करता है।
जेसी रूसक

1
एक वस्तु की संपत्ति दूसरी वस्तु हो सकती है। उदाहरण के लिए; var obj = {a: {}}; delete obj.a;
एलेक्स मुंड

2
लेकिन ... चर वास्तव में के गुण नहीं हैं window?
रेडक्लोवर

3
@Soaku स्थानीय चर नहीं है। (उदाहरण के लिए उन लोगों के साथ var)
जेसी रस्क

162

deleteआदेश नियमित चर, केवल गुणों पर कोई प्रभाव नहीं है। deleteआदेश के बाद संपत्ति का मूल्य नहीं है null, यह बिल्कुल मौजूद नहीं है।

यदि संपत्ति एक ऑब्जेक्ट संदर्भ है, तो deleteकमांड संपत्ति को हटा देती है, लेकिन ऑब्जेक्ट को नहीं। कचरा संग्रहकर्ता वस्तु का ध्यान रखेगा यदि इसके पास कोई अन्य संदर्भ नहीं है।

उदाहरण:

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'

(फ़ायरफ़ॉक्स में परीक्षण किया गया।)


39
यदि इसे वैश्विक दायरे में निष्पादित किया xजाता है , तो आपका चर वैश्विक windowऑब्जेक्ट पर सिर्फ एक संपत्ति बन जाता है , और delete x;वास्तव में xचर को पूरी तरह से हटा देता है।
क्रीसेंट फ्रेश

18
@ क्रेस्टसेन्फ्रेश: यह केवल एक संपत्ति है अगर इसे स्पष्ट रूप से घोषित किया जाता है। यदि इसे स्पष्ट रूप से उदाहरण के रूप में घोषित किया गया है, तो यह एक वैश्विक चर है और इसे हटाया नहीं जा सकता।
गुफ़ा

4
@Tarynn: मैं देख रहा हूँ, कि जहाँ समस्या है। यदि आप कंसोल में ऐसा करते हैं, तो किसी कारण xसे कुछ ब्राउज़रों में एक उचित चर नहीं होगा, लेकिन windowऑब्जेक्ट में एक संपत्ति । यह निश्चित रूप से कंसोल के साथ एक समस्या है, और यह प्रतिबिंबित नहीं करता है कि कोड को सामान्य रूप से कैसे निष्पादित किया जाता है।
गुफ़ा

2
@Guffa अनुसंधान के एक समूह के बाद मुझे यह स्वीकार करना होगा कि शायद यह एक अच्छी बात थी कि मुझे वोट देने के लिए पर्याप्त प्रतिनिधि नहीं था। मेरी ईमानदारी से माफी, और मुझे यह दिखाने के लिए समय देने के लिए धन्यवाद कि क्या
ख़ुशी

2
@ कोच: मैं देख रहा हूँ। आपको टैरिन के रूप में एक ही समस्या हो रही है (पहले टिप्पणियां देखें)। जब आप कंसोल में ऐसा करते हैं तो यह वास्तविक कोड के समान काम नहीं करता है।
गुफा जूल

56

"वैरिएबल घोषित रूप से" वैश्विक ऑब्जेक्ट के गुण हैं, इसलिए उन पर काम हटाएं जैसे कि यह किसी भी संपत्ति पर काम करता है। Var के साथ घोषित चर अविनाशी हैं।


53
मुझे कभी एहसास ही नहीं हुआ कि वर इतना बदमाश था।
गैविन

1
यह एक महान बिंदु है, और एक जेएस गेटा है। लोगों को विंडो वर्जन हटाने की आदत होती है और फिर आश्चर्य होता है कि वे स्थानीय वैरिएबल के साथ ऐसा क्यों नहीं कर सकते।
वेलबोर्नियो

2
उसी के लिए जाता है let
पचेरियर

23

मोज़िला डॉक्यूमेंटेशन से आ रहा है, "आप डिलीट ऑपरेटर का उपयोग करके स्पष्ट रूप से घोषित किए गए वेरिएबल्स को हटा सकते हैं, लेकिन वे वेरिएशन के साथ घोषित नहीं होंगे।"

यहाँ लिंक दिया गया है: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Operators:Special_Operators:delete_Operator


4

delete जावा स्क्रिप्ट में किसी ऑब्जेक्ट को हटाने के लिए उपयोग नहीं किया जाता है।

deleteobject keyआपके मामले में एक हटाने के लिए इस्तेमाल किया

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

ऑब्जेक्ट हटाया नहीं गया है चेक करें obj अभी भी समान मान हटाएं उपयोग:

delete obj.helloText

और फिर जाँच करें obj, foo , दोनों खाली वस्तु हैं।


2

बस एक jsperf मिला जिसे आप इस मामले के प्रकाश में दिलचस्प मान सकते हैं। (चित्र पूरा करने के लिए इसे इधर-उधर रखना आसान हो सकता है)

यह हटाना , अशक्त करना और अपरिभाषित करना तुलना करता है ।

लेकिन ध्यान रखें कि यह उस स्थिति का परीक्षण करता है जब आप संपत्ति को कई बार हटाते / सेट करते हैं।


2

जीसी प्रश्नों के अलावा, प्रदर्शन के लिए किसी को उन अनुकूलन पर विचार करना चाहिए जो ब्राउज़र पृष्ठभूमि में कर रहा है ->

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

ऐसा प्रतीत होता है कि संदर्भ को हटाने के बजाय इसे हटाना बेहतर हो सकता है क्योंकि यह पीछे के दृश्यों के वर्ग के क्रोम उपयोग को बदल सकता है।


1

IE 5 8 के माध्यम से एक बग है जहां एक मेजबान ऑब्जेक्ट (विंडो, ग्लोबल, डोम आदि) के गुणों पर डिलीट का उपयोग करके टाइपएयर को फेंकता है "ऑब्जेक्ट इस कार्रवाई का समर्थन नहीं करता है"।

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
}

बाद में अगर आपको यह जांचने की आवश्यकता है कि संपत्ति का अर्थ पूर्ण मूल्य उपयोग है el.foo !== undefinedक्योंकि "foo" in el IE में हमेशा सही वापस आएगा।

यदि आपको वास्तव में वास्तव में गायब होने के लिए संपत्ति की आवश्यकता है ...

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

यदि आपकी आवश्यकता मेजबान एपीआई के साथ मेजबान वस्तु का उपयोग करने की है ...

el.parent.removeChild(el._host);

1

मैं इसी उत्तर के लिए अपनी खोज में इस लेख को ठोकर मार गया। मैंने obj.pop()जो कुछ किया वह मेरी वस्तु में सभी संचित मूल्यों / वस्तुओं को भर रहा है ताकि मैं वस्तु का पुन: उपयोग कर सकूं। यकीन नहीं होता कि यह बुरा अभ्यास है या नहीं। यह तकनीक मेरे लिए क्रोम देव टूल्स या फायरफॉक्स वेब कंसोल में अपने कोड का परीक्षण करने के लिए काम आई।


1

यह मेरे लिए काम करता है, हालांकि यह एक अच्छा अभ्यास नहीं है। यह बस संबंधित सभी तत्व को हटा देता है जिसके साथ ऑब्जेक्ट संबंधित है।

 for (element in homeService) {
          delete homeService[element];
  }

सबसे अच्छा अभ्यास क्या है? मुझे याद है कि ऑब्जेक्ट ऑपरेटर को हटाने के लिए डिलीट ऑपरेटर सबसे अच्छा अभ्यास नहीं था। मेरा मानना ​​है कि मैं इसे क्रॉकफोर्ड की जावास्क्रिप्ट पुस्तक में पढ़ता हूं, लेकिन फिलहाल इसे खोद नहीं सकता।
जीरो_कूल

0

nullDOM और जावास्क्रिप्ट स्कैल्प के बीच बनाए जा रहे सर्कुलर रेफरेंस सहित सभी ब्राउजर्स में ऑब्जेक्ट्स के किसी भी रेफरेंस को सुनिश्चित करने के लिए वैरिएबल सेट करना । deleteकमांड का उपयोग करके हम वस्तुओं को कचरा संग्रह के अगले भाग पर साफ करने के लिए चिह्नित कर रहे हैं, लेकिन यदि एक ही वस्तु को संदर्भित करने वाले कई चर हैं, तो एक ही चर को हटाना वस्तु को मुक्त नहीं करेगा, यह केवल उस चर के बीच के संबंध को हटा देगा। उदेश्य। और कचरा संग्रह के अगले भाग पर, केवल चर को साफ किया जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.