V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
yorks
V2EX  ›  JavaScript

String.fromCharCode() 参数小于 0 还能正常 是怎么做到的?

  •  
  •   yorks · 2018-10-10 15:26:46 +08:00 · 2935 次点击
    这是一个创建于 2220 天前的主题,其中的信息可能已经有所发展或是发生改变。
    String.fromCharCode(-255)
    "!"
    
    4 条回复    2018-11-07 20:13:18 +08:00
    justou
        1
    justou  
       2018-10-10 15:38:58 +08:00   ❤️ 1
    yorks
        2
    yorks  
    OP
       2018-10-10 15:47:23 +08:00
    嗯,我也看了这个文档,好像没看到说怎么处理 小于 0 参数。
    justou
        3
    justou  
       2018-10-10 15:58:19 +08:00   ❤️ 1
    根据其描述, 它说只接收 0 到 0xffff 之间的数, 推断 String.fromCharCode()是把参数当做两个字节的 unsigned 解释的, 二的补码的-255 的 bit 跟 unsigned 的 65281 的 bit 是一样的, 你做几下实验发现
    Tapir
        4
    Tapir  
       2018-11-07 20:13:18 +08:00   ❤️ 1
    这个事儿其实挺有意思的
    按 ES 来说,fromCharCode 的参数需要进行 ES 规定的 ToUint16 运算操作
    可从 ES1 - 8 翻下来,大致上 ToUint16 整个转换流程都没有把负数的布码形式直接识别为无符号形式的明显说明。
    仅有一句较为不好理解的 Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)).
    但这句后半段又很好理解,按说就是绝对值后取整,显然这样操作下来应该是仅会是负值取正且小数取整。
    按这里来说 -255 应该转为 255 才对。
    可现实是,每个浏览器看起来都不是按 ES 规范来实现的。
    由于 v8 最近把 JS 对象相关 API 都用 code asm 重写了,非常不好读。
    就找来 mozilla 代码看看,它里面居然仅仅是做了 uint16_t 的强制类型转换 ……
    由于负数二进制形式是补码形式,强制无符号转换就是把这个补码的二进制值直接存了无符号 int16,成了 65281。
    不知道这种非规范实现是不是历史遗留,亦或是规范我没看仔细……
    就酱紫
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5393 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:25 · PVG 15:25 · LAX 23:25 · JFK 02:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.