2015-09-17 5 views
14

मुझे "जावास्क्रिप्ट ऑब्जेक्ट उन्मुख और असाइन करने योग्य" प्रतिमान में सबकुछ उठाया गया था। तो मैं अपने लाइव खुश रह गया, जब तक ...जावास्क्रिप्ट में सब कुछ असाइन करने योग्य क्यों नहीं है?

var x = {}; 

x.field = true; 
x.field.netType = "System.Boolean"; 

alert(x.field.netType); 

यह संकलित करता है, लेकिन अलर्ट 'अपरिभाषित' से मुलाकात करता रहता है। क्यूं कर!?

+4

फेंक;' शीर्ष पर और जादू ;-) – thefourtheye

+1

@thefourtheye देखते हैं? सख्त मोड यहाँ क्या करेगा? – Pointy

+2

@ छात्र शिकायत करें। यह शिकायत करेगा। सख्त मोड वह चुनिंदा लड़की है जो आपको सबसे मोहक चीजें नहीं करने देती है, जबकि गैर-सख्त मोड oposite है। –

उत्तर

19

प्रिमिटिव (स्ट्रिंग, संख्याओं, true और false) जावास्क्रिप्ट में ऑब्जेक्ट नहीं है। हालांकि, जब उनका उपयोग . या [] के साथ किया जाता है जैसे कि ऑब्जेक्ट्स थे, तो भाषा उनके लिए ऑब्जेक्ट रैपरों को स्पष्ट रूप से निर्मित करके बाध्य करती है।

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

दूसरी ओर:

var x = {}; 

x.field = new Boolean(true); 
x.field.netType = "System.Boolean"; 

alert(x.field.netType); 

(मैं वास्तव में क्या कर रही है कि सलाह नहीं होगा, आदिम आवरण प्रकार से बने वस्तुओं का उपयोग कर अजीब प्रभाव के रूप में उन मूल्यों कोड है कि उम्मीद नहीं है में प्रचार जाता है उन्हें।)

+1

क्या इस व्यवहार के बारे में कोई दस्तावेज है? –

+3

@ KeesC.Bakker अच्छी तरह से [भाषा spec] (http://www.ecma-international.org/ecma-262/5.1/) है लेकिन यह आसान पढ़ने नहीं है।मैं कल्पना करता हूं कि किसी भी अच्छे जावास्क्रिप्ट संदर्भ को इस व्यवहार को छूना होगा, क्योंकि यह भाषा के लिए बहुत मौलिक है। एक स्ट्रिंग की लंबाई की जांच के रूप में सामान्य कुछ सामान्य वस्तु लपेटने का कारण बन जाएगा। – Pointy

+2

@ KeesC.Bakker: यह आपकी रूचि रख सकता है: https://github.com/getify/You-Dont-Know-JS/blob/master/types%20&%20grammar/ch3.md#boxing-wrappers। कल्पना में, मुक्केबाजी को यहां परिभाषित किया गया है: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-getvalue (लेकिन यह संदर्भ के बिना वास्तव में मूल्यवान नहीं है, यानी यह जानना कि कैसे/कहाँ ' GetValue' कहा जाता है)। –

10
x.field = true; 
x.field.netType = "System.Boolean"; 

वास्तव में काम कर रहा है।
x.field जो एक प्राचीन बूलियन मान है आंतरिक रूप से ऑब्जेक्ट में परिवर्तित हो रहा है लेकिन हमारे पास इसका संदर्भ नहीं है इसलिए यह कचरा बन जाता है। अगर हम x.field का रिफ्रेंस स्टोर करते हैं ताकि यह कचरा न हो, तो हम मूल्य प्राप्त कर सकते हैं। इस तरह ....

x.field = true; 
var y = x.field.netType = "System.Boolean"; 
alert(y); 

आप आप इस

var x = {}; 

x.field = {}; 
x.field.netType = "System.Boolean"; 

alert(x.field.netType); 

की तरह कोड लिखने हैं तो यह काम करेंगे।

अपने कोड इस लाइन x.field.netType = "System.Boolean"; केवल रैपर हैं `सख्त मोड

`//Cannot assign to read only property 'netType' of true` 

में त्रुटि फेंक होगा क्यों इस लाइन x.field.netType इस प्रकार के undefined

वस्तुओं देता है, उनके मूल्य आदिम है वे लपेटें और वे आम तौर पर आवश्यकतानुसार इस मूल्य के लिए मजबूर होंगे।

जावास्क्रिप्ट primitives and objects के बीच आसानी से सहयोग करेगा।

var a = 'Intekhab'; 
a.length;//In this case the string value is coerced to a string object in order to access the property length. 

var Twelve = new Number(12); 
var fifteen = Twelve + 3; // In this case Object Twelve is coerced to a primitive value. 
fifteen; //15 

जावास्क्रिप्ट एक आदिम यह वास्तव में एक वस्तु को आदिम विवश होगा करने के लिए एक संपत्ति आवंटित करने की कोशिश का पता लगाता है। इस नई वस्तु का कोई संदर्भ नहीं है और तुरंत कचरा संग्रह के लिए चारा बन जाएगा।

var primitive = "september"; 
primitive.vowels = 3; 
//new object created to set property 
(new String("september")).vowels = 3; 



primitive.vowels; 
//another new object created to retrieve property 
(new String("september")).vowels; //undefined 
+2

यह केवल आधा जवाब है ... यह बताता है कि आपको 'अपरिभाषित' क्यों मिलता है। लेकिन यह स्पष्ट नहीं करता कि असाइनमेंट पहले स्थान पर क्यों काम करता है। इसके अलावा, सवाल यह नहीं था कि इसे कैसे ठीक किया जाए, लेकिन इसके लिए क्या कारण है ... @Pointy द्वारा उत्तर * रास्ता * बेहतर है। –

+1

यह कुछ स्पष्ट रूप से पर्याप्त नहीं है और "गलत" है क्योंकि var t = new Boolean() कर रहा है; टी.एफयू = "बार"; वास्तव में काम कर रहा है। यह ओपी गुमराह कर सकते हैं। @ पॉइंटी उत्तर अधिक सटीक एटीएम है। –

+0

क्या आपके पास अपने उत्तर का समर्थन करने के लिए कोई दस्तावेज है? –

5

x.field एक बुलियन मूल्य है; बुलियन मूल्य प्राइमेटिव हैं और केवल पढ़ने के लिए हैं। जब आप x.field.netType पर मान निर्दिष्ट करने का प्रयास करते हैं, तो आप x.field के मान को संशोधित करने का प्रयास कर रहे हैं। पॉइंटी का जवाब ज्यादातर बताता है।

जब 'सामान्य' जावास्क्रिप्ट मोड में होता है, तो इसका परिणाम केवल undefined होता है।

कारण क्यों टिप्पणी में कोई सख्त मोड (जो आप निश्चित रूप से का उपयोग कर किया जाना चाहिए) ने सुझाव दिया है कि सख्त मोड आपको बताए कि आप केवल पढ़ने के लिए मूल्य को कोई मान निर्दिष्ट का प्रयास कर रहे एक त्रुटि फेंक होगा और जब भी आप उस संपत्ति तक पहुंचते हैं तो चुपचाप undefined लौटने की बजाय इसे करने से रोकें।

'use strict'; 
var foo = true; 
foo.bar = 'qux'; // this line will throw an Error 

नुकीले के उदाहरण के अनुसार, यह नोड 4.0 पर बहुत कम से कम त्रुटि, वास्तव में नहीं है। मुझे नहीं पता कि जेएस इंजन प्वाइंट क्या उपयोग कर रहा है लेकिन यह सही ढंग से काम नहीं कर रहा है।

` 'सख्त का उपयोग' में
> (function() { 'use strict'; (true).x = 0; })() 
TypeError: Cannot assign to read only property 'x' of true 
    at repl:1:38 
    at repl:1:45 
    at REPLServer.defaultEval (repl.js:154:27) 
    at bound (domain.js:254:14) 
    at REPLServer.runBound [as eval] (domain.js:267:12) 
    at REPLServer.<anonymous> (repl.js:308:12) 
    at emitOne (events.js:77:13) 
    at REPLServer.emit (events.js:169:7) 
    at REPLServer.Interface._onLine (readline.js:209:10) 
    at REPLServer.Interface._line (readline.js:548:8) 
+0

@ पॉइंटी क्योंकि मैं मुख्य उत्तर पर टिप्पणी नहीं कर सकता, आपका उदाहरण और सख्त मोड के बारे में प्रश्न यहां है। –

+0

@ माइक TheLiar आपका नाम आपको अच्छी तरह से उपयुक्त बनाता है! जावास्क्रिप्ट वास्तव में एक जेआईटी संकलित भाषा है और * कम से कम * IE9 के बाद से किया गया है। –

+0

Noje.js V8 इंजन (क्रोम के समान) का उपयोग करता है, जबकि हम (मुझे और पॉइंट) फ़ायरफ़ॉक्स का उपयोग कर रहे हैं। फ़ायरफ़ॉक्स में, यह त्रुटि नहीं करता है। लेकिन यह वी 8 इंजन पर करता है। –

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