1.== 和 ===区别,分别在什么情况使用

1.等于操作符

等于操作符用两个等于号( == )表示,如果操作数相等,则会返回 true

等于操作符(==)在比较中会先进行类型转换,再确定操作数是否相等

  • 两个都为简单类型,字符串和布尔值都会转换成数值,再比较
  • 简单类型与引用类型比较,对象转化成其原始类型的值,再比较
  • 两个都为引用类型,则比较它们是否指向同一个对象
  • null 和 undefined 相等
  • 存在 NaN 则返回 false

2.全等操作符

全等操作符由 3 个等于号( === )表示,只有两个操作数在不转换的前提下相等才返回 true。即类型相同,值也需相同

3.区别

相等操作符(==)会做类型转换,再进行值的比较,全等运算符不会做类型转换

除了在比较对象属性为null或者undefined的情况下,我们可以使用相等操作符(==),其他情况建议一律使用全等操作符(===)

2.深拷贝浅拷贝的区别?如何实现一个深拷贝?

3. 防抖与节流的区别? 如何手写防抖与节流?

image-20230309150031243

image-20230309150145267

image-20230309150305676

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>防抖函数的手写</h2>
    <input type="text">
    <script>
        
     let oInput = document.querySelector('input')
    //  oInput.addEventListener("keyup", function () {
    //      console.log("keyup")
    //  }) 
        
     oInput.addEventListener("keyup", debounce(function () {
            console.log("一秒钟后执行keyup")
        }, 1000))
     // 防抖函数
     function debounce(fn,delay){
           let timer = null;
           return function(){
            if(timer){
                clearTimeout(timer)
            }
            timer = setTimeout(() => {
                //必须使用apply,call不行
                fn.apply(this,arguments)
            }, delay);
           }
     }
    </script>
</body>
</html>

节流函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
            width: 200px;
            height: 200px;
            background-color: #ccc;
        }
    </style>
</head>
<body>
    <h2>手写节流</h2>
<!-- draggable="true" 表示可以拖拽 -->
    <div draggable="true"></div>
</body>

 <script>
    let oDiv = document.querySelector('div');
    // oDiv.addEventListener('drag',function(e){
    //     console.log(e.clientX+" drag")
    // })
    // 使用节流函数
    oDiv.addEventListener('drag', throttle(function (e) {
        console.log(e.clientX + " drag")
    }, 1000))
 
    function throttle(fn, delay) {
        let timer = null;
        return function () {
            if (timer) return;
            
            timer = setTimeout(() => {
                fn.apply(this, arguments);
                timer = null;
            }, delay);
        }
    }
 </script>
</html>

4.请描述event loop 的机制

image-20230309231643590

image-20230309153830812

image-20230309154348375

事件循环⼜叫做消息循环,是浏览器渲染主线程的⼯作⽅式。 在 Chrome 的源码中,它开启⼀个不会结束的 for 循环,每次循环从消息 队列中取出第⼀个任务执⾏,⽽其他线程只需要在合适的时候将任务加⼊到 队列末尾即可。 过去把消息队列简单分为宏队列和微队列,这种说法⽬前已⽆法满⾜复杂的 浏览器环境,取⽽代之的是⼀种更加灵活多变的处理⽅式。 根据 W3C 官⽅的解释,每个任务有不同的类型,同类型的任务必须在同⼀ 个队列,不同的任务可以属于不同的队列。不同任务队列有不同的优先级, 在⼀次事件循环中,由浏览器⾃⾏决定取哪⼀个队列的任务。但浏览器必须 有⼀个微队列,微队列的任务⼀定具有最⾼的优先级,必须优先调度执⾏。

5.什么是宏任务?什么是微任务?二者有什么区别?

image-20230309154456103

image-20230309154917762

image-20230309155407085

image-20230309155411796

6.手写Promise 加载图片

image-20230309155450242

image-20230309162555525

7.Promise 阅读代码题

image-20230309162710133

image-20230309163034383

image-20230309163105157

image-20230309163434142

image-20230309163731916

image-20230309163944387

image-20230309164020922

image-20230309164115883

image-20230309164233191

image-20230309164323965

image-20230309164648077

image-20230309165053540

image-20230309165507577

image-20230309165736265

image-20230309170136782

8.for..in 和 for…of 有什么区别?

image-20230309170316254

image-20230309170552060

image-20230309170619690

image-20230309170817175

image-20230309170835825

image-20230309171001786

判断是否为可枚举

image-20230309171502671

image-20230309171507332

判断可迭代

image-20230309171716124

9.for await…of 有什么作用?

image-20230309171812239

image-20230309172013125 Promise.all()

image-20230309172116600

image-20230309172557595

10.var,let 和const 有什么区别?

image-20230311152634733

1.var 没有块级作用域,let和const 有块级作用域

image-20230311152852818

2.var 有变量的提升,let和const 没有变量的提升

image-20230311153115042

image-20230311153158535

image-20230311153327590

3.var 可以重名,let const 不可以

11.原型和原型链是怎么回事?

image-20230311160205214

image-20230311160353544

image-20230311160612357

image-20230311161026789

image-20230311161153509

image-20230311161358598

image-20230311161500763

image-20230311161523216

12.手写instanceof

image-20230311161738472

image-20230311161804418

image-20230311162223495

image-20230311162500494

13.手写bind函数

  • apply,call,bind 的区别?
  • 三者都可以改变函数的this对象指向
  • 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefinednull,则默认指向全局window
  • 三者都可以传参,但是apply是数组,而call是参数列表,且applycall是一次性传入参数,而bind可以分为多次传入
  • bind是返回绑定this之后的函数,applycall 则是立即执行

image-20230311162612964

image-20230313203816129

14.this在不同场景下,如何取值?

image-20230313203844661

1.普通函数下的this,非严格模式下位window,严格模式下为undefined

image-20230313204005446

image-20230313204031663

2. call(),call(undefined),call(null) ,this都为window(apply,bind同理),其他情况下,传什么,this就是什么

image-20230313204155715

image-20230313204411312

image-20230313204428361

其他情况

image-20230313204553854

image-20230313204617167

image-20230313204729578

3.定时器中的this

image-20230313204934140

image-20230313205123647

image-20230313205217891

image-20230313205427267

image-20230313205556909

4.箭头函数中的this

image-20230313205739788

image-20230313205931743

image-20230313210132740

image-20230313210245382

15.值类型和引用类型有什么区别?

image-20230313210426698

image-20230313211022297

image-20230313210634613

image-20230313210701405image-20230313210701505

image-20230313210947505

16.手写深拷贝

image-20230313211108404

image-20230313212111471

image-20230313212333490

JSON 无法对正则,时间对象,函数等这些进行深拷贝

image-20230313212706138

上图中只能进行一层深拷贝,需要使用递归处理才行

image-20230313212927374

image-20230313213143809

17.何时使用== 和 何时使用===?

image-20230313213614207

image-20230313213508792

18.truely 变量和falsely变量?

image-20230313213756141

19.谈谈闭包和闭包的应用场景?

image-20230313213851393

image-20230313224523797

image-20230313224735638

image-20230313224840435

闭包引用场景

image-20230313225105885

image-20230313225221203

image-20230313225420163

image-20230313225636876

20.手写flat 拍平数组

image-20230313225812169

image-20230313225923104

image-20230313230140042

image-20230313230225804

image-20230313230503696

image-20230313230650343

21.数组去重

image-20230313230852848

image-20230313230941135

22.求数组中的最大值?

image-20230313231039521

image-20230313231150243

image-20230313231205964

image-20230313231228164

image-20230313231256414

image-20230313231442947

image-20230313231818182