美文网首页
前端面试题【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