午夜视频在线观看区二区-午夜视频在线观看视频-午夜视频在线观看视频在线观看-午夜视频在线观看完整高清在线-午夜视频在线观看网站-午夜视频在线观看亚洲天堂

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

字母a的6種表示方法,以及其背后的編碼知識

freeflydom
2025年2月19日 10:33 本文熱度 651

前言

字符是我們編寫程序的基礎的基礎。

我們前端是最常見的字符,符號,數字,英文,中文, 我們通常都是使用直接量來表示,偶爾會在正則表達等場景用到UTF-16碼點的格式,問題來了,那你知道JS有幾種字符表示方式嗎?

答案:至少6種,以字符a為例子:

`a`        // 'a'
'a'        // 'a'
'\a'       // 'a'
'\141'     // 'a'
'\x61'     // 'a'
'\u0061'   // 'a'
'\u{0061}' // 'a'

前三種都很理解, 后面這又是\\x\u\u{}, 這都是什么玩意?

特別申明: 測試代碼最新版chrome上執行。

先看總結

格式示例碼點范圍注意
\8進制'\141'0-255模板字符串中不可直接使用
\x兩位16進制'\x61'0-255必須兩位
\u四位16進制'\u0061'0-65535必須四位
\u{16進制}'\u{0061}'0-0x10FFFF碼點大于0xFFFF,length為2,下標訪問值是高低位的值

編碼基礎知識

完全理解字符表示,還是需要一些簡單的編碼知識,我們一起來看看吧。

ASCII 碼

ASCII 碼一共定義了 128 個字符,例字母 a 是 97 (0110 0001)。這 128 個字符只使用了 8 位二進制數中的后面 7 位,最前面的一位統一規定為 0。

ASCII 碼止共定義了128個字符,其中33個字符無法顯示。0010 0000 ~ 0111 1110 (32-126)是可以顯示的 ,基本都能使用鍵盤打出來, 具體參見對照表: ASCII編碼對照表。

ASCII 額外擴展的版本 EASCII,這里就可以使用一個完整子節的 8 個 bit 位表示共 256 個字符,其中就又包括了一些衍生的拉丁字母。 可以參見 extended-ascii-table?。

Unicode 和 碼點

Unicode是字符集, 為了兼容ASCII,Unicode規定前0-127個字符是和ASCII是一樣的,不一樣的是128-255這一部分。

我們一起看看ASCII 128-255部分:

 再看看 Unicode的 128-255部分:

其給某個字符規定對應的數值,我們經常稱其為碼點。我們可以通過字符串的實例方法charCodeAtcodePointAt獲取,前者只能準確獲取碼點值小于0xFFFF(65535)的碼點。

'??'.codePointAt(0)  // 131104 0x20020  正確
'??'.charCodeAt(0)   // 55360  0xd840   錯誤
'a'.charCodeAt(0)    // 97     0x0061   正確

對應的我們可以使用String的靜態方法fromCharCode,fromCodePoint用碼點獲取對應的字符。

String.fromCodePoint(131104)  // "??" 正確
String.fromCharCode(131104)   // " "  錯誤
String.fromCharCode(97)       // "a"  正確

UTF-8, UTF-16

我們平時接觸比多的就是UTF-8和UTF-16,均是Unicode字符編寫的一種實現。 我們JS編碼的字符串是UTF-16格式來存儲的和表示的。

UTF-16對于碼點小于0xFFFF的用2個字節(1個編碼單元)表示,大于0xFFFF的編碼用四個字節(2個編碼單元)表示。 具體的體現可以表現在字符的長度上。

"??".length  // 2  碼點 131104(0x20020)> 65535 (0xFFFF)
"a".length   // 1
"人".length  // 1

這里強調 0xFFFF 是分界線,很重要。

進制轉換

我們可以使用數字實例toString()10進制轉為相對應的進制。

97..toString(16) // 61
97..toString(2)  // 1100001

下面進入正題, 一起來看字符的表示:

\ + 字符

\ 是一個特殊的存在,轉義字符,大多數情況下,不產生什么作用。 只對一些特殊的字符起作用。

從下可以看出\a這個\沒有任何作用,對\r就不一樣了。

更多轉義字符知識,參見 轉義字符-維基。

\ + 八進制

其能表示的碼點范圍值為 0-255。

這里提個問題, 這里顯示的ASCII的字符,還是Unicode的字符。

  1. 比如字符 a 為 97, 可以使用charCodeAt獲取,
'a'.charCodeAt(0) // 97
  1. 轉為8進制為97..toString(8) = 141
  2. \141
console.log('\141')  // a

我們看一些特殊碼點的字符,因為碼點為31和127的字符,不能被顯示或者表示。

// 37 = 31..toString(8) 
'\37' // '\x1F'
// 177 = 127..toString(8) 
'\177'  // '\x7F'

至于為什么 \177 變為了 \x7F, 是不是有點疑惑,其實也很簡單。 當程序檢查其值,不在可顯示范圍的時候,直接反向計算其原值,并轉為16進制值,并使用\x兩位十六進制格式表示。

// 177 = 127..toString(8) 
'\177'  // '\x7F'
127.toString(16) // 7f

關于表示碼點上限(255):

'\377'  // "?"   --- 碼點255 
'\400'  // ' 0'  --- 碼點256  // 大于255可以理解為 '\40' + '0'

回答開始的提問:
我們這里顯示的肯定是Unicode字符啊,前面提過了, JS字符編碼采用的是UTF-16啊。 可以用碼點在128-255的一個字符試試, 那就碼點254的字符吧:

擴展 ASCII 254: 
Unicode 254: 't'

//376 = 254..toString(8)
'\376'  // 't'

所以大家要明白,我們這各種字符表示方法,表示的都是Unicode字符。

關于\x兩位十六進制格式,我們開講。

\x + 兩位十六進制

我們可以用0x表示16進制的數字,所以\x大家也很好理解,是16進制。

0x61    // 97  0x表示16進制格式數字
'a'.charCodeAt(0)  // 獲取碼點   97
97..toString(16)   // 轉為16進制 61
'\x61'  // 'a'

兩位十六進制碼點, 0x00 ~ 0xFF(0~255) , 和 \八進制碼一樣,不可顯示的碼點字符,直接顯示其編碼

// 1f = 31..toString(16)
'\x1F' // '\x1F'
// 20 = 32..toString(16)
'\x20' // ' '
// 7e = 126..toString(16)
'\x7e' // '~'
// 7f = 127..toString(16)
'\x7f' // '\x7F'
// 80 = 128..toString(16)
'\x80' // '\x80'

到這里你可能問,你這里,那么這不能顯示,那不能顯示,有沒有一個表啊。有的, 參見 Unicode碼表, 這里記錄了 0x0000 到 0xFFFF的碼點的字符,一般情況準夠用。

0-255碼點范圍內, 0x00 到 0x1F(0-31), 0x80 到 0x9F(128-159)是無法顯示的或者看不見的。 

'\x9F'  // '\x9F'   // 編碼輸出
'\xA1'  // "?"     // 正常

這個結果,在不通瀏覽器,可能輸出還不一樣。 盡量采用最新版本的chrome去驗證。

雖然輸出的顯示有些區別,但是都表示這玩意不能表示一個字符,請自重。

360瀏覽器:

firefox:

chrome:

\u + 四位十六進制

這里固定是4位,少一位都不行。

"\u0061" // "a"
"\u061"  // 報錯

還是4位,如果多了, 截取前4位,后面的直接追加??磦€例子,非常好理解。

'\u0061'   // 'a'
'\u00610'  // 'a0'

這里也就反應了問題,碼點大于0xFFFF,大于4位16進制的字符怎么表示???

ES6考慮了這個問題,于是推出了 \u{ + 十六進制 + }, 看下個章節。

我們之前說過,UTF-16是Unicode的一種實現,Unicode的代理區 0xD800-0xDFFF, 其不代表任何字符。同理,我們采用\u + 四位十六進制方式,如果碼點在這個區間,返回 ?或者原字符(瀏覽器不同,可能返回不同), 當然其他的碼點也可能還沒設定值或者是不可打印的。

'\uD800'  // '\uD800' 
'\uDFFF'  // '\uD800'

實際上 UTF-16也就是利用了代理區,把碼點大于0xFFFF字符分為高低兩部分, 索引值0獲得的值實際上是高位部分,索引值1獲得的是低位部分。

var text = "??";
text[0]  //  '\uD840'
text[1]  //  '\uDC20'

更多utf-16編碼的知識,我們后續跟上。

\u{ + 十六進制 + }

ES6新增的能力。 這個多了一個{}包裹。
這個應該是可以一統江湖,可以表示碼點低于0xFFFF的字符,也可表示碼點大于0xFFFF的字符。

"\u{20020}"  // '??'
"\u{0061}"   // 'a'
"\u{061}"    // 'a'
"\u{61}"     // 'a'
"\u{9}"      // "\t"

而且其還沒有強制四位的限制,簡直爽的沒法沒邊。

缺點嘛,那就是兼容性了,就讓時間去磨平吧。

ES6的模板字符串

ES6的模板字符串,可以說是爽歪歪,我們就也算其一種新的字符表示方式吧。

我們也是可以使用\u, \u{}\x格式的

// 61 = "a".charCodeAt(0).toString(16)
`我\u{61}`  // 我a
`我\x61`    // 我a
`我\u0061`  // 我a
`我\a`      // 我a

到這里,你們沒覺得少了了點什么嗎? 沒錯 \8進制,是不被允許的

// 141 = "a".charCodeAt(0).toString(8)
`我\141`

如果,你非得用,那就 ${''}包裹一下:

`我${'\141'}`   // '我a'

實際的應用

匹配中文的正則

我們總不能去羅列,多義采取的是[\u4e00-\u9fa5]這種格式去匹配:

var regZH = /[\u4e00-\u9fa5]/g;
regZH.test("a");   // false
regZH.test("人");  // true
regZH.test("??");  // false  尷尬了不

這里注意了,只能識別常見中文。, 畢竟碼點的范圍就那么大點。

去掉空白字符

看看MDN上 String.prototype.trim

if (!String.prototype.trim) {
  String.prototype.trim = function () {
    return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
  };
}

我們一起來看一下著名的core-js對trim的空白字符的理解 whitespaces.js

module.exports = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' +
  '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';

我們還是輸出一下吧:

'\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' +
  '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'
 //  '\t\n\v\f\r  ?????????????? ???' 

CSS content屬性 和 CSS 字體圖標

現代瀏覽器,已經支持中文,但是建議還是使用\16進制編碼格式 。
這里使用的是 \16進制, 不需要u也不需要{}, 支持碼點大于0xFFFF的字符

    div.me::before {
        content: "\6211";  // 我
        padding-right: 10px;
    }
    
     div.me::before {
        content: "\20020:";  // ??
        padding-right: 10px;
    }

CSS顏色色值

字體顏色,背景顏色,邊框顏色等等,其有一種表示方式就是6位16進制,當然也有簡寫形式。

.title {
    color: #FFF
}

字符個數統計

這個是利用了UTF-16編碼特性。 因為\uD800-\DFFF是代理區,具體UTF-16編碼的東西,單獨來講解。 也可以看見文章 為什么一定是?, 里面有完整的解釋。

const spRegexp = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
function chCounts(str){
  return str.replace(spRegexp, '_').length;
}
chCounts("??")  // 1
"??".length // 2

ES6中的方式就多一些了:

Array.from("??").length //1
[..."??"].length  // 1

文件類型識別

具體可以參見阿寶哥的 JavaScript 如何檢測文件的類型?

const isPNG = check([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); // PNG圖片對應的魔數
const realFileElement = document.querySelector("#realFileType");
async function handleChange(event) {
  const file = event.target.files[0];
  const buffers = await readBuffer(file, 0, 8);
  const uint8Array = new Uint8Array(buffers);
  realFileElement.innerText = `${file.name}文件的類型是:${
    isPNG(uint8Array) ? "image/png" : file.type
  }`;
}

其他

  • emoji圖標
  • 編碼轉換,比如utf-8轉base64
  • 等等

轉自https://juejin.cn/post/7033184851494699022


該文章在 2025/2/19 10:33:51 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 国产亚洲成a人片在线观看 国产亚洲成v人片在线观黄桃 | 高清欧美一区二区免费影视 | 成人三级在线播放 | 国产偷窥熟女精品视频大全 | 2025国产精品自在自线 | 精品国产av无码一区二区三区 | 99久久夜色精品国产网站 | 国产精品无码专区av在线播放 | 成人免费视频一区二区 | 91麻豆精品国产91久久久久 | 国内免费av网站在线观看 | 国产成人精品福利 | 国产v亚洲v天堂无码久久久91 | 国产精品美 | 国产精品一二三区 | 国产三级国产经典国产av | 国产精品成人一区 | av激情亚洲男人的天堂国语 | 国产成人av无码精品 | 成一级女人大片在线视频 | 国产精品爆乳奶水无码视频 | 国产午夜精品美女视频露脸 | 成人综合国内精品久久久久久影院 | 国产美女啪啪视频 | 国产毛片特级av片 | 国产爆乳无码av一区二区 | 国产亚洲一区交换在线 | 国产亚洲制服无码中文 | 国产人妖乱国产精品人妖 | 国产精品一区二区毛卡片 | 精品国产国语对白 | 国产欧美日韩中文字幕 | 精品麻豆国产色欲色欲 | 成人va在线一区二区三区四区 | 69国产精品成 | 国产三级在观线 | h无码中字动漫在线观看 | 国产a久久精品一区二 | 丰满熟妇乱又伦在线 | 高清欧美日韩一区二区三区在线观看 | 91久久精品国产免费一区 |