字符串 String.prototype.at

669 阅读1分钟

这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战

前言

ECMAScript 6.0 简称ES6 , 是 JavaScript 语言的新一代的标准,于在 2015 年 6 月发布,正式名称就是《ECMAScript 2015 标准》。一般情况,泛指, 5.1版以后的标准,涵盖了 ES2015、ES2016、ES2017、ES2018、ES2019、ES2020、ES2021 等等

我们一起来学习:

  • String.prototype.at

String.prototype.at

我们之前获取字符串指定位置的字符,都是通过类似数组的索引值一样来获取的。

var str = "abcABC";
str[0] // 'a'
str[5] // 'C'

如果是索引值是负值呢?

var str = "abcABC";
str[-1]  // undefined

获得的就是undefined, ES6的 String.prototype.at就支持负数,就是倒数的位置。

var str = "abcABC";
str.at(-1) // 'C'

其实类似的,ES6数组也增加Array.prototype.at方法:

var arr = ['A', 'B', 'C'];
arr.at(-1) // C

如果传入的不是数字呢?

var str = "abcABC";
str.at("2x")    // 'a'
str.at("-2x")   // 'a'
str.at("-2")    // 'B'

这又是什么规则呢?

看协议怎么描述: String.prototype.at, 其核心在于如何参数 index转为数字:
1. Let number be ? ToNumber(argument).
2. If number is NaN, +0𝔽, or -0𝔽, return 0.
3. If number is +∞𝔽, return +∞.
4. If number is -∞𝔽, return -∞.
5. Let integer be floor(abs((number))).
6. If number < +0𝔽, set integer to -integer.
7. Return integer.

先看这条: If number is NaN, +0𝔽, or -0𝔽, return 0.

var str = "abcABC";
str.at(NaN)  // a

重点的重点是 ToNumber:

Argument TypeResult
UndefinedReturn NaN.
NullReturn +0𝔽.
BooleanIf argument is true, return 1𝔽. If argument is false, return +0𝔽.
NumberReturn argument (no conversion).
StringReturn ! StringToNumber(argument).
SymbolThrow a TypeError exception.
BigIntThrow a TypeError exception.
ObjectApply the following steps:1. 1. Let primValue be ? ToPrimitive(argument, number).
  1. 2. Return ? ToNumber(primValue).

可以看得出 Symbol和BigInt是不能转为数字,直接报错, 而对象,依旧是走原值再(ToNumber)转为数字。

我们验证一下 Symbol和BigInt

var str = "abcABC"; 
str.at(2n) 
// Uncaught TypeError: Cannot convert a BigInt value to a number

var str = "abcABC"; 
str.at(Symbol.for("a")) 
// Uncaught TypeError: Cannot convert a Symbol value to a number

很多地方也有相同的情况, ToNumber是很多底层的依赖,之后但速度说。

"a".repeat(2n)
// Uncaught TypeError: Cannot convert a BigInt value to a number

传入的字符串

var str = "abcABC";
str.at("2x")    // 'a'
str.at("-2x")   // 'a'
str.at("-2")    // 'c'

这里面就有一个很有意思的 StringToNumber , 具体我们先不讲解了。 这里大家先记住, 对于传入字符串,处理是比较特别的。

垫片

String.prototype.at = function(index){
     var str = this + '';
     var len = str.length;
     var number = +index;
     var relativeIndex =  number !== number || number === 0 ? 0 : (number > 0 ? Math.floor : Math.ceil)(number);
    var k = number >= 0 ? number : len + relativeIndex;
    return (k < 0 || k >= len) ? undefined  : str[k]
     
}

测试一下:

var str = "abcABC";
str.at(0)  // 'a'
str.at(-1) // 'B'
str.at("2") // 'c'

整体没什么问题。

小结

今天你收获了吗?

引用

String.prototype.at -tc39.es
String.prototype.at - MDN