春招冲刺12.27

202 阅读3分钟

数组去重

大致主要分为两类

1. 两个for循环遍历数组

 //判断数组是否相等
function diffArr(arr1,arr2){
    if(Object.prototype.toString.call(arr1) === "[object Array]"
    && Object.prototype.toString.call(arr2) === "[object Array]"
  ){ //这里只是判断值类型对象与数组不会被判断
     return JSON.stringify(arr1) === JSON.stringify(arr2)? true : false;
 }
}
//判断对象是否相等
function diffObj(obj1,obj2){
    if(Object.pro'p'to.call(obj1) === "[object Object]"
    && Object.prototype.toString.call(obj2) === "[object Object]"
    ){
        return JSON.stringify(obj1) === JSON.stringify(obj2)? true : false;
    }
}

function duplicate1(arr){
    for(let i =0 ;i<arr.length;i++){
        for(let j =i+1;j<arr.length;j++){
            if(diffArr(arr[i],arr[j])){ //这里只是判断值类型对象与数组不会被判断
                arr.splice(j,1)
                j--
            }
            else if(diffObj(arr[i],arr[j]))
           {
                arr.splice(j,1)
                j--
            }
            else if(arr[i] === arr[j]){
                  arr.splice(j,1)
                  j--
            }
        }
    }
}

2. 利用语法自身键不可重复性

例如 利用set的键的唯一性

let arr = [1,2,'1','2',1,null,null,undefined,undefined,{},{},[],[],[1],[1],['1'],['1'],NaN.NaN,true,true]
let arr2 = [...new Set(arr)]
console.log(arr2)
// 不能判断引用类型的重复

遍历数组,看是否遍历到的item的下标与其第一次出现的下标相等

//应该都能去除
function duplicate2 (arr) {
    let newObj = {}
    let newArr = []
    arr.forEach(item => {
    if (typeof item !== 'object') { 
    //这里因为array和object类型都可以用Json.stringify来判断
    //,所以没有使用object.prototype.toString.call()的方法
      // NaN是唯一一个不等于任何自身的类型
      if (item !== item) {
        if (!newObj[item.toString()]) {
          newArr.push(item)
          newObj[item.toString()] = true
        }
      } else {
        if (newArr.indexOf(item) === -1) {
          newArr.push(item)
        }
      }
    } else {
      let str = JSON.stringify(item)
      if (!newObj[str]) {
        newArr.push(item)
        newObj[str] = true
      }
    }
    })
    return newArr
    }

CSS

可以用如下的方式实现响应式布局

  1. 百分比布局
  2. 使用媒体查询 (CSS3 @media 查询)
  3. rem 响应式布局
  4. vw 响应式布局
  5. flex 弹性布局

媒体查询如果期望以下的div,该如何书写样式

  • 在视口宽度 <=750px展示为长宽都为200px的红色方块
  • 在视口宽度 >750px且 <=1400px 时展示为 长宽400px的蓝色方块
  • 在视口宽度 >1400px 是展示为 长宽 600px 的黑色方块 代码如下
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        @media screen and (max-width: 750px) {
            .container {
                background-color: red;
                width: 200px;
                height: 200px;
            }
        }

        @media screen and (max-width: 1400px) and (min-width: 750px){
            .container {
                background-color:blue;
                width: 400px;
                height: 400px;
        }
        }
        @media screen and (min-width: 1400px) {
            .container {
                background-color:black;
                width: 600px;
                height: 600px;
            }
        }
    </style>
</head>

<body>
    <div class='container'></div>
</body>

</html>

浏览器

requestIdleCallback 与 requestAnimationFrame 的作用分别是什么?有何异同?

requestIdleCallback

这个API的作用是查询距离下次调度还有多久的时间可以供你执行,如果时间足够就会执行其回调函数它是一个后台任务,会在空闲的时候执行。如果你现在正在执行一个requestAnimationFrame的动画,对于性能好的机器,在动画的间歇期,requestidlecallback就会被执行,而对于一些性能不好的机器,requestAnimationFrame动画,可能一直占据了线程,那么这个时候,requestidlecallback就可能是在整个动画 执行完毕之后,才会被执行

  • 如果浏览器一直很忙可以传入第二个参数 此时和setTimeout的作用一样了
// 默认参数
requestIdleCallback((deadline)=>{
    console.log(<code>剩余可执行时间为:${deadline.timeRemaining()}ms</code>);
    console.log(<code>当前任务是否超时:${deadline.didTimeout}</code>)
    // 剩余可执行时间为:49.9ms,当前任务是否超时:false
});
 
// 设置延迟执行时间,类似于timeout,如果在一个周期内cb一直没有被执行,但是你又设置了timeout,且时间已经到了,那么cb就会被推到任务队列中,等待执行
requestIdleCallback((deadline)=>{
    console.log('任务一:会被执行')
    console.log(<code>剩余可执行时间为:${deadline.timeRemaining()}ms</code>)
    console.log(<code>当前任务是否超时:${deadline.didTimeout}</code>)
    // 剩余可执行时间为:0ms,当前任务是否超时:true
}, {timeout: 100});
 
requestIdleCallback((deadline)=>{
    console.log('任务二:会被抛弃,因为没有设置timeout,当浏览器没有空闲时间的话就会被抛弃')
    console.log(<code>剩余可执行时间为:${deadline.timeRemaining()}ms</code>)
    console.log(<code>当前任务是否超时:${deadline.didTimeout}</code>)
});
 
console.log('开始执行一段复杂任务')
for(let i=0; i<100000000; i++) {
  ;
}
console.log('执行完毕')

requestAnimationFrame

类似于setTimeout,但是比setTimeout更加的可以说是智能,requestAnimationFrame最大的优势是由系统来决定回调函数的执行时机。具体一点讲,如果屏幕刷新率是60Hz,那么回调函数就每16.7ms被执行一次,如果刷新率是75Hz,那么这个时间间隔就变成了1000/75=13.3ms,换句话说就是,requestAnimationFrame的步伐跟着系统的刷新步伐走。它能保证回调函数在屏幕每一次的刷新间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。

window.requestAnimationFrame(function( time){
    //显示频刷新的时候被执行
});

区别

  • equestAnimationFrame的回调会在每一帧确定执行,属于高优先级任务,而requestIdleCallback的回调则不一定,属于低优先级任务。
  • requestAnimationFrame会在每次屏幕刷新的时候被调用,而requestIdleCallback则会在每次屏幕刷新时,判断当前帧是否还有多余的时间

相同点

都是异步执行的函数