JavaScript – 冷知识 (新手)

当 charAt 遇上 Emoji

参考: stackoverflow – How to get first character of string?

我们经常会用 charAt(0) 来获取 first character. 这个用在 ASCII 是完全没有问题的. 但是如果遇到 Unicode 的话, 很有可能会翻车.

const text = '👍';
console.log(text.charAt(0));
console.log(Array.from(text)[0]);

效果

所以当遇上 Unicode 的话记得改用 Array.from 哦.

 

当 flatMap 遇上 not array

const values = [[1, 2, 3], [4, 5, 6]].flatMap(v => v); // [1,2,3,4,5,6]

flatMap 的功能是打平 array, 但如果里面有一个不是 array 呢?

const values = [[1, 2, 3], [4, 5, 6], 'not array'].flatMap(v => v); // [1,2,3,4,5,6, 'not array']

它会原封不动的返回.

那如果是一个 iterator 呢? 它会不会聪明的当 array 处理? 

function* generator() {
  yield 1;
  yield 2;
  yield 3;
}
const iterator = generator();
const values = [[1, 2, 3], [4, 5, 6], iterator].flatMap(v => v); // [1,2,3,4,5,6,iterator]
console.log(values[values.length - 1] === iterator); // true

是不会的哦.

 

encodeURI 和 encodeURIComponent 的区别

参考: 知乎 – escape,encodeURI,encodeURIComponent有什么区别?

encodeURI 不会对 ~!@#$&*()=:/,;?+' 进行编码

encodeURIComponent 方法不会对 ~!*()' 进行编码

用法

如果我们想 encode "full URI" 那就用 encodeURI. 

比如 

encodeURI('https://www.stooges.com.my/a b'); // https://www.stooges.com.my/a%20b

encodeURIComponent('https://www.stooges.com.my/a b') // https%3A%2F%2Fwww.stooges.com.my%2Fa%20b

encodeURI 编码后的 value 依然是一个 URI, 但 encodeURIComponent 就完全不是了.

encodeURIComponent 的 Component 指的是组件. 也就是 part of the URI.

顾名思义, 它的用法就是针对某一个区域做 encode.

const example1 = `https://www.stooges.com.my/${encodeURIComponent('a b')}`; // https://www.stooges.com.my/a%20b

const example2 = `https://www.stooges.com.my?key=${encodeURIComponent('ok?')}`; // https://www.stooges.com.my?key=ok%3F

都是 encode 整个 URI 里的某一部分. 

 

new Array(10) vs Array.from({ length: 10 })

如果想创建一个 array 数字从 1 到 100,通常代码是这样的

const numbers = new Array(100).fill(undefined).map((_, i) => i + 1);

今天看到 Angular Material 的例子使用了另一个方式

const numbers = Array.from({ length: 100 }).map((_, i) => i + 1);

好奇的我,测试了一下速度

const start2 = performance.now();
const array2 = Array.from({ length: 10000000 });
const end2 = performance.now();
console.log(end2 - start2); // 4xx - 5xx ms

const start = performance.now();
const array = new Array(10000000).fill(undefined);
const end = performance.now();
console.log(end - start); // < 100 ms

显然 Angular Material 的方式慢了好几倍。

不清楚为什么它使用慢的,我猜是因为 

Array.from({ length: 100 })

new Array(100).fill(undefined)

美观。

Array.from 会直接得到 100 个 undefined,然后通过 map 就可以创建出 1 -100 了。

new Array 会得到 100 个 empty value,empty value 和 undefined 是有区别的。

如果你去拿一个 empty value 你会得到 undefined

const array = new Array(100);
console.log(array[5]); // undefined

这会让我们以为 empty value 就是 undefined,但其实不是。

const array = new Array(100);
console.log(array);
console.log(array.fill(undefined));

效果

empty 最大的伤害是 map 方法会 skip 掉 empty value

const array = new Array(100);
array[30] = 'x';
console.log(array.map(v => 'a'));

效果

只有 index 30 的 value 被 map 成了 'a',其余的依然是 empty value。

也就是这个原因导致了使用 new Array 实现 1-100 必须加一句 .fill(undefined)。

 

 

 

posted @ 2022-06-20 16:55  兴杰  阅读(38)  评论(0编辑  收藏  举报