फ्रीज और सील के बीच अंतर


164

मैंने अभी जावास्क्रिप्ट विधियों के बारे में सुना है freezeऔर sealइसका उपयोग किसी भी वस्तु को अपरिवर्तनीय बनाने के लिए किया जा सकता है।

इसका उपयोग करने का एक छोटा उदाहरण यहां दिया गया है:

var o1 = {}, o2 = {};
Object.freeze(o2);

o1["a"] = "worked";
o2["a"] = "worked";

alert(o1["a"]);   //prints "worked"
alert(o2["a"]);   //prints "undefined"

बीच क्या अंतर है freezeऔर seal? क्या वे प्रदर्शन बढ़ा सकते हैं?


6
इस प्रश्न को देखने वाले किसी भी व्यक्ति के लिए सिर्फ एक नोट, स्वीकृत उत्तर तथ्यात्मक रूप से गलत है। @ तुंगड का जवाब सही है।
ब्योर्न

2
एक और नोट, Object.preventExtensionsइसके अलावा Object.sealऔर भी है Object.freezeObject.preventExtensionsकिसी वस्तु में नई वस्तुओं को जोड़े जाने से रोकता है। आप उन वस्तुओं के गुणों को हटा सकते हैं, कॉन्फ़िगर कर सकते हैं, और बदल सकते हैं, जिन पर उनकी एक्स्टेंसिबिलिटी थी Object.preventExtensions
ब्योर्न

जवाबों:


193

Object.seal

  • यह सीलबंद वस्तु से गुणों को जोड़ने और / या हटाने से रोकता है; उपयोग करने deleteसे असत्य वापस आ जाएगा
  • यह हर मौजूदा संपत्ति को गैर-विन्यास योग्य बनाता है : उन्हें 'डेटा डिस्क्रिप्टर' से 'एक्सेसर डिस्क्रिप्टर' (और इसके विपरीत) में परिवर्तित नहीं किया जा सकता है, और एक्सेस डिस्क्रिप्टर की कोई विशेषता बिल्कुल भी संशोधित नहीं की जा सकती है (जबकि डेटा डिस्क्रिप्टर उनकी writableविशेषता को बदल सकते हैं , और उनकी valueविशेषता अगर writeableसच है)।
  • TypeErrorसील किए गए ऑब्जेक्ट के मूल्य को स्वयं संशोधित करने का प्रयास करते समय फेंक सकते हैं (सबसे आम तौर पर सख्त मोड में )

Object.freeze

  • वास्तव में क्या Object.sealकरता है, प्लस:
  • यह किसी भी मौजूदा गुणों को संशोधित करने से रोकता है

न तो कोई 'गहरी' पोते / पोतियों को प्रभावित करता है। उदाहरण के लिए, यदि objजमे हुए है , तो obj.elपुन: असाइन नहीं किया जा सकता है, लेकिन मूल्य को obj.elसंशोधित किया जा सकता है, उदाहरण के obj.el.idलिए बदला जा सकता है।


प्रदर्शन:

किसी ऑब्जेक्ट को सील या फ्रीज़ करना उसकी गणना की गति को प्रभावित कर सकता है, जो ब्राउज़र पर निर्भर करता है:

  • फ़ायरफ़ॉक्स: गणना प्रदर्शन प्रभावित नहीं है
  • IE: गणना प्रदर्शन प्रभाव नगण्य है
  • क्रोम: सीमांकित या जमे हुए वस्तुओं के साथ गणना प्रदर्शन तेज है
  • सफ़ारी: 92% धीमी (2014 के अनुसार) सीमांकित या जमी हुई वस्तुएँ

टेस्ट: सील की गई वस्तुएं , फ्रोजन ऑब्जेक्ट्स


2
क्या आप इस बारे में बात कर सकते हैं कि हम कभी इन तरीकों का इस्तेमाल क्यों करेंगे? सिर्फ इसलिए कि हम कर सकते हैं?
एलन डोंग

3
भविष्य में मुझे लगता है कि लाइब्रेरी / फ्रेमवर्क विकसित करते समय उनका बहुत उपयोग होने वाला है (यदि इसे सही ढंग से अनुकूलित किया गया है)। वे आपको उपयोगकर्ता को (यहां तक ​​कि अनजाने में) अपने कोड को रोकने की अनुमति देते हैं (और, जैसा कि उत्तर में कहा गया है, अनुकूलन को महान गति में सुधार करना चाहिए)। लेकिन यह शुद्ध अनुमान है :)
निकोलो कैम्पोलुंगो

2
इस उत्तर में कई तथ्यात्मक त्रुटियाँ हैं। एक के लिए, sealमौजूदा गुणों को भी गैर-विन्यास योग्य बनाता है, देखें jsfiddle.net/btipling/6m743whn नंबर 2, आप अभी भी संपादित कर सकते हैं, जो एक सील ऑब्जेक्ट पर मौजूदा गुणों के मूल्यों को बदल सकता है।
ब्योर्न

8
FWIW, जमे हुए और सील की गई वस्तुएं अब क्रोम कैनरी v43.0.21717.0 में उनके अप्रमाणित और अनसाल्टेड समकक्षों की तुलना में तेज़ हैं।
llambda

2
@AlanDong आने में थोड़ा देर हो गई, लेकिन यहाँ आप एक ऑब्जेक्ट को लॉक करना चाहते हैं। जावास्क्रिप्ट की विशेषताओं में से एक यह है कि आप अपनी पसंद के अनुसार किसी भी समय एक संपत्ति जोड़ सकते हैं; आप भी ऐसा कर सकते हैं गलती से गलत टाइपिंग द्वारा। मेरे कई छात्रों ने एक इवेंट हैंडलर जोड़ने का प्रयास किया है onClickया कहा है onlickकि यह काम क्यों नहीं कर रहा है। यदि जावास्क्रिप्ट एक त्रुटि फेंकता है, तो यह गलत होने के लिए एक कम चीज है। दूसरे, यह आपको एक वस्तु पर निरंतर गुणों को लागू करने की अनुमति देता है जो परिवर्तनों को रोकता है। यह वस्तु मेथजोड पर विशेष रूप से उपयोगी है।
मन्नंगो

119

मैंने एक परीक्षण परियोजना लिखी है जो इन 3 विधियों की तुलना करती है:

  • Object.freeze()
  • Object.seal()
  • Object.preventExtensions()

मेरी इकाई परीक्षण CRUD के मामलों को कवर करती है:

  • [सी] नई संपत्ति जोड़ें
  • [R] पढ़ी हुई संपत्ति मौजूद है
  • [यू] मौजूद संपत्ति को संशोधित करें
  • [डी] मौजूद संपत्ति को हटा दें

परिणाम:

यहां छवि विवरण दर्ज करें


2
ये जबरदस्त है। क्या UPDATE खाते को संशोधित करने (डिफाइनप्रोपरेटी के माध्यम से) में ले जाता है?
दिनाई

मैं हमेशा यद्यपि डोम ऑब्जेक्ट्स को सील किया जाना चाहिए (पॉलीफ़िल्स के बाद, निश्चित रूप से)। यह बहुत टाइपो त्रुटियों को रोकने में मदद करेगा।
मन्नंगो

@ मानगो आप अपने डोम ऑब्जेक्ट्स को सील कर सकते हैं। बस एक DEBUGMODEवेरिएबल बनाएं और इसे सेट करें true। फिर, करते हैं if (DEBUGMODE) { ... }। में ..., यह सुनिश्चित करने के लिए अपनी कार्यक्षमता डालें कि सभी DOM ऑब्जेक्ट हमेशा सील हो। तब, जब आप अपने वेबपेज स्क्रिप्ट, परिवर्तन वितरित करने के लिए तैयार कर रहे हैं DEBUGMODEकरने के लिए false, बंद संकलक के माध्यम से अपनी स्क्रिप्ट चलाने, और इसे वितरित। यह इतना सरल है।
जैक गिफिन

@JackGiffin टिप्पणी के लिए धन्यवाद। मैं सिर्फ यह कह रहा था कि मैंने हमेशा सोचा था कि यह एक अच्छा विचार होगा। मेरे पास बहुत से छात्र हैं जो कुछ टाइप करना पसंद करते हैं element.onlick=somethingऔर निराश हो जाते हैं क्योंकि यह काम नहीं करता है, लेकिन यह तकनीकी रूप से एक त्रुटि नहीं है।
19ng में मानेजो

2
@ तब तक यह सीआरयूडी को नहीं भाएगा। आपको RUDE;) जैसे कुछ के लिए समझौता करना होगा;
Manngo

84

आप हमेशा एमडीएन में इन्हें देख सकते हैं। संक्षेप में:

  • फ्रीज : ऑब्जेक्ट को अपरिवर्तनीय बनाता है, जिसका अर्थ है परिभाषित संपत्ति में कोई परिवर्तन नहीं, जब तक कि वे वस्तुएं न हों।
  • सील : संपत्तियों के अलावा को रोकें, हालांकि परिभाषित गुणों को अभी भी बदला जा सकता है।

1
Object.seal()प्रोटोटाइप गुण को स्थिर करने के लिए भी लगता है : \
K ..

10

Object.freeze()एक जमी हुई वस्तु बनाता है, जिसका अर्थ है कि यह एक मौजूदा वस्तु लेता है और अनिवार्य रूप Object.seal()से उस पर कॉल करता है, लेकिन यह सभी "डेटा एक्सेसर" गुणों को भी चिह्नित करता है writable:false, ताकि उनके मूल्यों को बदला नहीं जा सके। - काइल सिम्पसन, तुम नहीं जानते जेएस - यह और वस्तु प्रोटोटाइप


4

मैं ECMAScript 5 में फ्रीज़ और सील के बीच के अंतरों को देख रहा था और मतभेदों को स्पष्ट करने के लिए एक स्क्रिप्ट बनाई। जमे हुए डेटा और संरचना सहित एक अपरिवर्तनीय वस्तु बनाता है। सील नामित इंटरफेस में परिवर्तन को रोकता है - कोई जोड़ नहीं, हटाता है - लेकिन आप ऑब्जेक्ट को म्यूट कर सकते हैं और इसके इंटरफ़ेस के अर्थ को फिर से परिभाषित कर सकते हैं।

function run()
{
    var myObject = function() 
    { 
        this.test = "testing"; 
    }

    //***************************SETUP****************************

    var frozenObj = new myObject();
    var sealedObj = new myObject();

    var allFrozen = Object.freeze(frozenObj);
    var allSealed = Object.seal(sealedObj);
    alert("frozenObj of myObject type now frozen - Property test= " + frozenObj.test);
    alert("sealedObj of myObject type now frozen - Property test= " + sealedObj.test);

    //***************************FROZEN****************************

    frozenObj.addedProperty = "added Property"; //ignores add
    alert("Frozen addedProperty= " + frozenObj.addedProperty);
    delete frozenObj.test; //ignores delete
    alert("Frozen so deleted property still exists= " + frozenObj.test);
    frozenObj.test = "Howdy"; //ignores update
    alert("Frozen ignores update to value= " + frozenObj.test);
    frozenObj.test = function() { return "function"; } //ignores
    alert("Frozen so ignores redefinition of value= " + frozenObj.test);

    alert("Is frozen " + Object.isFrozen(frozenObj));
    alert("Is sealed " + Object.isSealed(frozenObj));
    alert("Is extensible " + Object.isExtensible(frozenObj));

    alert("Cannot unfreeze");
    alert("result of freeze same as the original object: " + (frozenObj === allFrozen).toString());

    alert("Date.now = " + Date.now());

    //***************************SEALED****************************

    sealedObj.addedProperty = "added Property"; //ignores add
    alert("Sealed addedProperty= " + sealedObj.addedProperty);
    sealedObj.test = "Howdy"; //allows update
    alert("Sealed allows update to value unlike frozen= " + sealedObj.test);
    sealedObj.test = function() { return "function"; } //allows
    alert("Sealed allows redefinition of value unlike frozen= " + sealedObj.test);
    delete sealedObj.test; //ignores delete
    alert("Sealed so deleted property still exists= " + sealedObj.test);
    alert("Is frozen " + Object.isFrozen(sealedObj));
    alert("Is sealed " + Object.isSealed(sealedObj));
    alert("Is extensible " + Object.isExtensible(sealedObj));

    alert("Cannot unseal");
    alert("result of seal same as the original object: " + (sealedObj === allSealed).toString());

    alert("Date.now = " + Date.now());
}

3

मुझे पता है कि मुझे थोड़ी देर हो सकती है लेकिन

  • समानता: दोनों का उपयोग गैर-एक्स्टेंसिबल ऑब्जेक्ट बनाने के लिए किया जाता है ।
  • अंतर: फ्रीज विन्यास में, ऑब्जेक्ट के गुणनीय और लिखने योग्य गुण सेट किए जाते हैं false। जहां के रूप में मुहरबंद लिखने योग्य विशेषता के लिए सेट किया गया है trueऔर बाकी विशेषताएँ झूठी हैं।

6
यह पूरी तरह सही नहीं है। Object.getOwnPropertyDescriptor(Object.freeze({ prop: 1 }), 'prop').enumerable=== true
लियोन एडलर

2

अब आप पूरी ऑब्जेक्ट को फ्रीज करने के बजाय एक ही ऑब्जेक्ट प्रॉपर्टी को फ्रीज करने के लिए मजबूर कर सकते हैं। आप के साथ इस लक्ष्य को हासिल कर सकते हैं Object.definePropertyके साथ writable: falseएक पैरामीटर के रूप।

var obj = {
    "first": 1,
    "second": 2,
    "third": 3
};
Object.defineProperty(obj, "first", {
    writable: false,
    value: 99
});

इस उदाहरण में, obj.firstअब इसका मूल्य 99 पर लॉक हो गया है।


0

मैंने नीचे दिए गए कार्यों की तुलना करने और इन कार्यों के बीच के अंतर को समझाने के लिए एक सरल तालिका बनाई है।

  • Object.freeze ()
  • Object.seal ()
  • Object.preventExtensions ()

तालिका जो उपरोक्त तीन विधियों के बीच के अंतर को बताती है

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