2015-06-12 7 views
41

में 'ऑब्जेक्ट' बनाम 'ऑब्जेक्ट' बनाम तो, मैं new Object और Object की परिभाषा पर ES5 विनिर्देश को देख रहा हूं। मेरे आश्चर्य करने के लिए: - इलाज क्या मूल्यों के विभिन्न प्रकार के साथ होता हैईसीएमएस्क्रिप्ट स्पेक

  • new Object कैसे वस्तु निर्माता काम करता है की एक पूरी एल्गोरिथ्म वर्णन करता है। मूल रूप से ToObject गैर वस्तुओं पर - वस्तुओं पर पहचान और शून्य और अपरिभाषित पर बनाता है।
  • Object में शून्य और अपरिभाषित के लिए एक विशेष पहला कदम है जहां यह एक वस्तु बनाता है और फिर वस्तुओं पर प्राइमेटिव्स और पहचान पर ToObject पर कॉल करता है।

विवरण पढ़ने के बाद कुछ बार - वे समान लगते हैं। हालांकि, स्पष्ट रूप से वे स्पेक से कुछ अलग-अलग हैं। Array में उदाहरण के लिए - new Array बुला the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.`

के रूप में निर्दिष्ट किया जाता है तो - new Object और Object के बीच क्या अंतर है? वे अलग-अलग क्यों निर्दिष्ट किए गए थे?

आसानी से - यहां एक link to the spec है।

+0

जेएस रूम लोग (अर्थात् जन ड्रोकोवा) ने अनुमान लगाया कि इसे होस्ट ऑब्जेक्ट्स के साथ करना है, लेकिन मैं वास्तव में कोई फर्क नहीं पड़ता था। –

+0

'नया ऑब्जेक्ट' होस्ट ऑब्जेक्ट्स पर क्रियान्वयन-परिभाषित है। मैं अभी भी एक उदाहरण देखना चाहता हूं जब यह पहचान नहीं है। –

+14

क्या यह उन प्रसिद्ध प्रश्नों में से एक होगा? –

उत्तर

16

Object(window) कभी भी window क्लोन नहीं करेगा लेकिन new Object(window) हो सकता है। सभी मौजूदा - संभावित रूप से सभी ज्ञात - कार्यान्वयन केवल एक ही संदर्भ को वापस करते हैं, हालांकि spec कार्यान्वयन-परिभाषित व्यवहार के लिए अनुमति देता है।

15.2.1.1 के लिए चरणों का

कहते हैं:

  1. यदि मान, अशक्त अपरिभाषित है या नहीं की आपूर्ति की है, बना सकते हैं और एक नई वस्तु वस्तु लौट बिल्कुल के रूप में करता है, तो मानक निर्मित वस्तु निर्माता कहा जाता है किया गया था उसी तर्क के साथ
  2. वापसी ToObject (मान)।

ToObject (9,9) की परिभाषा में कुछ प्रकार है कि चरण 1 (तालिका 14 में) द्वारा पकड़ा हो जाएगा सूचीबद्ध करता है, लेकिन Object के लिए एक बहुत ही सरल परिभाषा है:

परिणाम है इनपुट तर्क (कोई रूपांतरण नहीं)।

यह स्पष्ट रूप से कहता है कि इनपुट तर्क के रूप में वापस किया जाएगा, इसलिए वे बराबर संदर्भ (===) होना चाहिए।

के लिए new Object (15.2.2.1) परिभाषा चरण 1 में टाइप-जांच की एक ऐसी ही श्रृंखला है, लेकिन वस्तुओं के लिए कदम (1.a) है:

मैं। यदि मान मूल ईसीएमएस्क्रिप्ट ऑब्जेक्ट है, तो कोई नई ऑब्जेक्ट न बनाएं लेकिन केवल मूल्य वापस करें।

ii। यदि मान होस्ट ऑब्जेक्ट है, तो क्रियाएं की जाती हैं और परिणाम कार्यान्वयन-निर्भर तरीके से वापस आ जाता है जो होस्ट ऑब्जेक्ट पर निर्भर हो सकता है।

यही है, किसी भी मेजबान वस्तु foo के लिए, कॉल Object(foo) चाहिए === foo लेकिन new Object(foo) मई === foo

होस्ट वस्तुओं 4.3.8 में परिभाषित कर रहे हैं

वस्तु मेजबान वातावरण द्वारा आपूर्ति ECMAScript के निष्पादन के वातावरण को पूरा करने के किया जाना है।

This answer सूचियों में कुछ मेजबान वस्तुओं को शामिल करने के window, history, आदि new Object(foo)चाहिए के माध्यम से उन चल रहा है (लेकिन नहीं है) एक अलग वस्तु लौटने।

किसी भी मामले लेकिन एक मेजबान वस्तु गुजर में, new Object(foo) एक और अधिक जटिल श्रृंखला है कि Object(foo) के रूप में ज्यादा एक ही तरीके से ToObject को defers हो रहा है।

दुर्भाग्यवश, 15.2.2.1.1.a.ii बताता है कि "परिणाम कार्यान्वयन-निर्भर तरीके से वापस आ गया है" और इसमें "क्रियाएं [उन] किए गए कार्यों" के बारे में कोई विशिष्ट जानकारी नहीं है और ऐसा लगता है कि क्रोम सूचीबद्ध सभी "होस्ट ऑब्जेक्ट्स" के लिए एक ही ऑब्जेक्ट (बराबर संदर्भ) लौटाएं।

जाँच करने के लिए इस स्क्रिप्ट का उपयोग करना:

var objects = [ 
 
    /* Native objects */ 
 
    'Object', 'Date', 'Math', 'parseInt', 'eval', 
 
    /* Host objects */ 
 
    'window', 'document', 'location', 'history', 'XMLHttpRequest', 'setTimeout' 
 
]; 
 

 
function getDefinedReference(name) { 
 
    if (eval('typeof ' + name) !== 'undefined') { 
 
    return eval(name); 
 
    } else { 
 
    throw new Error('' + name + ' is not defined.'); 
 
    } 
 
} 
 

 
function checkIdentity(name) { 
 
    try { 
 
    var ref = getDefinedReference(name); 
 
    var no = new Object(ref); 
 
    var o = Object(ref); 
 

 
    console.log(name, ref === no, ref === o, no === o); 
 

 
    if (ref === o && no !== o) { 
 
     // Make sure ref === Object(ref) but not new Object(ref) 
 
     console.log(name, 'returns different references.'); 
 
    } 
 
    } catch (e) { 
 
    console.warn(e); 
 
    } 
 
} 
 

 
objects.forEach(checkIdentity); 
 

 
if (typeof window !== 'undefined') { 
 
    for (var f in window) { 
 
    checkIdentity(f); 
 
    } 
 
}

जहां Object और new Object व्यवहार अलग ढंग से किसी भी वस्तुओं नहीं मिल रहा है। @ Xotic750 सही लगता है कि यह कार्यान्वयन-निर्भर हो सकता है, लेकिन कोई भी इसका उपयोग नहीं कर रहा है।

+1

क्या आप एक क्रियान्वयन और एक होस्ट ऑब्जेक्ट पा सकते हैं जो 'ऑब्जेक्ट' और 'नया ऑब्जेक्ट' के बीच भिन्न है? –

+0

@ बेंजामिनग्रेनबाम अभी भी देख रहे हैं। मुझे दृढ़ता से संदेह है कि यह कुछ ऐसा है जो कल्पना की अनुमति देता है लेकिन कोई भी इसका उपयोग नहीं कर रहा है, लेकिन एक परीक्षण सूट चोट नहीं पहुंचा सकता है। – ssube

+0

@AwalGarg कि दो नव निर्मित वस्तुओं का संदर्भ समान नहीं है- {{} === {} ' –

संबंधित मुद्दे