मैं किसी सरणी में नामित गुणों को क्यों जोड़ सकता हूं जैसे कि वह एक वस्तु थी?


105

निम्नलिखित दो भिन्न कोड स्निपेट मेरे समतुल्य लगते हैं:

var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";

तथा

var myObject = {'A': 'Athens', 'B':'Berlin'};

क्योंकि वे दोनों समान व्यवहार करते हैं, और typeof(myArray) == typeof(myObjects)(दोनों 'वस्तु') भी।

क्या इन भिन्नताओं में कोई अंतर है?

जवाबों:


131

वस्तुतः जावास्क्रिप्ट में सब कुछ एक वस्तु है, इसलिए आप उस पर मनमाना गुण स्थापित करके एक सरणी वस्तु का "दुरुपयोग" कर सकते हैं । इसे हानिकारक माना जाना चाहिए , हालांकि। अंक संख्यात्मक रूप से अनुक्रमित डेटा के लिए हैं - गैर-संख्यात्मक कुंजी के लिए, एक ऑब्जेक्ट का उपयोग करें।

यहाँ एक और अधिक ठोस उदाहरण है कि गैर-संख्यात्मक कुंजी एक एरे को "फिट" क्यों नहीं करती हैं:

var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";

alert(myArray.length);

यह '2' प्रदर्शित नहीं करेगा, लेकिन '0' - प्रभावी रूप से, सरणी में कोई तत्व नहीं जोड़े गए हैं, बस कुछ नए गुण सरणी ऑब्जेक्ट में जोड़े गए हैं।


4
myArray.length सरणी में अंतिम तत्व का एक संख्यात्मक सूचकांक / कुंजी देता है, लेकिन तत्वों की वास्तविक संख्या नहीं। ऐरे ऑब्जेक्ट के गुण सरणी मान के समान नहीं हैं?
दशा सालो

1
मैं सिर्फ एरे ऑब्जेक्ट के अभिप्रायों को स्पष्ट करने की कोशिश कर रहा था, यदि आप इसे सिर्फ एक नियमित वस्तु की तरह मानते हैं तो इसका दुरुपयोग किया जाता है। जुड़ा हुआ लेख बेहतर काम करता है, हालांकि :)
पॉल डिक्सन

13
अगली बार जब कोई कहता है कि जावास्क्रिप्ट को विकसित करने के लिए एक अच्छी भाषा है, तो मैं उसे यह नमूना दिखाऊंगा। धन्यवाद।
ओलिवियर पोंस

@ ओलिवर, जिसे आप "बग" कहते हैं, वह एक भयानक "फीचर" हो सकता है। आप अपनी सामग्री या लंबाई को प्रभावित किए बिना और उनके साथ वस्तुओं में रैप करने के लिए बिना सरणियों के लिए एक टुकड़ी और विवरण जोड़ सकते हैं title, descriptionऔर itemsगुण। यह सब इस बात पर निर्भर करता है कि आप भाषा को कितनी अच्छी तरह जानते हैं और आप इसका उपयोग कैसे करते हैं।
ताओ

Arrays पर कस्टम गुणों का उपयोग स्वाभाविक रूप से गलत नहीं है। आपके द्वारा एक बार करने पर सरणी सदस्यों के रूप में कार्य करने के लिए उनसे क्या उम्मीद की जा रही है। वे सरणी गुण हैं, सदस्य नहीं, इसलिए सरणी विधियों से प्रभावित नहीं हैं। यह वास्तव में उपरोक्त लिंक लेख के लेखक द्वारा टिप्पणियों में कहा गया है। अब, सभी निष्पक्षता में, मैं इसके खिलाफ एक अभ्यास के रूप में सलाह दूंगा, क्योंकि यह शायद आपके कोड का उपयोग करने वाले लोगों से नरक को भ्रमित करेगा। या, यदि वे अभी शुरू कर रहे हैं, तो यह उन्हें एक खतरनाक पथ पर स्थापित करेगा, उदाहरण के लिए। लेकिन मैं यह नहीं कहूंगा कि जावास्क्रिप्ट खराब है क्योंकि यह सामान को अनुमति नहीं देता है।
ताओ

14

जेएस सरणियों में वस्तुएं हैं, बस थोड़ा संशोधित (कुछ और कार्यों के साथ)।

जैसे कार्य:

concat
every   
filer
forEach
join
indexOf
lastIndexOf
map
pop
push
reverse
shift
slice
some
sort
splice
toSource
toString
unshift
valueOf 

हालाँकि मुझे नहीं लगता कि सूचीबद्ध किए गए सभी कार्य अंतर्निहित जेएस कार्यान्वयन में हैं, आपको यह बात मिल गई है। दूसरा अंतर अलग-अलग प्रोटोटाइप होगा (जो उन अतिरिक्त कार्यों से निहित है)।
राशेक

6

मुझे लगता है, मुझे भी पिछले जवाब के साथ रूपक और गूढ़ है। क्लैरिफिकेशन इस प्रकार है।

ऐरे, बुलियन, दिनांक, फ़ंक्शन, संख्या, RegExp, स्ट्रिंग का एक उदाहरण एक वस्तु है, लेकिन प्रत्येक प्रकार के लिए विशिष्ट विधियों और गुणों के साथ बढ़ाया जाता है। उदाहरण के लिए, एक सरणी में एक पूर्वनिर्धारित lengthसंपत्ति होती है जबकि जेनेरिक ऑब्जेक्ट नहीं होते हैं।

javascript:alert([].length+'\n'+{}.length)

प्रदर्शित करता है

0
अपरिभाषित

आंतरिक रूप से, एफएफ गेको दुभाषिया भाषा के मूल्यांकन के साथ अलग-अलग मतभेदों के साथ एरे और जेनेरिक वस्तुओं के बीच भी अंतर करता है।

javascript:
  ra=[  "one",   "two",   "three"]; ra.a=4;
  ob={0:"one", 1:"two", 2:"three"}; ob.a=4;
  alert(
    ra            +"\n\n"+
    ob            +"\n\n"+
    ra.toSource() +"\n\n"+
    ra.a          +"\t .toSource() forgot me! \n\n"+
    ra.length     +"\t and my length! \n\n"+
    ob.toSource());
  ps=""; for(i in ra)ps+=i+" "; alert(ps);  /* NB .length is missing! */
  ps=""; for(i in ob)ps+=i+" "; alert(ps);

प्रदर्शित

एक दो तीन

[वस्तु वस्तु]

["एक दो तीन"]

4 .toSource () मुझे भूल गया! 

3 और मेरी लंबाई! 

({0: "एक", 1: "दो", 2: "तीन", a: 4})

और 0 1 2 aऔर 0 1 2 a

सभी वस्तुओं के कार्य हैं इस कथन के बारे में:

यह न तो है और न ही वाक्य रचना शब्दार्थ सही तरह एक समारोह के रूप में एक मनमाना वस्तु उदाहरण का उपयोग करने के लिए है 123()या "abc"()या []()या {}()या obj()जहां objकिसी भी प्रकार के अलावा अन्य है Functionतो एक मनमाना वस्तु दृष्टान्त एक नहीं है, Function। हालाँकि, एक वस्तु दी गई है objऔर यह प्रकार है Array, Boolean, Date, ..., कैसे objएक के रूप में आया था Array, Boolean, Date, ...? एक क्या है Array, Boolean, Date, ...?

javascript:
    alert([Array, Boolean, Date, Function, 
              Number, Object, RegExp, String] . join('\n\n') );

प्रदर्शित करता है

function Array() {
    [native code]
}

function Boolean() {
    [native code]
}

function Date() {
    [native code]
}

function Function() {
    [native code]
}

function Number() {
    [native code]
}

function Object() {
    [native code]
}

function RegExp() {
    [native code]
}

function String() {
    [native code]
}

हर मामले में, संतुलन के बिना, वस्तु प्रकार एक के रूप में प्रकट होता है function परिभाषा के , इसलिए यह कथन कि सभी ऑब्जेक्ट फ़ंक्शन हैं! (जीभ-इन-गाल यह है कि मैंने जानबूझकर अस्पष्ट और ऑब्जेक्ट प्रकार के अंतर को धुंधला कर दिया है क्योंकि यह टाइप है! फिर भी, यह दिखाता है कि "आपके पास एक के बिना दूसरा नहीं हो सकता", ऑब्जेक्ट और फ़ंक्शन! कैपिटलाइज़ेशन प्रकार पर जोर देता है उदाहरण के लिए विरोध।)

दोनों एक कार्यात्मक और वस्तु प्रतिमान प्रोग्रामिंग करने के लिए मौलिक और निम्न स्तर दुभाषिया जे एस के लागू करने लगते निर्मित जैसे पुरातन, Mathऔर JSONऔर true

 javascript:alert([Math, JSON, true.toSource()].join("\n\n"));

प्रदर्शित करता है

[object Math]

[object JSON]

(new Boolean(true))

जावास्क्रिप्ट के विकास के समय, एक वस्तु-केंद्रित प्रोग्रामिंग शैली (OOP's - ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग स्टाइल - "s" मेरा अपना दंड है!) प्रचलन में थी और दुभाषिया को इसी तरह अधिक विश्वसनीयता प्रदान करने के लिए Java पर समान रूप से नामांकित किया गया था! । ऑटोमैटिक, रिकर्सिव फंक्शंस, फॉर्मल लैंग्वेज आदि के सिद्धांतों का अध्ययन करने वाली अधिक सारगर्भित और गूढ़ परीक्षाओं के लिए कार्यात्मक प्रोग्रामिंग तकनीकों को फिर से लागू किया गया और जैसे कि तालमेल नहीं था। हालाँकि, इन औपचारिक विचारों की ताकत जावास्क्रिप्ट में विशेष रूप से एफएफ के गेको इंजन (यानी। .toSource()) में लागू होने के रूप में स्पष्ट रूप से प्रकट होती है ।


फ़ंक्शन के लिए ऑब्जेक्ट परिभाषा विशेष रूप से संतोषजनक है क्योंकि इसे पुनरावृत्ति संबंध के रूप में परिभाषित किया गया है! यह परिभाषा का उपयोग कर परिभाषित किया गया है!

function Function() { [native code] }
और चूंकि एक फ़ंक्शन एक ऑब्जेक्ट है, वही भावना के लिए है
function Object() { [native code] }

अन्य परिभाषाओं में से अधिकांश एक स्थिर टर्मिनल मान से अलग हैं। हालांकि, eval()एक विशेष रूप से शक्तिशाली आदिम है और इसलिए एक स्ट्रिंग भी मनमाना कार्यक्षमता को एम्बेड कर सकता है।

फिर से ध्यान दें, ऊपर का उपयोग किया गया अस्पष्ट वस्तु प्रकार और उदाहरण भेद को अस्पष्ट करता है।


5

जावास्क्रिप्ट में सब कुछ आदिम प्रकार के अलावा एक वस्तु है।

कोड

var myArray = Array();

जबकि ऐरे ऑब्जेक्ट का एक उदाहरण बनाता है

var myObject = {'A': 'Athens', 'B':'Berlin'};

वस्तु वस्तु का एक उदाहरण बनाता है।

निम्नलिखित कोड का प्रयास करें

alert(myArray.constructor)
alert(myObject.constructor)

तो आप देखेंगे कि अंतर ऑब्जेक्ट कंस्ट्रक्टर के प्रकार में है।

एरे ऑब्जेक्ट के उदाहरण में एरे प्रोटोटाइप के सभी गुण और तरीके शामिल होंगे।


2

जावास्क्रिप्ट में सरणियों और अन्य वस्तुओं के बीच का अंतर। जबकि सरणियों में जादुई रूप से लंबाई की संपत्ति होती है, सरणियों के अलावा अन्य वस्तुओं के लिए ऐसी संपत्ति को लागू करने का कोई तरीका नहीं है।

var arrName = [];
arrName[5] = "test";
arrName.length; // <- 6

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


2

आप जावास्क्रिप्ट में लगभग कुछ भी करने के लिए नामित गुण जोड़ सकते हैं लेकिन इसका मतलब यह नहीं है कि आपको चाहिए। Arrayजावास्क्रिप्ट में एक सूची के रूप में इस्तेमाल किया जाना चाहिए, यदि आप Objectइसके बजाय एक साहचर्य सरणी का उपयोग करना चाहते हैं ।

सावधान रहें कि यदि आप वास्तव Arrayमें Objectउन गुणों के बजाय नामित गुणों के साथ उपयोग करना चाहते हैं तो for...ofलूप में पहुंच नहीं पाएंगे और जब JSON इसे चारों ओर से गुजरने के लिए एन्कोडिंग करता है तो आपको अप्रत्याशित परिणाम भी मिल सकते हैं। नीचे दिए गए उदाहरण देखें जहां सभी गैर-संख्यात्मक सूचकांक को अनदेखा किया जाता है:

let arr = [];
let obj = {};

arr['name'] = 'John';
obj['name'] = 'John';

console.log(arr);    // will output [name: "John"]
console.log(obj);    // will output {name: "John"}

JSON.stringify(arr); // will return [] <- not what you expected
JSON.stringify(obj); // will return {"name":"John"}

-1

{}-Notation कोड अच्छे बनाने के लिए सिर्फ वाक्य-चीनी है ;-)

जावास्क्रिप्ट में कार्यों के निर्माण जैसे कई समान निर्माण हैं, जहां फ़ंक्शन () केवल एक पर्याय है

var Func = new Function("<params>", "<code>");

3
फ़ंक्शन निर्माता फ़ंक्शन शाब्दिक के लिए एक पर्याय नहीं है। शाब्दिक रूप से शाब्दिक रूप से स्कोप है, जबकि कंस्ट्रक्टर वैश्विक है। {}शाब्दिक वस्तु संकेतन है, []शाब्दिक सरणी है, मुझे यकीन नहीं है कि आपके उत्तर का बिंदु क्या है।
जुआन मेंडेस

साथ ही, किसी भी कोड को निष्पादित करने से पहले घोषित फ़ंक्शन उपलब्ध हैं, फ़ंक्शन कंस्ट्रक्टर का उपयोग करने वाले असाइनमेंट तब तक उपलब्ध नहीं होते हैं जब तक कि कोड उन्हें निष्पादित नहीं करता है।
रॉबग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.