疑难杂症记录

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:fixedabsolute

.parent {
  transform: translate(0,0);
  .child{
    position: fixed;
    ...
  }
}

此时.childfixed会变成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函数的好。

评论

0 / 800
全部评论()