2016-07-13 7 views
5

मैं यह समझने की कोशिश कर रहा हूं कि इमोजी कैसे काम करते हैं और दूसरी बात यह है कि मेरे ब्राउज़र में कोई भी टेक्स्टरेरा एक प्रतीत होता है कि एक प्रतीत होता है 2 वर्णों को एक के रूप में दर्शाया जाता है?इमोजी स्ट्रिंग लंबाई 2 क्यों है?

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

"".length 
// -> 2 

अधिक यहाँ उदाहरण: https://jsbin.com/zazexenigi/edit?js,console

+0

देखें: // डेवलपर .teradata.com/ब्लॉग/jasonstrimpel/2011/11/जावास्क्रिप्ट स्ट्रिंग-लंबाई और अंतर्राष्ट्रीयकरण-वेब-अनुप्रयोगों। – str

उत्तर

9

जावास्क्रिप्ट UTF-16 (source) का उपयोग करता तार प्रबंधन करने के लिए।

यूटीएफ -16 में 1,112,064 संभावित पात्र हैं। अब, प्रत्येक वर्ण प्रतिनिधित्व करने के लिए code points का उपयोग करता है (*)। यूटीएफ -16 में एक कोड-पॉइंट दो बाइट्स (16 बिट्स) को सहेजने के लिए उपयोग करते हैं। इसका मतलब है कि एक कोड बिंदु के साथ आप केवल 65536 विभिन्न वर्ण प्राप्त कर सकते हैं।

इसका मतलब है कि कुछ पात्रों को दो कोड बिंदुओं के साथ प्रदर्शित किया जाना है।

स्ट्रिंग। लम्बाई() स्ट्रिंग में कोड इकाइयों की संख्या देता है, न कि वर्णों की संख्या।

MDN के बारे में String.length()

यह गुण स्ट्रिंग में कोड इकाइयों की संख्या रिटर्न पृष्ठ पर बहुत अच्छी तरह से बात बताते हैं। यूटीएफ -16, जावास्क्रिप्ट द्वारा उपयोग किए जाने वाले स्ट्रिंग प्रारूप, सबसे आम पात्रों का प्रतिनिधित्व करने के लिए एक 16-बिट कोड इकाई का उपयोग करता है, लेकिन कम सामान्य रूप से उपयोग किए जाने वाले वर्णों के लिए दो कोड इकाइयों का उपयोग करने की आवश्यकता होती है, इसलिए लंबाई से लौटाए गए मूल्य के लिए यह संभव है स्ट्रिंग में वर्णों की वास्तविक संख्या से मेल नहीं खाते।

(*): असल में कुछ वर्ण, रेंज में 010,000 - 03FFFF और 040,000 - 10FFFF 4 बाइट (32 बिट) कोड बिंदु प्रति अप करने के लिए उपयोग कर सकते हैं, लेकिन इस सवाल का जवाब नहीं बदलता है : कुछ वर्णों को प्रदर्शित करने के लिए 2 बाइट से अधिक की आवश्यकता होती है, इसलिए उन्हें 1 से अधिक कोड बिंदु की आवश्यकता होती है।

इसका मतलब है कि 16 से अधिक बिट्स की आवश्यकता वाले कुछ वर्णों की लंबाई 1 है। जैसा 0x03FFFF, यह 21 बिट की जरूरत है, लेकिन यह UTF-16 में केवल एक ही कोड इकाई का उपयोग करता है, इसलिए इसके String.length 1.

console.log(String.fromCharCode(0x03FFFF).length)

+0

मुझे लगता है कि केवल ES2015 आंतरिक रूप से इंजन और भाषा स्तर पर दोनों यूटीएफ -16 का उपयोग करता है।ईसीटी -2 के साथ ES5 एन्कोड (कम से कम भाषा स्तर पर)। इसके अलावा प्रति चरित्र केवल एक कोड बिंदु है (0x0 से 0x10FFFF तक)) जिसे एक से दो कोड इकाइयों द्वारा दर्शाया जाता है। चूंकि 'string.length' कोड इकाइयों को एकल अक्षरों के रूप में व्याख्या करता है, यह मूल बहुभाषी प्लेन (बीएमपी) के बाहर वर्णों के लिए गलत परिणाम की गणना करता है। – ftor

+0

@ LUH3417 afaik ES5 यूटीएफ -16 का भी उपयोग करता है: 'जब एक स्ट्रिंग में वास्तविक टेक्स्ट डेटा होता है, तो प्रत्येक तत्व को एक यूटीएफ -16 कोड इकाई माना जाता है।' Https://es5.github.io/ – rpadovani

+1

ओह, मेरा गलती। इसे यूसीएस -2 कहा जाता है और ईएस 5 इंजन उनमें से किसी एक का उपयोग कर सकते हैं (यूसीएस -2/यूटीएफ -16)। – ftor

5

मेरा मानना ​​है कि rpadovani दिए अपने "क्यों है "सबसे अच्छा सवाल है, लेकिन एक कार्यान्वयन के लिए जो आपको इस स्थिति में उचित ग्लिफ गिनती मिलेगा, लोडाश ने इस समस्या को उनके toArray मॉड्यूल में निपटाया है।

उदाहरण के लिए

,

_.toArray('12').length; // --> 3 

या, यदि आप एक स्ट्रिंग से कुछ स्वैच्छिक वर्णों दस्तक करना चाहते हैं, तो आप में हेरफेर और सरणी, की तरह पुन: शामिल हैं: http

_.toArray("trimToEightGlyphs").splice(0,8).join(''); // --> 'trimToE' 
संबंधित मुद्दे