了解Unicode編碼


一. Unicode是什么?

Unicode是一種字符編碼方案,它為每種語言中的每個字符都設定了統一唯一的二進制編碼。以實現跨語言、跨平台進行文本轉換。

Unicode是為了解決傳統字符編碼方案的局限而產生的。

Unicode編碼的發展及詳細介紹可以看這篇文章(https://www.php.cn/js-tutorial-414753.html)。

Unicode字符編碼是用一個碼位映射一個字符,碼位值的范圍是從 U+0000 到 U+10FFFF。

碼位:一般是被格式化為十六進制數字的,零填充至少四位數,格式為 U + 前綴。

比如 A的碼位:U+0041, a的碼位:U+0061;

因為A的ASCII十進制為 65; a的ASCII的十進制為97; 我們可以在chrome瀏覽器下測試下即可:

'A'.charCodeAt(); // 打印65

因此 字符 A 十進制為65,轉換成十六進制就是41了,十六進制轉十進制的方法為 65 = 4 * 16 + 1; 因此變成Unicode碼位的話: U+0041了。

Unicode最前面的65536個字符位,稱為零號平面,它的碼位范圍是從 U+0000 到 U+FFFF; 我們最常見的字符都在這里面了。

Unicode轉義

1. 16進制轉義

"A" 轉義為:'\x41'; "a" 轉義為: '\x61';

2. Unicode轉義

A的Unicode碼位為: 'U+0041'; 因此 字符A的Unicode的轉義就變成了 '\u0041'; 我們可以在chrome控制台打印下就知道了。

在ECMAScript6中,引入了一種新的轉義序列:Unicode碼位轉義: 比如:'\u{41}'; 使用大括號對16進制數字,在大括號之間可以使用最多6個十六進制數字。

字符串方法中的Unicode

1. String.fromCharCode()

String.fromCharCode() 方法可以將一個碼位轉換為字符,但是它只適用於BMP范圍內的碼位(即從 U+0000 到 U+FFFF)。如果將它用於轉換超過BMP外的碼位,將不會得到想要的結果。

fromCharCode()可以接受一個指定的Unicode的值,然后返回一個字符串。該方法是String的靜態方法,字符串中的每個字符都由單獨的Unicode數字編碼指定。基本語法如下所示:

String.fromCharCode(n1, n2, ......nx);

比如如下代碼:

var n = String.fromCharCode(72,69,76,76,79); 
console.log(n); // 打印的值為:"HELLO"

String.fromCharCode() 的缺點是:

對於在 U+0000 到 U+FFFF 范圍之外的碼位是獲取不到結果的,我們看下:

String.fromCharCode(0x1F4A9);

打印的結果如下:

解決的方法當然也有,但是方法也不是很好,但是幸運的是,ES6中引入了 String.fromCodePoint(codePoint). 該方法的優點是可以用於任何的Unicode編碼,它是范圍更廣,是從 U+0000 到 U+10FFFF; 我們可以繼續使用該方法測試下上面的demo;

String.fromCodePoint(0x1F4A9);

在chrome瀏覽器下執行的結果如下所示:

2. String.prototype.charAt(position)

該方法是用來檢索包含字符串中的第一個字符。

比如如下代碼:

'abcdeb'.charAt(1); // 打印 b

3. String.prototype.charCodeAt(position)

該方法的含義是:從字符串中獲取碼位, 檢索字符串中第一個字符的碼位。

比如如下代碼:

'ABC'.charCodeAt(1); // 輸出結果為66;

如上是字符串 'ABC'; 找到第2個字符串的碼位。

二:JS中Unicode編碼與String相互轉換

1. 字符串轉Unicode

第一種方式:

var str='\u6211\u662f\u4e2d\u56fd\u4ebaChina';
var ret1 = eval("'" + str + "'");
console.log(ret1); // 打印出:我是中國人China

第二種方式:

var str='\u6211\u662f\u4e2d\u56fd\u4ebaChina';
var ret2 = (new Function("return '" + str + "'"))();
console.log(ret2); // 打印出:我是中國人China

第三種方式:

var str='\u6211\u662f\u4e2d\u56fd\u4ebaChina';
var ret3 = unescape(str.replace(/\u/g, '%u'));
console.log(ret3); // 打印出:我是中國人China

2. Unicode轉字符串

function string2unicode(str) {
  var html = '';
  for (let i = 0; i < str.length; i++) {
      console.log(str.charCodeAt(i))
    html += "\\u" + str.charCodeAt(i).toString(16);
  }
  return html;
}
var str = "我是中國人";
var s2u = string2unicode(str);
console.log(s2u); // 打印出: \u6211\u662f\u4e2d\u56fd\u4eba
console.log(eval("'"+s2u+"'")); // 輸出:我是中國人

如上代碼,使用的語法是:number.toString(radix);

radix參數可選;它值可以是2、8、16,表示以多少進制來顯示。
更多了解可以看對應的API(https://www.runoob.com/jsref/jsref-tostring-number.html)

如下代碼演示:

var num = 15;
var a = num.toString();
var b = num.toString(2);
var c = num.toString(8);
var d = num.toString(16);

console.log(a); // 15
console.log(b); // 1111
console.log(c); // 17
console.log(d); // f

如上字符串轉Unicode的方法 string2unicode 有缺陷的,比如中文里面包含英文的話,就不行了,請看如下代碼:

function string2unicode(str) {
  var html = '';
  for (let i = 0; i < str.length; i++) {
    html += "\\u" + str.charCodeAt(i).toString(16);
  }
  return html;
}
var str = "我是中國人a"; 
var s2u = string2unicode(str);
console.log(s2u); // 打印結果為: \u6211\u662f\u4e2d\u56fd\u4eba\u61
console.log(eval("'"+s2u+"'"));

如上代碼就報錯了,因為JS自身的Unicode轉字符串不能識別不足4位的unicode。因此我們要對 string2unicode方法改進一下。

function string2unicode(str) {
  var html = '';
  var rets = '';
  for (let i = 0; i < str.length; i++) {
      // 獲取碼位
    var c1 = str.charCodeAt(i);
    // 轉換成16進制
    var c16 = c1.toString(16);
    // 0xf 代表16進制f,轉換成10進制就是15
    if (c1 < 0xf) {
      html += "\\u" + "000" + c16;
    } else if (c1 < 0xff) { 
      html += "\\u" + "00" + c16;
    } else if (c1 < 0xfff) {
      html += "\\u" + '0' + c16;
    } else {
      html += "\\u" + c16;
    }
  }
  rets += html;
  return rets;
}

var str = "我是中國人a"; 
var s2u = string2unicode(str);
console.log(s2u); // 打印結果為: \u6211\u662f\u4e2d\u56fd\u4eba\u61
console.log(eval("'"+s2u+"'")); // 打印: 我是中國人a

我們可以在chrome控制台看下打印信息如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM