美文网首页
JavaScript 变量类型 和 深度克隆

JavaScript 变量类型 和 深度克隆

作者: 邢走在云端 | 来源:发表于2020-05-23 21:50 被阅读0次

对以前写过的博客进行补充和回顾 https://www.jianshu.com/p/9c818497f25f

一、基本数据类型

Number String Boolean Undefined Null Symbol(ES6)

基本数据类型存放于栈内存。包括变量标识符和变量的值

let a = 1;
let b = 2;
image

基本类型赋值后两个变量互不影响

let a = 10;
let b = a;
image

二、引用数据类型

引用类型的存储需要内存的栈区和堆区共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,也可以说是该对象在堆内存的地址,而堆内存中存储这个对象

let person1 = {name:'张三'};
let person2 = {name:'张三'};
let person3 = person1;
image

引用类型的赋值是地址的复制,所以两个变量指向的还是同一个对象,对任何一个的操作都会相互的影响

person3.name = '李四'
console.log(person1.name) // 李四

三、使用深度克隆的几种方式

1. Object.assign的方式

function cloneDeep(obj) {
  return Object.assign({}, obj);
}

MDN:Object.assign讲解

弊端:

  • 假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。这时候对于嵌套的对象深度拷贝是无效的。例如下面的——

    let oldObj = {
      name: '张三',
      friend: {
        name: '李四'
      }
    };
    

2. JSON.parse()和JSON.stringify()的方式

function cloneDeep(obj) {
  return JSON.parse(JSON.stringify(obj));
}

这种方式实现通过 JSON.stringify()将对象或数组进行JSON字符串化,这时候他就是一个基本数据类型,然后在通过JSON.parse进行解析。

MDN:JSON.stringify()讲解

MDN:JSON.parse()讲解

弊端:

  • 如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;
  • 如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;
  • 如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;
  • 如果obj里有NaN、Infinity和 - Infinity,则序列化的结果会变成null

3. 相对全面的一个方式

function cloneDeep(obj) {

  if (typeof obj !== 'object') {
    return obj;
  }

  if (!obj) {  // obj 是 null的情况
    return obj;
  }

  if (obj instanceof Date) {
    return new Date(obj);
  }

  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }

  if (obj instanceof Function) {
    return obj;
  }

 // 定义一个新的空数组或者对象
  let newObj = Array.isArray(obj) ? [] : {}
  if (obj && typeof obj === "object") {
    for (let key in obj) {
      // 执行 hasOwnProperty() 来确定某属性是否是对象本身的属性
      if (obj.hasOwnProperty(key)) {
        newObj[key] = (obj && typeof obj[key] === 'object') ? cloneDeep(obj[key]) : obj[key];
      }
    }
  }
  return newObj;
    
}

弊端:

  • 较为复杂

4. 直接使用lodash中的方法

项目中使用最好使用他人已经分装好的库来使用,比我们考虑的更为周全和简洁。这里推荐lodash,lodash 是一个 JavaScript 的实用工具库,众多常用的方法他都给我们封装好了

点击查看lodash文档

🌰下面一个官网栗子

直接引用库,然后调用其方法即可

const _ = require('lodash')

var objects = [{ 'a': 1 }, { 'b': 2 }];
 
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false

相关文章

  • JavaScript 变量类型 和 深度克隆

    对以前写过的博客进行补充和回顾 https://www.jianshu.com/p/9c818497f25f 一、...

  • js浅拷贝和深拷贝

    javaScript的变量类型 javaScript的变量类型基本类型:引用类型: 浅拷贝和深拷贝的区分 浅拷贝浅...

  • JS类型判断与深度克隆

    要进行深度克隆,首先就需要知道进行克隆的这个变量是什么类型的值,知道了是什么类型的,我们才能分门别类的去根本不同的...

  • JavaScript 变量和类型篇

    一、JavaScript基础 变量和类型 1.JavaScript规定了几种语言类型 JavaScript中的每一...

  • Javascript 学习笔记

    JavaScript 中的变量类型JavaScript 中变量可以存储两种类型的值,即原始值和引用值。5种原始类型...

  • JavaScript——深度克隆

    为什么要使用深度克隆? 直接克隆的话,克隆类中的数组只是获得了原始类中的数组指向。这样的话,原始类和克隆类中的...

  • Java深复制浅复制解析.md

    Java 克隆概念 Java克隆分为深克隆和浅克隆两种类型。 浅复制(浅克隆)被复制对象的所有变量都含有与原来的对...

  • js的变量类型和计算

    变量类型 按照存贮方式来分,变量类型分为值类型和引用类型 1.JavaScript中的变量类型有哪些? (1)值类...

  • JS基础

    JavaScript概述 、 JavaScript基础语法 、 变量和常量 、 数据类型 数据类型转换 、 运算符...

  • 变量、作用域和内存问题

    javascript的变量和其他语言的变量有很大区别。 基本类型和引用类型的值 ECMAScript变量可能包含两...

网友评论

      本文标题:JavaScript 变量类型 和 深度克隆

      本文链接:https://www.haomeiwen.com/subject/pjcrahtx.html