面试题:深拷贝方法、for in 和for of区别 、this指向、改变this指向

实现深拷贝方法:

利用json.parse()和json.stringify()实现;

let copyObj =  JSON.parse(JSON.stringify(obj))

lodash函数库中lodash.cloneDeep()实现深拷贝;

let deep = _.cloneDeep(objects);

通过jQuery.extend()实现深拷贝

 let obj = {
        a: 1,
        b: {  c: 2  }
    }
    let copyObj = {}
    $.extend(true, copyObj, obj);
    copyObj.b = 3
    console.log(obj, copyObj)

使用递归的方式实现数组、对象的深拷贝:

  function deepClone(obj) {
        //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
        var objClone = Array.isArray(obj) ? [] : {};
        //进行深拷贝的不能为空,并且是对象或者是数组
        if (obj && typeof obj === "object") {
            for (key in obj) {
                if (obj.hasOwnProperty(key)) {
                    if (obj[key] && typeof obj[key] === "object") {
                        objClone[key] = deepClone(obj[key]);
                    } else {
                        objClone[key] = obj[key];
                    }
                }
            }
        }
        return objClone;
    }

for in 和 for of的区别:

for in 和 for of 都可以循环数组,for in 输出的是数组的index下标,而for of 输出的是数组的每一项的值。

const arr = [1, 2, 3, 4]
for (const key in arr) {
console.log(key) // 输出 0,1,2,3
}
// for … of
for (const key of arr) {
console.log(key) // 输出 1,2,3,4
}

for in 可以遍历对象,输出的是对象的键,for of 不能遍历对象,只能遍历带有iterator接口的

  const object = { name: 'lx', age: 23 }
    // for ... in
    for (const key in object) {
        console.log(key) // 输出 name,age
        console.log(object[key]) // 输出 lx,23
    }
    // for ... of
    for (const key of object) {
        console.log(key) // 报错 Uncaught TypeError: object is not iterable
}
const list = [{ name: 'lx' }, { age: 23 }]
    for (const val of list) {
        console.log(val) // 输出{ name: 'lx' }, { age: 23 }
        for (const key in val) {
            console.log(val[key]) // 输出 lx,23
        }
    }

多维数组变一维数组:

利用es6中的flat()方法

let arr = [1,2,3,[4,5]]
console.log(arr.flat());
let arr2 = [1,2,3,[4,5,[6,7,[8,9]]]]
console.log(arr2.flat(3));

一行实现数组去重:

利用es6中的Set()方法

let arr = [1,2,3,4,5,6,2,3,1,4,2]
console.log([...new Set(arr)]);

关于this指向问题:

1、在全局环境下:this始终指向全局对象window
2、在函数的this
2.1严格模式下:直接调用函数,this指向undefined,window.函数 调用函数this指向window。
2.2非严格模式下:直接调用函数和window.函数 this都指向window。
3、通过构建函数new关键字生成一个实例对象,此时this指向这个实例对象
4、对象中的this:谁调用就指向谁,多层嵌套对象,内部方法的this指向距离被调用函数最近的对象
5、箭头函数中的this:箭头函数中this不会被改变,箭头函数内的 this 指向外层的 this。
6、原型链中的this:指向它原本属于的对象

改变this指向的方法:call() apply() bind()

Call():第一个参数是this的指向,后面传入的是一个参数列表,改变this指向后原函数会立即执行,且此方法只是临时改变this指向一次
Apply():第一个参数是this的指向,第二个参数是函数接受的参数,以数组的形式传入
改变this指向后原函数会立即执行,且此方法只是临时改变this指向一次
Bind():第一个参数是this的指向,后面传入的是一个参数列表(但是这个参数列表可以分多次传入),改变this指向后不会立即执行,而是返回一个永久改变this指向的函数

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

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜空孤狼啸

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值