JavaScript每日五题面试题(第一天)

文章详细介绍了JavaScript中的深拷贝和浅拷贝概念,以及如何通过不同方法实现深拷贝,包括自定义函数和使用JSON.stringify、lodash库等。同时,文章还提到了原始数据类型、原型和原型链的基本概念,以及JavaScript语言的特性及其在网页交互中的作用。
摘要由CSDN通过智能技术生成

1、什么是深拷贝和浅拷贝? 如何实现深浅拷贝?

首先我们先来理解一下什么是浅拷贝和深拷贝

什么是深拷贝和浅拷贝?

  • 深拷贝
    • 创建一个 新对象, 拷贝对象的所有属性, 如果属性是 基本数据, 拷贝的就是 基本数据 的值; 如果是 引用数据, 则需要重新分配一块内存, 拷贝该 引用数据 的所有属性, 然后将 引用地址 赋值给对应的属性, 如果该 引用数据 中某个属性也是 引用数据 则需要继续一层层递归拷贝……
  • 浅拷贝
    • 会新建一个对象, 拷贝对象的所有属性值, 对于 基本数据 来说就是拷贝一份对应的值, 但是对于 引用数据 则是拷贝一份 引用数据 的引用地址 。

那么我们应该怎么去实现呢?

  • 实现深拷贝

    • 简单版本

    •   // 对象的深克隆
              function cloneObj(obj,type){
                  type = type || "object"
                  var clone = (type === "object" ? {}: []);
                  for(var attr in obj){
                      // 判断数组项是不是对象
                      // 1. typeof对象必须是object
                      // 2. instanceof不能是Array
                      if(typeof obj[attr] === "object" && !obj[attr] instanceof Array){
                          // 这是对象类型
                          clone[attr] = cloneObj(obj[attr]);
                      }else if(typeof obj[attr] === "object" && obj[attr] instanceof Array){
                          // 这是数组类型
                          clone[attr] = cloneObj(obj[attr],"array");
                      }else {
                          // 这是基本类型
                          clone[attr] = obj[attr]
                      }
                  }
                  return clone
              }
      
    • 复杂版本

    • 		// map 用于记录出现过的对象, 解决循环引用
              const deepClone = (target, map = new WeakMap()) => {
                  // 1. 对于基本数据类型(string、number、boolean……), 直接返回
                  if (typeof target !== 'object' || target === null) {
                      return target
                  }
      
                  // 2. 函数 正则 日期 MAP Set: 执行对应构造器函数, 返回新的对象
                  const constructor = target.constructor
                  if (/^(Function|RegExp|Date|Map|Set)$/i.test(constructor.name)) {
                      return new constructor(target)
                  }
      
                  // 3. 借用WeakMap来记录每次复制过的对象, 在递归过程中, 如果遇到已经复制过的对象, 则直接使用上次拷贝的对象, 不重新拷贝
                  if (map.get(target)) {
                      return map.get(target)
                  }
      
                  // 4. 创建新对象
                  const cloneTarget = Array.isArray(target) ? [] : {}
                  map.set(target, cloneTarget)
      
                  // 5. 循环 + 递归处理
                  Object.keys(target).forEach(key => {
                      cloneTarget[key] = deepClone(target[key], map);
                  })
      
                  // 6. 返回最终结果
                  return cloneTarget
              }
      
    • JSON.parse(JSON.stringify())

    • 利用 JSON.stringify 将对象转成 JSON 字符串, 再用 JSON.parse 把字符串解析成对象, 如此一来一去就能够实现 引用数据 的一个深拷贝

    • const obj = {
        age: 18,
        name: 'lucky',
      }
      
      const res = JSON.parse(JSON.stringify(obj))
      
    • 注意事项:

      • NaN Infinity -Infinity 会被序列化为 null
      • Symbol undefined function 会被忽略(对应属性会丢失)
      • Date 将得到的是一个字符串
      • 拷贝 RegExp Error 对象,得到的是空对象 {}
    • 使用的是 lodash 这个库里面的一个 _.cloneDeep()

    • jQuery.extend() 通过jquery 这个可以实现

    • 使用structuredClone()方法,这是一个新的 API 可用于对数据进行 深拷贝, 同时还支持循环引用 。

  • 实现浅拷贝

    • 通过Object.assign()实现
    • 展开运算符
    • 对于数组可以使用, 数组的一些方法进行拷贝, 比如: Array.prototype.concat() Array.prototype.slice() Array.from 等方法, 它们的特点都是不改变原数组、同时返回一个新的数组
    • 可以使用一些第三方库提供的工具方法来实现拷贝, 比如: lodash 中的 _clone 方法

2、js中原始数据类型有哪些?

Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt

3、什么是原型和原型链?

  • 原型
    • 在js中,每个构造函数内部都有一个prototype属性,该属性的值是个对象,该对象包含了该构造函数所有实例共享的属性和方法。当我们通过构造函数创建对象的时候,在这个对象中有一个指针,这个指针指向构造函数的prototype的值,我们将这个指向prototype的指针称为原型。
  • 原型链
    • 实例对象在查找属性时,如果查找不到,就会沿着__ proto __ 去与对象关联的原型上查找,如果还查找不到,就去找原型的原型,直至查到最顶层,这也就是原型链的概念。

4、什么是JavaScript?

JavaScript是一门跨平台、面向对象的脚本语言(不需要编译,直接解释运行即可),来控制网页的行为,它能使网页可交互

W3C标准:网页主要由三部分构成

  • 结构:HTML
  • 表现:CSS
  • 行为:JavaScript

5、null和undefined有什么区别?

首先 undefined 和 Null 都是基本数据类型,undefined 代表的含义是未定义,null 代表的含义是空对象。一般变量声明了但还没有定义的时候会返回 undefined,null主要用于赋值给一些可能会返回对象的变量,作为初始化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值