जावास्क्रिप्ट में संरचनाएं


112

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

function Item(id, speaker, country) {
    this.id = id;
    this.speaker = spkr;
    this.country = country;
}
var myItems = [
    new Item(1, 'john', 'au'),
    new Item(2, 'mary', 'us')
];

लेकिन मैं सोच रहा हूं कि क्या यह एक अच्छा अभ्यास है। जावास्क्रिप्ट में एक संरचना का अनुकरण करने के लिए कोई अन्य, बेहतर तरीके हैं?

जवाबों:


184

वस्तु शाब्दिक और निर्मित वस्तुओं के बीच एकमात्र अंतर प्रोटोटाइप से विरासत में मिली संपत्ति है।

var o = {
  'a': 3, 'b': 4,
  'doStuff': function() {
    alert(this.a + this.b);
  }
};
o.doStuff(); // displays: 7

आप एक संरचना कारखाना बना सकते हैं।

function makeStruct(names) {
  var names = names.split(' ');
  var count = names.length;
  function constructor() {
    for (var i = 0; i < count; i++) {
      this[names[i]] = arguments[i];
    }
  }
  return constructor;
}

var Item = makeStruct("id speaker country");
var row = new Item(1, 'john', 'au');
alert(row.speaker); // displays: john

27
... और फिर मुझे कारखाने के कार्य समझ में आ गए। फैक्ट्री उदाहरण के साथ एक स्पष्ट, समझने योग्य और संक्षिप्त उत्तर के लिए +1।
जॉन

यदि आप क्लोजर कंपाइलर का उपयोग करते हैं तो मुझे यह दृष्टिकोण पसंद है। टपल को केवल इस मामले में स्ट्रिंग के रूप में एक्सेस किया जा सकता है, क्योंकि गुणों का नाम बदल दिया गया है। (कम से कम एडवांस मोड में)
kap

मैं वस्तु शाब्दिकों पर इस पद्धति की दक्षता के बारे में उत्सुक था।
c0degeas

जेएस वर्ग का उपयोग करना भी संभव है।
स्फिंक्सटेक

31

मैं हमेशा ऑब्जेक्ट शाब्दिक का उपयोग करता हूं

{id: 1, speaker:"john", country: "au"}

2
इसे बनाए रखने में बहुत मुश्किल नहीं होगी (क्या आपको भविष्य में एक नया क्षेत्र जोड़ना चाहिए), और बहुत अधिक कोड ("आईडी", "स्पीकर", "देश" हर बार पुनर्प्राप्त करना)?
6

5
यह कक्षाओं के साथ समाधान के रूप में बनाए रखने योग्य है क्योंकि जावास्क्रिप्ट आपके द्वारा फ़ंक्शन को कॉल करने वाले तर्कों की संख्या की परवाह नहीं करता है। यदि आप Emacs जैसे सही टूल का उपयोग कर रहे हैं तो फिर से आना कोई समस्या नहीं है। और आप देख सकते हैं कि क्या समान है जो स्वैपिंग तर्कों जैसी गलतियों को अप्रचलित बनाता है।
वाव

4
लेकिन सबसे बड़ा समर्थक यह है कि आप कम कोड लिखेंगे और यह क्लीनर होगा :)
vava

1
@vava को फिर से तैयार करना अभी भी एक मुद्दा है, क्योंकि नए ___ (,,,) आर्काइव की नकल करने की तुलना में अधिक कूदता है। इसके अलावा, कोई पठनीयता नहीं है। एक बार जब आप कोडिंग करने के new READABLE_PART(ignore everything in here)अभ्यस्त हो जाते हैं, तो {read: "ignore", everything: "ignore", in: "ignore", here: "ignore"} // and then come up with READABLE_PARTआपके सिर में विरोध के रूप में बहुत ही स्कैन करने योग्य और स्व-दस्तावेजीकरण हो जाता है । पहला संस्करण तेजी से पेजिंग करते समय पठनीय है। दूसरा, आप केवल समझने के लिए संरचनाओं में रिफ्लेक्टर करते हैं।
क्रिस्टोफर

19

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


8

मुझे लगता है कि सी-जैसी संरचनाओं को अनुकरण करने के लिए एक वर्ग बनाना, जैसे आप कर रहे हैं, सबसे अच्छा तरीका है।

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

मैंने पाया है कि जावास्क्रिप्ट को किसी अन्य भाषा की तरह बनाने की कोशिश करना तेजी से जटिल हो जाता है, लेकिन मैं जावास्क्रिप्ट कक्षाओं का उपयोग कार्यहीन संरचनाओं के रूप में पूरी तरह से करता हूं।


मुझे स्ट्रक्चर्स, टुपल्स जैसा कुछ पसंद है - ऐसा कुछ जो डेटा के जोरदार टाइप किए गए कलेक्शन को अनुमति देता है - जिसे कंपाइलटाइम पर निपटाया जाता है और इसमें ऑब्जेक्ट्स की तरह हैशैप्स का ओवरहेड नहीं होता है
derekdreery

4

मार्कस के जवाब के बाद , जेएस (ईएस 6 मुझे लगता है) के नए संस्करणों में आप एरो फंक्शंस और रेस्ट पैरामीटर का उपयोग करके एक 'स्ट्रक्चर' फैक्ट्री को और अधिक बना सकते हैं :

const Struct = (...keys) => ((...v) => keys.reduce((o, k, i) => {o[k] = v[i]; return o} , {}))
const Item = Struct('id', 'speaker', 'country')
var myItems = [
    Item(1, 'john', 'au'),
    Item(2, 'mary', 'us')
];

console.log(myItems);
console.log(myItems[0].id);
console.log(myItems[0].speaker);
console.log(myItems[0].country);

इसे चलाने का परिणाम है:

[ { id: 1, speaker: 'john', country: 'au' },
  { id: 2, speaker: 'mary', country: 'us' } ]
1
john
au

आप इसे पायथन के नामपट्ट के समान बना सकते हैं:

const NamedStruct = (name, ...keys) => ((...v) => keys.reduce((o, k, i) => {o[k] = v[i]; return o} , {_name: name}))
const Item = NamedStruct('Item', 'id', 'speaker', 'country')
var myItems = [
    Item(1, 'john', 'au'),
    Item(2, 'mary', 'us')
];

console.log(myItems);
console.log(myItems[0].id);
console.log(myItems[0].speaker);
console.log(myItems[0].country);

और परिणाम:

[ { _name: 'Item', id: 1, speaker: 'john', country: 'au' },
  { _name: 'Item', id: 2, speaker: 'mary', country: 'us' } ]
1
john
au

यह C / C ++ और अन्य भाषाओं में संरचना की तरह दिखता है, लेकिन वास्तव में ऐसा नहीं है -, वस्तुओं में गुणों को निम्नलिखित के रूप में वर्णित किए जाने की गारंटी नहीं है: ECMAScript तीसरे संस्करण से एक वस्तु की परिभाषा (पीडीएफ): 4.3.3 वस्तु ऑब्जेक्ट ऑब्जेक्ट का एक सदस्य है। यह गुणों का एक अनियंत्रित संग्रह है, जिनमें से प्रत्येक में एक आदिम मूल्य, ऑब्जेक्ट या फ़ंक्शन होता है। किसी वस्तु की संपत्ति में संग्रहित एक कार्य को एक विधि कहा जाता है
tibetty

3

मैं गूंगा रचना (कोई सदस्य कार्य नहीं) के लिए ऑब्जेक्ट्स JSON शैली का उपयोग करता हूं।


1

यदि आप ES6 संगतता के साथ काम करते हैं तो मैंने संरचना को परिभाषित करने के लिए एक छोटी सी लाइब्रेरी बनाई।

यह एक जेकेटी पार्सर है जिसे आप प्रोजेक्ट रिपॉजिटरी यहां जेकेटी पार्सर के रूप में देख सकते हैं

एक उदाहरण के लिए आप इस तरह से अपनी संरचना बना सकते हैं

const Person = jkt`
    name: String
    age: Number
`

const someVar = Person({ name: "Aditya", age: "26" })

someVar.name // print "Aditya"
someVar.age // print 26 (integer)

someVar.toJSON() // produce json object with defined schema 

0

यह स्थापित करने के लिए अधिक काम है, लेकिन अगर स्थिरता एक बार के प्रयास को हरा देती है तो यह आपका मामला हो सकता है।

/**
 * @class
 */
class Reference {

    /**
     * @constructs Reference
     * @param {Object} p The properties.
     * @param {String} p.class The class name.
     * @param {String} p.field The field name.
     */
    constructor(p={}) {
        this.class = p.class;
        this.field = p.field;
    }
}

लाभ:

  • तर्क व्यवस्था के लिए बाध्य नहीं
  • आसानी से विस्तार योग्य
  • प्रकार स्क्रिप्ट समर्थन:

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

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