2017-03-10 39 views
4

考慮到charAt(),charCodeAt()codePointAt()我發現參數的含義不一致。在我真正想到它之前,我認爲你總是可以安全地訪問length -1的字符。但是我讀到charCodeAt()和codePointAt()之間的區別在於charCodeAt()指的是16位(字節對),所以除了讀取i之外,如果它們是代理對,還需要i+1(如同使用UTF-16 )。而codePointAt()需要引用UTF-8字符位置(基於零)的參數。所以現在我對於是否對length計數字符數或UTF-16樣式的字節對數目感到困惑。我相信JavaScript將字符串保存爲UTF-16,但是使用length -1的字符串中包含大量4字節字符的codePointAt()函數將不在字符串的末尾!什麼是JavaScript字符串的安全長度?

+0

只要有足夠的內存,字符串可以是任意長度。 – PHPglue

回答

3

的的stringslength16位無符號整數值(「元素」)代碼單元進行計數(它們一起形成一個有效或無效的UTF16編碼單元序列),其指數也是如此。我們也可以稱他們爲「角色」。

不要緊,你是否訪問它們as properties或通過charAtchatCodeAtcodePointAtlength - 1將永遠是一個有效的索引。代碼點可能被編碼爲跨越兩個索引的代理對。沒有內建的方法來測量它們的數量,但是默認的字符串迭代器會產生它們,所以你可以用for … of循環對它們進行計數。

+0

請爲OP的問題「什麼是安全長度」提出解決方案。 –

+0

感謝您的回答。非常失望,雖然JavaScript是如此無用,如果你碰巧給它一個代理對的第二個索引它可以提供非法返回值。 – Clive

+0

@Clive你是什麼意思的「非法」?它只是該索引處的代碼單元,而不管它前面的字節是什麼。但是,是的,JavaScript字符串是不可變的'Uint16Array's而不是Unicode字符列表。 – Bergi

2

使用[...str].length作爲字符數。

var mb = ""; 
 
console.log(mb.length); 
 
console.log([...mb].length); // "real" length (ES6) 
 
console.log(mb.charAt(0)); // The first two byte 
 
console.log(mb.codePointAt(0)); // The first two byte 
 
console.log(mb.codePointAt(1)); // The second two byte 
 
console.log(mb.charCodeAt(0)); // The four bytes combined (ES6) 
 
console.log(mb.charCodeAt(1)); // The second two byte (ES6)

+0

我假設你的MB字符集是一個非基本的multiligual平面字符。感謝您的回答和包含的來源。但我對JavaScript的「長度」屬性感到失望,它似乎沒有說明有多少個字符。我不知道elipses。 – Clive

+0

我推薦使用'Array.from(...)'將迭代序列轉換爲數組,傳播語法只能用作文字的一部分。 – Bergi

相關問題