美文网首页
前端面试题【Day01】

前端面试题【Day01】

作者: 小王子__ | 来源:发表于2021-08-19 17:00 被阅读0次

    本篇绪论
    1,闭包
    2,深浅拷贝
    3,防抖、节流

    1,闭包

    闭包的定义很简单:函数 A 返回了一个函数 B,并且函数 B 中使用了函数 A 的变量,函数 B就被称为闭包。

    function A() {
      let a = 100
      function B() {
        console.log(a)
      }
      return B()
    }
    A()  // 100
    

    经典面试题:

    1, for (var i = 0; i <= 5; i++) {
      setTimeout(function () {
        console.log(i)
      }, i * 1000)
    }
    // 6 6 6 6 6 6
    

    因为setTimeout是异步函数,所以回把循环全部执行完成,这时候 i 就是 6 了,所以输出6个6

    如何改动能使打印出的是0 1 2 3 4 5呢
    解决办法:
    1,第一种方法使用闭包

    for (var i = 0; i <= 5; i++) {
        (function (j) {
          setTimeout(function () {
            console.log(j)
          }, j * 1000)
        })(i)
      }
    

    2, 第二种方法是使用setTimeout的第三个参数

    for (var i = 0; i <= 5; i++) {
        setTimeout(function timer(j) {
          console.log(j)
        }, i * 1000, i)
      }
    

    3,第三种方法使用let

    for (let i = 0; i <= 5; i++) {
        setTimeout(function () {
          console.log(i)
        }, i * 1000)
      }
    
    2, 深浅拷贝
    let a = {
        age: 100
      }
      let b = a
      a.age = 200
      console.log(a)  // {age: 200}
      console.log(b)  // {age: 200}
    

    以上代码,如果给一个变量赋值一个对象,那么两者的值会是同一个引用,其中一个改变,另一个也会相应改变

    浅拷贝

    1,Object.assign()可以实现浅拷贝

    let a = {
        num: 1000
      }
      let b  = Object.assign({}, a)
      a.num = 2000
      console.log(a) // {num: 2000}
      console.log(b) // {num: 1000}
    

    2,使用展开运算符...

    let a = {
        num: 1000
      }
      let b = {...a}
      a.num = 2000
      console.log(a)  // {num: 2000}
      console.log(b)  // {num: 1000}
    

    3, Array.prototype.slice

    let a = [{num: 1000}]
    let b = a.slice(0)
    console.log(a) // [{num: 1000}]
    console.log(b) // [{num: 1000}]
    
    深拷贝

    可以通过JSON.parse(JSON.stringify(obj))实现

    let a = {
        age: 1000,
        jobs: {
          first: 'FE'
        }
      }
      let b = JSON.parse(JSON.stringify(a))
      a.jobs.first = 'Native'
      console.log(a)  // {age: 1000, jobs: {first: 'Native'}}
      console.log(b)  // {age: 1000, jobs: {first: 'FE'}}
    

    但是该方法是有局限性的:

    • 会忽略 undefined
    • 不能序列化函数
    • 不能解决循环引用的对象
    let obj = {
        a: 10,
        b: {
          c: 20,
          d: 30
        }
      }
      obj.c = obj.b
      obj.e = obj.a
      obj.b.c = obj.c
      obj.b.d = obj.b
      obj.b.e = obj.b.c
      let newObj = JSON.parse(JSON.stringify(obj))
      console.log(newObj)
    
    image

    这个循环引用对象,不能通过该方法深拷贝。

    在遇到函数或者undefined的时候,该对象也不能正常的序列化:

    let a = {
        age: undefined,
        sayHi: function () {},
        name: 'xiaowang'
      }
      let b = JSON.parse(JSON.stringify(a))
      console.log(a)
      console.log(b)
    
    image

    以上代码,该方法会忽略掉函数和undefined

    还可以通过lodash实现深拷贝

    相关文章

      网友评论

          本文标题:前端面试题【Day01】

          本文链接:https://www.haomeiwen.com/subject/bpdabltx.html