(मान लीजिए कि यह करने के लिए एक अच्छा कारण है। यदि आप अच्छे कारण को पढ़ना चाहते हैं तो प्रश्न का अंत देखें ।)किसी भी for..in लूप के बिना एक ही परिणाम प्राप्त करें ..in लूप
मैं for in
लूप के समान परिणाम प्राप्त करना चाहता हूं, लेकिन बिना उस भाषा निर्माण का उपयोग कर प्राप्त करना चाहता हूं। नतीजतन मेरा मतलब केवल संपत्ति के नामों की एक सरणी है (मुझे उस व्यवहार को पुन: उत्पन्न करने की आवश्यकता नहीं है जो तब होगा जब मैं ऑब्जेक्ट को संशोधित करते समय ऑब्जेक्ट को संशोधित करता हूं)।
कोड में सवाल में कहें, मैं for in
के बिना इस समारोह को लागू करना चाहते हैं:
function getPropertiesOf(obj) {
var props = [];
for (var prop in obj)
props.push(prop);
return props;
}
the for in statement और the Object.keys
method के बारे में ECMAScript 5.1 विनिर्देश की मेरी समझ से ऐसा प्रतीत होता निम्नलिखित क्रियान्वयन सही होना चाहिए :
function getPropertiesOf(obj) {
var props = [];
var alreadySeen = {};
// Handle primitive types
if (obj === null || obj === undefined)
return props;
obj = Object(obj);
// For each object in the prototype chain:
while (obj !== null) {
// Add own enumerable properties that have not been seen yet
var enumProps = Object.keys(obj);
for (var i = 0; i < enumProps.length; i++) {
var prop = enumProps[i];
if (!alreadySeen[prop])
props.push(prop);
}
// Add all own properties (including non-enumerable ones)
// in the alreadySeen set.
var allProps = Object.getOwnPropertyNames(obj);
for (var i = 0; i < allProps.length; i++)
alreadySeen[allProps[i]] = true;
// Continue with the object's prototype
obj = Object.getPrototypeOf(obj);
}
return props;
}
विचार स्पष्ट रूप से प्रोटोटाइप श्रृंखला चलना, और Object.keys
का उपयोग श्रृंखला के प्रत्येक वस्तु में खुद गुण प्राप्त करने के लिए है। हम श्रृंखला में पिछली वस्तुओं में पहले से देखी गई संपत्ति के नामों को बहिष्कृत करते हैं, जिनमें उन्हें गैर-गणना के रूप में देखा गया था। इस विधि भी सम्मान करना चाहिए the additional guarantee mentioned on MDN:
Object.keys()
विधि एक दिए गए वस्तु की अपनी गणनीय गुण की एक सरणी, रिटर्न एकfor...in
पाश द्वारा प्रदान की किसी एक ही क्रम में [...]।
(जोर मेरा है)
मैं इस कार्यान्वयन के साथ एक सा खेला जाता है, और मैं इसे तोड़ने के लिए नहीं कर पाए हैं।
तो सवाल:
अपने विश्लेषण सही है? या क्या मैं इस स्पेस का विस्तार देख रहा हूं जो इस कार्यान्वयन को गलत बना देगा?
क्या आप ऐसा करने का एक और तरीका जानते हैं, जो कार्यान्वयन के सभी मामलों में for in
के विशिष्ट क्रम से मेल खाता है?
टिप्पणी:
- मैं ECMAScript < 5.1 के बारे में परवाह नहीं है।
- मुझे प्रदर्शन के बारे में परवाह नहीं है (यह विनाशकारी हो सकता है)।
संपादित करें: @ lexicore की जिज्ञासा (लेकिन वास्तव में सवाल का भाग नहीं है) को पूरा करने के, अच्छे कारण के इस प्रकार है। मैं जावास्क्रिप्ट (स्कैला से) के लिए एक कंपाइलर विकसित करता हूं, और for in
भाषा निर्माण उन चीजों का हिस्सा नहीं है जो मैं सीधे अपने कंपाइलर के मध्यवर्ती प्रतिनिधित्व में समर्थन करना चाहता हूं। इसके बजाए, मेरे पास "अंतर्निर्मित" फ़ंक्शन getPropertiesOf
है जो मूल रूप से मैं पहले उदाहरण के रूप में दिखाता हूं। मैं "उपयोगकर्ता-स्थान" कार्यान्वयन (स्कैला में लिखे गए) द्वारा उन्हें बदलकर जितना संभव हो सके उतने बिल्टिन से छुटकारा पाने की कोशिश कर रहा हूं।प्रदर्शन के लिए, मेरे पास अभी भी एक अनुकूलक है जो कभी-कभी कुछ तरीकों को "अंतर्निहित" करता है, और इस मामले में यह प्रभावी पहले कार्यान्वयन के साथ getPropertiesOf
को घुमाएगा। लेकिन इंटरमीडिएट प्रतिनिधित्व ध्वनि बनाने के लिए, और जब अनुकूलक अक्षम हो जाता है, तो मुझे सुविधा के वास्तविक कार्यान्वयन की आवश्यकता होती है, चाहे प्रदर्शन लागत चाहे, जब तक यह सही हो। और इस मामले में मैं for in
का उपयोग नहीं कर सकता, क्योंकि मेरा आईआर उस निर्माण का प्रतिनिधित्व नहीं कर सकता है (लेकिन मैं किसी भी ऑब्जेक्ट पर मनमानी जावास्क्रिप्ट फ़ंक्शंस को कॉल कर सकता हूं, उदाहरण के लिए, Object.keys
)।
'(obj === null || obj === अपरिभाषित)' 'obj == null' जैसा ही है। जिज्ञासा से, क्या कोई कारण है कि आप अधिक वर्बोज़ फॉर्म का उपयोग कर रहे हैं? – gilly3
@ gilly3 क्योंकि '==' बुरा है। कम राय वाले उत्तर के लिए: इसी कारण से मैं 'इन के लिए 'उपयोग नहीं कर सकता: आईआर जानबूझकर' == '(क्योंकि यह बुरा है ...) का समर्थन नहीं करता है। – sjrd
दिलचस्प। मुझे लगता है कि '==' वास्तव में भाषा की एक * ताकत * है जिसे समझदारी से इस्तेमाल किया जाना चाहिए। – gilly3