JavaScript codePointAt()

admin發表於2019-01-31

codePointAt方法返回字串中指定位置字元的Unicode碼點值,與charCodeAt方法功能相同。

既然已經存在charCodeAt方法,為何還要建立codePointAt方法,下面首先介紹一下此原因。

計劃不如變化快,生活中或者工作中大家肯定都遇到過類似的情況。

對於字元編碼的設計也有類似的問題,原來設計好東西,隨著時間推移不能滿足實際需求。

UTF-16中,十六位二進位制位表示一個字元,碼點範圍介於U+0000到U+FFFF,用兩個位元組儲存一個字元。

但是隨著時間的推移,字元不斷增加,十六位編碼空間無法容納新增的字元,於是採用四個位元組儲存新增的字元。

首先看一段程式碼例項:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let str="A";
let strSpecial = "?"; 
console.log(str.length);  
console.log(strSpecial.length);

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201901/31/221726zr7rsa4heo5e8w64.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

程式碼分析如下:

(1).JavaScript中,字串中有幾個字元,length屬性返回對應的數字。

(2).str.length返回1很容易理解,因為字串中只有一個字元"A",雖然strSpecial中也只有一個字元,但是length屬性返回值卻是2,這是因為此字元是用四個位元組表示,JavaScript識別為兩個字元,這很明顯是錯誤的。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let str="A";
let strSpecial = "?"; 
console.log(str.charCodeAt(0));  
console.log(str.codePointAt(0));  
console.log(strSpecial.charCodeAt(0));  
console.log(strSpecial.codePointAt(0));

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201901/31/221817pehizic0di8adbzl.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

可以看到charCodeAt方法對於使用四個位元組儲存的字元無法返回正確的碼點值,功能存在一定缺陷。

codePointAt彌補此缺陷,不但可以返回兩個位元組儲存的字元的碼點值,也可以返回四個位元組儲存字元的碼點值。

語法結構:

[JavaScript] 純文字檢視 複製程式碼
str.codePointAt(pos);

引數解析:

(1).pos:要獲取碼點值的字元的位置,從0開始計算。

ES2015新增此方法,返回指定位置字元的碼點值,如果指定位置沒有字元,返回undefined。

前面已經演示了此方法的功能,下面再介紹一下此方法一些其他需要注意的特點。

程式碼例項如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let strSpecial = "?"; 
console.log(strSpecial.charCodeAt(0));
console.log(strSpecial.charCodeAt(1));
console.log(strSpecial.codePointAt(0));
console.log(strSpecial.codePointAt(1));

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201901/31/222006oja67667767v7224.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

程式碼分析如下:

(1).charCodeAt方法會將四個位元組儲存字元解讀為前後兩個字元,分別讀取碼點值。

(2).codePointAt方法能夠正確返回四個位元組儲存字元的碼點值。

(3).下面就要注意了,codePointAt(1)與charCodeAt(1)的返回值相同,都是返回後兩個位元組的碼點值。

這個特點有時會帶來不便,看如下程式碼例項:

[JavaScript] 純文字檢視 複製程式碼
let str="A";
let strSpecial = "?"; 
console.log(str.charCodeAt(0));
console.log(strSpecial.codePointAt(0));
console.log(strSpecial.codePointAt(1));
console.log(strSpecial.codePointAt(2));

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201901/31/222054k0sf0bk72jsmmsmo.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

我們本來想要通過codePointAt(1)獲取第二個字元"A"碼點值,但是它獲取的是第一個字元後兩個位元組資料的碼點值。比如通過for迴圈來獲取每一個字元的碼點值的時候就會遇到上述問題,ES2015給出了相關的配套解決方案。

通過for of迴圈可以正確輸出,因為它可以識別由四個位元組構成的字元,程式碼例項如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let strSpecial = "?"; 
for (let char of strSpecial) {
  console.log(char.codePointAt(0));
}

非常的完美,關於for of可以參閱JavaScript for of 迴圈一章節。

可以通過此方法判斷一個字元是否是由四個位元組組成,程式碼例項如下:

[JavaScript] 純文字檢視 複製程式碼
function is32Bit(c) {
  return c.codePointAt(0) > 0xFFFF;
}

上面程式碼實現了判斷功能,比較簡單,不多介紹。

相關文章