Object.create (नल) के साथ JS ऑब्जेक्ट बनाना?


150

मुझे JS ऑब्जेक्ट बनाने के बहुत से तरीके पता हैं, लेकिन मुझे Object.create(null)एक नहीं पता था ।

सवाल:

क्या यह बिल्कुल वैसा ही है:

var p = {}

बनाम

var p2 = Object.create(null);

?

जवाबों:


199

वे समकक्ष नहीं हैं। {}.constructor.prototype == Object.prototypeजबकि Object.create(null)कुछ से विरासत में नहीं मिलता है और इस तरह कोई भी गुण नहीं है।

दूसरे शब्दों में: एक जावास्क्रिप्ट ऑब्जेक्ट तब तक डिफ़ॉल्ट रूप से ऑब्जेक्ट से विरासत में मिलती है, जब तक कि आप इसे स्पष्ट रूप से इसके प्रोटोटाइप के रूप में अशक्त के साथ नहीं बनाते हैं: जैसे Object.create(null)

{}इसके बजाय के बराबर होगा Object.create(Object.prototype)


Chrome Devtool में आप देख सकते हैं कि Object.create(null)कोई __proto__संपत्ति नहीं है, जबकि {}है।

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


99

वे निश्चित रूप से समकक्ष नहीं हैं। मैं इस उत्तर को और अधिक पूरी तरह से समझाने के लिए लिख रहा हूं कि इससे क्या फर्क पड़ता है।

  1. var p = {};

    एक ऐसी वस्तु बनाता है जो गुणों और विधियों से विरासत में मिलती है Object

  2. var p2 = Object.create(null);

    एक वस्तु बनाता है जो कुछ भी वारिस नहीं करता है।

यदि आप किसी ऑब्जेक्ट को मानचित्र के रूप में उपयोग कर रहे हैं, और आप उपरोक्त विधि 1 का उपयोग करके एक ऑब्जेक्ट बनाते हैं, तो आपको मैप में लुकअप करते समय अतिरिक्त सावधानी बरतनी होगी। क्योंकि गुण और विधियाँ Objectविरासत में मिली हैं, इसलिए आपका कोड एक ऐसे मामले में चल सकता है जहाँ आपके द्वारा डाले गए नक्शे में कुंजियाँ होती हैं। उदाहरण के लिए, यदि आपने एक खोज की, तो आपको toStringएक फ़ंक्शन मिल जाएगा, भले ही आपने उस मूल्य को कभी नहीं रखा हो। आप इस तरह के आसपास काम कर सकते हैं:

if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
    // we actually inserted a 'toString' key into p
}

ध्यान दें कि कुछ को असाइन करना ठीक है p.toString, यह बस विरासत में दिए गए toStringफ़ंक्शन को ओवरराइड करेगा p

ध्यान दें कि आप सिर्फ p.hasOwnProperty('toString')इसलिए नहीं कर सकते क्योंकि आपने एक कुंजी "hasOwnProperty" में डाली होगी p, इसलिए हम इसे कार्यान्वयन में उपयोग करने के लिए बाध्य करते हैं Object

दूसरी ओर, यदि आप ऊपर विधि 2 का उपयोग करते हैं, तो आपको Objectनक्शे में दिखाई देने वाली चीजों के बारे में चिंता करने की आवश्यकता नहीं होगी ।

आप ifइस तरह से एक संपत्ति के अस्तित्व की जांच नहीं कर सकते हैं :

// Unreliable:
if (p[someKey]) {
    // ...
}

मान एक रिक्त स्ट्रिंग हो सकती है, हो सकता है false, या null, या undefined, या 0, या NaNयह जांचने के लिए कि क्या कोई संपत्ति मौजूद है, फिर भी आपको उपयोग करने की आवश्यकता होगी Object.prototype.hasOwnProperty.call(p, someKey)


6
एक संपत्ति के अस्तित्व की जाँच के लिए एक सरल विकल्प है:if (someKey in p) {
mrcrowl

2
@mrcrowl केवल अगर वे इस्तेमाल किया Object.create(null)। मैं इस तरह की धारणाएं नहीं बनाना पसंद करता हूं, भले ही आप बिल्कुल सही थे कि इसका इस्तेमाल किया गया था Object.create(null), कोड बदल सकता है, वस्तु को उस Objectबिंदु से बदला जा सकता है जो किसी बिंदु पर विरासत में मिला है । hasOwnPropertyहमेशा काम करता है।
doug65536 8

1
मुझे लगता है कि इस तरह से कुछ के बारे में सावधान रहना अनावश्यक होना चाहिए। मैं आपके उत्तर की सराहना करता हूं, लेकिन आपको जो भी कोड आपके साथ काम कर रहा है, उसके साथ काम करने के लिए दस्तावेज़ीकरण आपको आवश्यक रूप से एपी देना चाहिए। यदि आप github से कुछ यादृच्छिक कोड ले रहे हैं, तो आप इसे कांटा कर सकते हैं और कम प्रलेखित अपडेट से सुरक्षित रह सकते हैं। उल्लेख करने के लिए {}इतना अधिक प्रचलित नहीं है Object.create(null), कि यदि आपका कोड गलती से इस स्थान पर विरासत में मिली संपत्ति को पकड़ लेता है, तो आपके पास चिंता करने के लिए बड़े कीड़े होने की संभावना है। मैं केवल मामूली अनुकूलन के रूप में Object.create (नल) का उपयोग करने वाले लोगों को देख सकता हूं।
आहा।

डबल नकार के !!p[key]साथ अच्छा काम करता है Object.create(null)। लेकिन hasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)बुरा भी नहीं है
andreid

> ध्यान दें कि आप बस p.hasOwnProperty ('toString') नहीं कर सकते, क्योंकि आपने p में एक "hasOwnProperty" कुंजी डाली होगी, इसलिए हम इसे ऑब्जेक्ट में कार्यान्वयन का उपयोग करने के लिए बाध्य करते हैं। यह अनावश्यक है। इस स्थिति में, आप किसी भी तरीके का उपयोग नहीं कर सकते pक्योंकि हर विधि सम्मिलित की जा सकती है और इसलिए सुरक्षित नहीं है।
xianshenglu

1

ऑब्जेक्ट का उपयोग करके ऑब्जेक्ट बनाना, {}जिसका प्रोटोटाइप है, Object.prototypeजो Objectप्रोटोटाइप से बुनियादी कार्यों को विरासत में मिला है, जबकि ऑब्जेक्ट का उपयोग करके ऑब्जेक्ट Object.create(null)बनाना एक खाली ऑब्जेक्ट बना देगा जिसका प्रोटोटाइप शून्य है।


0

अगर किसी को लागू करने की तलाश है Object.create(null), तो यह जानने के लिए कि यह कैसे काम करता है। यह प्रयोग __proto__किया जाता है जो गैर-मानक है और इसलिए, मैं इसकी सिफारिश नहीं करता हूं

function objectCreateMimic()
{
  /*optional parameters: prototype_object, own_properties*/
  var P = arguments.length>0?arguments[0]:-1;
  var Q = arguments.length>1?arguments[1]:null;
  var o = {};
  if(P!==null && typeof P === "object")
  {
    o.__proto__ = P;
  }
  else if(P===null)
  {
    o.__proto__ = null;
  }
  if(Q!==null && typeof Q === "object")
  {
   for(var key in Q)
   {
     o[key] = Q[key];
   }
  }
  return o;
}

नोट : मैंने इसे लिखा था, जिज्ञासा से बाहर, और यह केवल सरल शब्दों में लिखा गया है, उदाहरण के लिए, मैं संपत्ति के विवरणकर्ताओं को दूसरी वस्तु से रिटर्न ऑब्जेक्ट में स्थानांतरित नहीं कर रहा हूं।


1
ध्यान दें कि गर्मियों में ECMAScript जारी होने के बाद, __proto__अब आधिकारिक रूप से भाषा का हिस्सा होगा ।
चिरू

1
क्यों -1में arguments.length>0?arguments[0]:-1;?
happy_marmoset

@happy_marmoset देर से प्रतिक्रिया देता है, लेकिन ऐसा लगता है कि यह सिर्फ एक अशक्त प्लेसहोल्डर है, ताकि Objectपहला तर्क न दिए जाने पर प्रोटोटाइप को बरकरार रखा जाए। परिवर्तनीय नाम यहां बहुत बेहतर हो सकते हैं।
माइक हिल

साथ ही, दूसरे पैरामीटर को वास्तविक गुणों के बजाय संपत्ति विवरणकों का वर्णन करना चाहिए । यहाँ देखें संदर्भ: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
माइक हिल

0

जब आप Object.create (नल) के साथ एक ऑब्जेक्ट बनाते हैं, तो इसका मतलब है कि आप बिना किसी प्रोटोटाइप के ऑब्जेक्ट बना रहे हैं। यहाँ नल का मतलब है प्रोटोटाइप श्रृंखला का अंत। फिर भी जब आप {} ऑब्जेक्ट प्रोटोटाइप बनाते हैं तो ऑब्जेक्ट जोड़ा जाएगा। इसलिए ये दो अलग-अलग वस्तुएं हैं, एक प्रोटोटाइप के बिना दूसरे के साथ। यह मदद करता है

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