• 面试题:深拷贝方法、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 则是立即执行

  • 相关阅读:
    洛谷题单 【入门3】循环结构
    spark集群环境下,实现人口平均年龄计算
    Python编程实例-播放音频汇总(Linux环境)
    洛谷 P2350 [HAOI2012]外星人(素因子分解,欧拉函数)
    STM32之串口中断接收丢失数据
    Spring的Bean生命周期+bean注入+项目启动时正确姿势初始化数据的五种方式
    LED行业粘性助焊剂市场现状研究分析
    金球奖提名!5家自主品牌「争夺」年度高阶智能辅助驾驶系统
    操作系统知识点总结——第一章计算机系统概述
    Scrapy下载视频示例1
  • 原文地址:https://blog.csdn.net/qq_43940789/article/details/125363263