为什么使用复杂的函数来计算字符串的长度而不是string.length?

时间:2019-03-29 23:25:55

标签: javascript node.js

我正在阅读Java程序员的源代码。我想知道为什么编码员使用复杂的函数来计算字符串长度,而不是仅使用.length原型方法?

原始script。 这里是其功能的代码段:

function byteLength(str) {
      // returns the byte length of an utf8 string
      var s = str.length;
      for (var i=str.length-1; i>=0; i--) {
        var code = str.charCodeAt(i);
        if (code > 0x7f && code <= 0x7ff) s++;
        else if (code > 0x7ff && code <= 0xffff) s+=2;
        if (code >= 0xDC00 && code <= 0xDFFF) i--; //trail surrogate
      }
      return s;
    }

2 个答案:

答案 0 :(得分:2)

JavaScript将字符串表示为UTF-16序列。您发布的代码指出了将JavaScript字符串表示为一系列UTF-8代码的长度。 UTF-8和UTF-16是表示Unicode的两种不同方式,它们相似但不相同。

基本上在旧的“ ASCII”范围(拉丁1)中的字符是UTF-8中的一个字节。还有大约60000个字符用UTF-8表示两个字节,然后用三个字节的簇表示更多的字符。

UTF-16用两个16位字符(称为“代理对”)代表那些较长的代码组。

请注意,根据一个“字符”的含义,事情要复杂得多,因为存在一些Unicode“字符”,它们更像变音符,并与基本字符和其他修饰符一起使用。

最重要的是,.length仅给您字符串中的UTF-16代码数。如果字符串中存在需要代理对的字符,则实际字符数比.length 。此外,按照函数的名称,UTF-8 bytes 的数量几乎总是少于UTF-16字节的数量(也许总是 更少,但是我我是保守派,所以我不会提出这个主张;不过看起来是真的)。​​

答案 1 :(得分:2)

该代码实际上只是通过验证字符串是否为UTF8并仅计算那些字符。运行此示例,它应该使您很好地了解如何计算非uft-8字符(就字符串长度而言)有所不同

const isObjectClass = (value: any, className: any) => (Object.prototype.toString.call(value) === `[object ${className}]`);

export const isDate = (value: any) => isObjectClass(value, 'Date');


const time = (time: Date): string => {
    return ((isDate(time) && !isNaN(time)) ? time : new Date()).toISOString();
};

如果您想进一步研究以下内容,这是一篇很好的文章,其中提供了一些好坏测试数据:

Really Good, Bad UTF-8 example test data