1227面试题——数组去重、响应式、requestIdleCallback/requestAnimationFrame

367 阅读2分钟

JS

  1. 数组去重(不限于一种方案) 参考了一下tdk的0.0
// 1. {}与{},{a:1}与{a:1},[]与[]算一样的
// [1,2,'1','2',1,null,null,undefined,undefined,{},{},[],[],[1],[1],['1'],['1'],NaN.NaN,true,true]

function duplicate(arr){
    // ...code
}

// 第一种

 //判断数组是否相等
function sameArr(arr1,arr2){
    if(Object.prototype.toString.call(arr1) === "[object Array]"
    && Object.prototype.toString.call(arr2) === "[object Array]"
  ){ 
     return JSON.stringify(arr1) === JSON.stringify(arr2);
   } else {return false}
}
//判断对象是否相等
function sameObj(obj1,obj2){
    if(Object.prototype.toString.call(obj1) === "[object Object]"
    && Object.prototype.toString.call(obj2) === "[object Object]"
    ){
        return JSON.stringify(obj1) === JSON.stringify(obj2);
    } else {return false}
}

function duplicate1(arr){
    for(let i =0 ;i<arr.length;i++){
        for(let j =i+1;j<arr.length;j++){
            if(sameArr(arr[i],arr[j])){ 
                arr.splice(j,1)
                j--
            }
            else if(sameObj(arr[i],arr[j]))
           {
                arr.splice(j,1)
                j--
            }
            else if(arr[i] === arr[j]){
                  arr.splice(j,1)
                  j--
            }
        }
    }
    return arr;
}

// 第二种
function duplicate2 (arr) {
    // 用来判断是否已经加入
    let newObj = {}
    // 去重后的数组
    let newArr = []
    arr.forEach(item => {
        if (typeof item !== 'object') { 
            // 如果为 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. 响应式布局是如何实现的?
    • 媒体查询
    • flex布局
    • 响应式单位:rem、vw、百分比等
  2. 如果期望以下的div,该如何书写样式
    • 在视口宽度 <=750px展示为长宽都为200px的红色方块
    • 在视口宽度 >750px且 <=1400px 时展示为 长宽400px的蓝色方块
    • 在视口宽度 >1400px 是展示为 长宽 600px 的黑色方块
<!DOCTYPE html>
<html>
<head>
	<style>
		html {
			height: 100%;
		}
		body {
			display: flex;
			justify-content: center;
			align-items: center;
			height: 100%;
		}
		@media (max-width:750px) {
			.container {
				width: 200px;
				height: 200px;
				background-color: red;
			}
		}
		@media (min-width:750px) and (max-width: 1440px) {
			.container {
				width: 400px;
				height: 400px;
				background-color: blue;
			}
		}
		@media (min-width:1440px) {
			.container {
				width: 600px;
				height: 600px;
				background-color: black;
			}
		}
	</style>
</head>
<body>
	<div class='container'></div>
</body>
</html>

浏览器

  1. requestIdleCallback 与 requestAnimationFrame 的作用分别是什么?有何异同?
    • 浏览器会在一帖内完成如下六个步骤:

      • 处理用户的交互
      • JS 解析执行
      • 帧开始。窗口尺寸变更,页面滚动等的处理
      • requestAnimationFrame(rAF)
      • 布局
      • 绘制
    • requestIdleCallback 当以上六个步骤完成后,还有富余的时间(未到下一帧刷新的开始时间),就会执行 requestIdleCallback 里注册的任务。因为有时浏览器处于忙碌状态,可能一直没机会执行requestIdleCallback。因为它发生在一帧的最后,此时页面布局已经完成,所以不建议在 requestIdleCallback 里再操作 DOM,这样会导致页面再次重绘。

    • requestAnimationFrame 会在每一帧中都执行,优先级比requestIdleCallback高