#015#相等和拷贝

前言

日志,各位看官就当乐子看吧。

正经人谁写日记啊?!! ——鹅城县长

结合理解,用短篇幅回答一个面试题

浅拷贝和深拷贝

原文:https://vue3js.cn/interview/JavaScript/copy.html#%E4%B8%80%E3%80%81%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E5%AD%98%E5%82%A8

浅拷贝:指一个对象的副本,副本中的属性与源对象的属性共享相同引用(指向相同的底层值);
深拷贝:不共享,也就是当改变源或副本时,可以保证不对其他对象也产生变化。

进阶

复制操作方法哪些是浅拷贝

扩展运算符Array.prototype.concat()Array.prototype.slice()Array.from()Object.assign()Object.create()

如何实现深拷贝?

  1. JSON.stringify

    先将数据字符串化,然后通过JSON.parse生成对象并赋值。
    缺点:会忽略如函数、Symbol、undefined等类型的属性

  2. 代码实现,基于递归

function deepClone(obj, hash = new WeakMap()) {
  if (obj == null) return obj; // 如果是null或者undefined我就不进行拷贝操作
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);
  // 可能是对象或者普通的值  如果是函数的话是不需要深拷贝
  if (typeof obj !== "object") return obj;
  // 是对象的话就要进行深拷贝
  if (hash.has(obj)) return hash.get(obj);
  // 找到的是所属类原型上的constructor,创建相同类型数据
  let cloneObj = new obj.constructor();
  hash.set(obj, cloneObj);
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      // 实现一个递归拷贝
      cloneObj[key] = deepClone(obj[key], hash);
    }
  }
  return cloneObj;
}

其中WeakMap是处理循环引用的情况,避免栈溢出。就是以下这种情况。

lain.itself=lain
deepClone(lain)

建议看深拷贝的实现(其中,有对拷贝代码的步步完善过程)。最后我有个问题,数据的循环引用的应用场景是什么?

  1. structuredClone()

原文:深拷贝的定义, structuredClone()

MDN中提到了这个方法,也支持循环引用,

let original = { name: "MDN"};
original.itself = original;
let clone = structuredClone(original);
console.log(clone !== original); // true
console.log(clone.name === "MDN"); // true
console.log(clone.itself === clone); // true

缺点是输入值要求必须可以序列化,还有兼容问题

let original = { name: "MDN", A: undefined, B: function(){} };
let clone = structuredClone(original);  // Uncaught DOMException: ... function(){} could not be cloned.

文中提到了"它是浏览器和任何其他实现了 window 这样全局对象的 JavaScript 运行时的一个特性",意思应该是存在兼容性问题,可以引入core-js解决。

其他

==相等===全等,以及适用场景
==相等的判断会出现类型转换:

  1. 只有不同类型数据比较,才会发生隐式转换;
  2. 两个操作数都是基本类型,则字符串和布尔类型会转换成数值;
  3. 仅单个操作数是对象,则会获取对象原始值,再依据1,2做对比;
  4. 两个数都是对象,则判断他们是否是相同引用,相同则相等;
  5. null和undefined相等;
  6. 任一数是NaN,结果都是false

===全等,则是不转换类型,直接判断是否相等。其中null、undefined只和自身全等。
场景:当需要判断对象属性是否等于null和undefined时,使用==。其余建议都使用===

for…in 遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。阮一峰老师的博客有些,对象的扩展
for…of 主要用于依赖索引顺序的遍历,Array

总结

学习Proxy以及基于Proxy实现响应式系统

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值