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


    实现深拷贝方法:

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

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

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

    let deep = _.cloneDeep(objects);
    
    • 1

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

     let obj = {
            a: 1,
            b: {  c: 2  }
        }
        let copyObj = {}
        $.extend(true, copyObj, obj);
        copyObj.b = 3
        console.log(obj, copyObj)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

      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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    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
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    多维数组变一维数组:

    利用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));
    
    • 1
    • 2
    • 3
    • 4

    一行实现数组去重:

    利用es6中的Set()方法

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

    关于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 则是立即执行

  • 相关阅读:
    【iOS】——知乎日报第三周总结
    央国企信创改造难在何处?先行建设国产身份域管可少走弯路
    android应用开发基础知识,安卓面试2020
    -数字之和-
    JSONP解决跨域问题
    8 路数字量输入兼容干接点、湿节点多功能RTU
    中英文说明书丨CalBioreagents艾美捷重组丁型肝炎病毒蛋白
    干货|建模3D Max中常见问题
    线上JVM thread 3000+ 未OOM的思考
    skywalking 6.4 分布式链路跟踪 使用笔记
  • 原文地址:https://blog.csdn.net/qq_43940789/article/details/125363263