这是我参与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 Type | Result |
|---|---|
| Undefined | Return NaN. |
| Null | Return +0𝔽. |
| Boolean | If argument is true, return 1𝔽. If argument is false, return +0𝔽. |
| Number | Return argument (no conversion). |
| String | Return ! StringToNumber(argument). |
| Symbol | Throw a TypeError exception. |
| BigInt | Throw a TypeError exception. |
| Object | Apply the following steps:1. 1. Let primValue be ? ToPrimitive(argument, number). |
- 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'
整体没什么问题。
小结
今天你收获了吗?