疑难杂症记录
ts
无法主动推断真实类型
interface Test {
a: string;
b?: number;
}
const test: Test = {
a: "1231",
b: 1
};
test.b?.toFixed()
按理来说虽然接口定义了属性b
的类型为number|undefined
,但实际上test
的属性b
的类型为number
,这种理应直接推断即可,但是却还是按的接口的类型。
诡异的RegExp.$1
在浏览器控制台输入
/(M+)/g.test("yyyy-MM-dd");RegExp.$1; // MM
可以得到正确的结果。
但如果我们分开写的话
/(M+)/g.test("yyyy-MM-dd");
RegExp.$1; // ''
这时候RegExp.$1的值为空字符串了。
RegExp.$1的解释:
RegExp.$1是RegExp的一个属性,指的是与正则表达式匹配的第一个 子匹配(以括号为标志)字符串,
以此类推,RegExp.$2,RegExp.$3,..RegExp.$99总共可以有99个匹配。
RegExp.$1通常与test函数一起搭配使用,否则无法判断是否是自己获取到的
也就是说获取最后匹配的值,但我们这里看似/(M+)/g.test("yyyy-MM-dd");
是最近执行的值,但浏览器里可能执行过很多次js正则了,所以这样获取的RegExp.$1
并不准确。
应该使用exec代替test+RegExp.$1的组合,或者正则判断后马上赋值给某个变量。
css
backdrop-filter: brightness加hover transform会闪烁
.parent {
transition: transform .3s;
.img {
backdrop-filter: brightness(0.99);
}
&:hover {
transform: translateY(-5px);
}
}
.img
在hover的时候会闪烁。
权宜之计:可用background
代替
position:fixed
变absolute
.parent {
transform: translate(0,0);
.child{
position: fixed;
...
}
}
此时.child
的fixed
会变成absolute
的效果。
解决办法:.child
移出.parent
外面。
for in耗时
let obj = Array(1000000).fill(1).reduce((p,it,k)=>{
p["k"+k] = k;
return p;
},{});
function test(obj){
console.time("test");
const keys = Object.keys(obj);
console.timeEnd("test");
return keys.length === 0;
}
function isEmptyObj(obj){
for(k in obj){return false;}
return true;
}
function test2(obj){
console.time("test2");
const flag = isEmptyObj(obj);
console.timeEnd("test2");
return flag;
}
test(obj)
:test: 249.4609375 ms
test2(obj)
:test2: 247.507080078125 ms
按理来说for in
第一个就马上return
不会花那么多时间才对。
不过ecma上说for in
会提前遍历出所有属性。
再来对比一组自己实现的Object.keys()
function keys(obj){
let arr = [];
for(let k in obj){
arr.push(k);
}
return arr;
}
function testKeys(){
console.time("keys");
keys(obj);
console.timeEnd("keys");
console.time("Object.keys");
Object.keys(obj);
console.timeEnd("Object.keys");
}
运行:
testKeys()
keys: 325.948974609375 ms
Object.keys: 250.131103515625 ms
可以发现Object.keys
比我们自己实现的要快很多,原生内部或浏览器已经优化过了。
看上面的例子,也就相当于我们遍历一个属性就退出的时间。
所以非必要还是使用原生的js函数的好。
评论