जावास्क्रिप्ट में छंटनी के गुण टूट गए हैं


15

मुझे एक जावास्क्रिप्ट ऑब्जेक्ट के माध्यम से लूप करने की आवश्यकता है जो इसे कस्टम कुंजियों के साथ एक सरणी के रूप में मानता है। मुझे पता है कि यह पूरी तरह से समर्थित नहीं है, क्योंकि गुणों का कोई सहज आदेश नहीं है, लेकिन जब से मैं हमेशा गुणों को फिर से व्यवस्थित करता हूं, मुझे यह दृष्टिकोण सरल और विश्वसनीय लगा ... अब तक।

समस्या तब होती है जब कुंजियाँ संख्याएँ होती हैं, या तार जिन्हें संख्याओं के रूप में डाला जा सकता है।

जब मैं यह कोड चलाता हूं:

var test1 = {4294966222:"A",4294966333:"A",4294966111:"A"};
var test2 = {4294968222:"A",4294968333:"A",4294968111:"A"};
        
for (var k in test1) {console.log(k);}
console.log("---");
for (var k in test2) {console.log(k);}

आउटपुट है:

4294966111
4294966222
4294966333
---
4294968222
4294968333
4294968111

जिसका मतलब है:

  • (test1) यदि चाबियाँ 2 ^ 32 (4,294,967,296) से नीचे हैं, तो वे स्वचालित रूप से फिर से व्यवस्थित हो जाते हैं, सबसे छोटा
  • (test2) यदि कुंजियाँ 2 ^ 32 से ऊपर हैं, तो वे पुनः क्रमबद्ध नहीं हैं।

सवाल यह है कि ऐसा क्यों हो रहा है?

चूंकि सभी ब्राउज़रों का मैंने परीक्षण किया (Google Chrome 79.0, मोज़िला फ़ायरफ़ॉक्स 71.0, Microsoft एज 44.18362, इंटरनेट एक्सप्लोरर 11.535) इस आउटपुट के बारे में सहमत हैं, इसलिए कुछ आधिकारिक विनिर्देश होना चाहिए।

अपडेट करें

मैंने यह पता लगाने से पहले बहुत सी संख्याओं का परीक्षण किया कि यह एक थ्रेशोल्ड मामला है। मुझे अजीब लगा कि अनुक्रम 2,3,1 एक ही तरह से आदेशित तीन टाइमस्टैम्प से अलग व्यवहार करता है।


मेरा अनुमान है कि हैश कोड की गणना कैसे की जाती है, लेकिन यह आपके प्रश्न का वास्तविक उत्तर नहीं है।
— मारियो वर्नरी

1
मुझे नहीं लगता कि यह शब्द के वास्तविक बोलचाल के अर्थ में टूट गया है, वे गारंटी नहीं देते कि मूल्यों को क्रम से पुनरावृत्त किया जाएगा क्योंकि यह मनमाने ढंग से चलता है क्योंकि आप developer.mozilla.org/en-US/docs/Web की जांच कर सकते हैं / जावास्क्रिप्ट / संदर्भ /… "नोट: के लिए ... का उपयोग उस सरणी पर पुनरावृति करने के लिए नहीं किया जाना चाहिए जहां सूचकांक आदेश महत्वपूर्ण है।" वे केवल संग्रह में प्रत्येक तत्व पर पुनरावृत्ति की गारंटी देते हैं। कुछ इस तरह के आदेश वास्तव में आरोही क्रम में आइटमों को ध्यान में रखते हुए आदेश लेते हैं ecma-international.org/ecma-262/5.1/#sec-15.4.4.18
— Mr.Toxy

रिकॉर्ड के लिए, आप प्रवेश द्वारा सीधे समस्या को देख सकते हैं test1और test2। मुझे लगता है कि "मुद्दा" वी के कार्यान्वयन में महत्वपूर्ण कैशिंग से है।
— सेबोर

यह अधिक है कि नीचे 2 ^ 32 आपकी संपत्ति का नाम संयोग से आंतरिक संपत्ति संदर्भों के समान है। आप ऑब्जेक्ट गुणों के क्रम पर भरोसा नहीं कर सकते हैं और परिभाषा से उन्हें ऑर्डर नहीं किया जाता है और इसमें निहित गुण शामिल हो सकते हैं। हमेशा किसी ऑब्जेक्ट को अपनी सरणी में मैप / मैप करें, सरणी को सॉर्ट करें, यदि ऑर्डर महत्वपूर्ण है तो इसके माध्यम से लूप करें।
— user3154108

1
@ Mr.Toxy ऐसा इसलिए है क्योंकि वे गुण 4294968333और (जो है ) 4294968111से अधिक हैं । इसलिए, वे सरणी संकेत नहीं देते हैं, इसलिए वे संख्यात्मक निर्माण क्रम में होने के बजाय संपत्ति निर्माण क्रम में पुनरावृत्त होते हैं - जो कि जैसा वे उम्मीद कर रहे हैं, ठीक वैसा ही वे कर रहे हैं। (मेरा उत्तर देखें)2 ** 324294967296
— १

जवाबों:


4

यह अपेक्षित है। प्रति विनिर्देश , विधि है कि सम्पत्ति के ऊपर iterates, OrdinaryOwnPropertyKeys, करता है:

  1. O के प्रत्येक गुण कुंजी P के लिए, जो कि एक अनुक्रमणिका सूचकांक है , आरोही संख्यात्मक सूचकांक क्रम में, करते हैं

    ए। पी को कुंजी के अंतिम तत्व के रूप में जोड़ें।

  2. प्रत्येक स्वयं की संपत्ति कुंजी के लिए P का O जो कि एक स्ट्रिंग है, लेकिन एक सरणी इंडेक्स नहीं है, संपत्ति निर्माण के कालानुक्रमिक क्रम में, करते हैं

    ए। पी को कुंजी के अंतिम तत्व के रूप में जोड़ें।

आरोही सांख्यिक क्रम केवल उन गुणों के लिए लागू होता है जो सरणी संकेत हैं।

तो, "सरणी इंडेक्स" क्या है? इसे देखो :

पूर्णांक सूचकांक एक स्ट्रिंग-मूल्यवान संपत्ति कुंजी है जो एक कैनोनिकल न्यूमेरिक स्ट्रिंग है (7.1.21 देखें) और जिसका संख्यात्मक मान +0 या एक सकारात्मक पूर्णांक है ^ 2 ^ 53 - 1. एक सरणी सूचकांक एक पूर्णांक सूचकांक या एक संख्यात्मक सूचकांक है मान i श्रेणी +0 ≤ i <2 ^ 32 - 1 में है।

इसलिए, संख्यात्मक गुण जो 2 ^ 32 से अधिक हैं , सरणी संकेत नहीं हैं , और इसलिए संपत्ति निर्माण के क्रम में पुनरावृत्त होते हैं। हालाँकि, संख्यात्मक गुण जो कि सरणी संकेत से कम 2^32 हैं , और बढ़ते क्रम में पुनरावृत्त होते हैं।

इसलिए, उदाहरण के लिए:

1: एरे इंडेक्स, संख्यात्मक रूप से पुनरावृत्त होगा

10: एरे इंडेक्स, संख्यात्मक रूप से पुनरावृत्त होगा

4294968111: संपत्ति के निर्माण क्रम में सरणी संकेत समाप्त होने के बाद से अधिक से अधिक 2 ** 32, इसकी पुनरावृत्ति होगी

9999999999999: संपत्ति के निर्माण क्रम में सरणी संकेत समाप्त होने के बाद से अधिक से अधिक 2 ** 32, इसकी पुनरावृत्ति होगी

इसके अलावा, यह ध्यान रखें कि, लोकप्रिय धारणा के विपरीत, संपत्ति पुनरावृत्ति क्रम को विनिर्देश द्वारा भी गारंटी दी जाती है, इसके लिए धन्यवाद प्रस्ताव प्रस्ताव जो चरण 4 है।


2

यह उस तरह से करना है जिस तरह से वे किसी वस्तु की चाबियाँ हैं।

ES6 विनिर्देशों के अनुसार यह होना चाहिए:

9.1.12 [[OwnPropertyKeys]] ( )

When the [[OwnPropertyKeys]] internal method of O is called the following steps are taken:

    Let keys be a new empty List.
    For each own property key P of O that is an integer index, in ascending numeric index order
        Add P as the last element of keys.
    For each own property key P of O that is a String but is not an integer index, in property creation order
        Add P as the last element of keys.
    For each own property key P of O that is a Symbol, in property creation order
        Add P as the last element of keys.
    Return keys.

http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys

इसका मतलब है कि यदि किसी कुंजी का मान एक समान रहता है, तो उसे 53 बिट संख्या में बदल दिया जाता है और वापस उसे पूर्णांक सूचकांक के रूप में माना जाता है जो आरोही संख्यात्मक क्रम में क्रमबद्ध हो जाता है।

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

यहां पकड़ यह है कि सभी प्रमुख ब्राउज़र अभी तक इस विनिर्देश का पालन नहीं करते हैं और इसके बजाय एक सरणी सूचकांक का उपयोग करते हैं जो एक सकारात्मक संख्या तक सीमित है 2 ^ 32-1। तो उस सीमा से ऊपर कुछ भी वास्तव में एक स्ट्रिंग कुंजी है।

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