• JavaScript中判断数据类型,浅拷贝和深拷贝详解


    一.JS中的数据类型

    1.基本数据类型:Number,String,Boolean,Undefined,Null,Symbol

    2.复杂数据类型:Object,Array,Function,Map,Set

    二.JS中判断数据类型

    1.typeof 

    可以判断Number,String,Boolean,Undefined,Function,Symbol但是Null,Object,Array,Map,Set这三种类型都会判断为Object

    2.instanceof

    obj instanceof Object:判断Object是否在obj的调用链上

    obj instanceof Object;// true
    arr instanceof Array;// true 
    map instanceof Map //true 
    set instanceof Set //true
    null instanceof Object;// false
    undefined instanceof Object;// false
    symbol instanceof Symbol //false

    instanceof不能区别undefined和null,而且对于基本类型如果不是用new声明的则也测试不出来,对于是使用new声明的类型,它还可以检测出多层继承关系

    3.object.prototype.toString

    1. console.log(Object.prototype.toString.call(bool));//[object Boolean]
    2. console.log(Object.prototype.toString.call(num));//[object Number]
    3. console.log(Object.prototype.toString.call(str));//[object String]
    4. console.log(Object.prototype.toString.call(und));//[object Undefined]
    5. console.log(Object.prototype.toString.call(nul));//[object Null]
    6. console.log(Object.prototype.toString.call(arr));//[object Array]
    7. console.log(Object.prototype.toString.call(obj));//[object Object]
    8. console.log(Object.prototype.toString.call(fun));//[object Function]
    9. console.log(Object.prototype.toString.call(s1)); //[object Symbol]
    10. console.log(Object.prototype.toString.call(map));//[object Map]
    11. console.log(Object.prototype.toString.call(set)); //[object Set]
    12. function Person(){}
    13. function Student(){}
    14. Student.prototype = new Person()
    15. var haoxl = new Student()
    16. console.log(Object.prototype.toString.call(haoxl));//[object Object]

    参考:js判断数据类型 - SegmentFault 思否由结果可知typeof可以测试出number、string、boolean、undefined及function,而对于null及数组、对象,typeof均检测出为object,不能进一步判断它们的类型。https://segmentfault.com/a/1190000015264821

    三.深拷贝

    1.常见的浅拷贝

    1.1 Object.assign

    将obj1和obj2中的可枚举属性拷贝到第一个目标对象中,并且将这个对象返回

    let obj = Object.assign({},obj1,obj2);

    1.2 Array.prototype.concat()

    将alpha和numeric合并为一个新数组并返回

    1. var alpha = ['a', 'b', 'c'];
    2. var numeric = [1, 2, 3];
    3. alpha.concat(numeric);
    4. // result in ['a', 'b', 'c', 1, 2, 3]

    1.3 Array.prototype.slice()

    slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。

    1. const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
    2. console.log(animals.slice(2));
    3. // expected output: Array ["camel", "duck", "elephant"]
    4. console.log(animals.slice(2, 4));
    5. // expected output: Array ["camel", "duck"]

     1.4 扩展运算符 ...

    参考:https://github.com/YvetteLau/Step-By-Step/issues/17https://github.com/YvetteLau/Step-By-Step/issues/17

    2.简单实现深拷贝

    JSON.parse(JSON.stringify(obj))

    • 可以处理普通值(string,number,boolean),对象数组
    • 不能处理函数map,set,symbol类型的值
    • 并且当对象中包含循环引用时会报错(obj.info = obj)

    3.完整的深拷贝

    封装一个函数来实现:

    1. function isObject(value) {
    2. const valueType = typeof value
    3. return (value !== null) && (valueType === "object")
    4. }
    5. function deepClone(originValue, map = new WeakMap()) {
    6. // 判断是否是一个Set类型
    7. if (originValue instanceof Set) {
    8. return new Set([...originValue])
    9. }
    10. // 判断是否是一个Map类型
    11. if (originValue instanceof Map) {
    12. return new Map([...originValue])
    13. }
    14. // 判断如果是Symbol的value, 那么创建一个新的Symbol
    15. if (typeof originValue === "symbol") {
    16. return Symbol(originValue.description)
    17. }
    18. // 判断如果是函数类型, 那么直接使用同一个函数
    19. if (typeof originValue === "function") {
    20. return originValue
    21. }
    22. // 判断传入的originValue是否是一个对象类型
    23. if (!isObject(originValue)) {
    24. return originValue
    25. }
    26. if (map.has(originValue)) {
    27. return map.get(originValue)
    28. }
    29. // 判断传入的对象是数组, 还是对象
    30. const newObject = Array.isArray(originValue) ? []: {}
    31. map.set(originValue, newObject)
    32. for (const key in originValue) {
    33. newObject[key] = deepClone(originValue[key], map)
    34. }
    35. // 对Symbol的key进行特殊的处理
    36. const symbolKeys = Object.getOwnPropertySymbols(originValue)
    37. for (const sKey of symbolKeys) {
    38. // const newSKey = Symbol(sKey.description)
    39. newObject[sKey] = deepClone(originValue[sKey], map)
    40. }
    41. return newObject
    42. }

  • 相关阅读:
    遗传算法解决旅行商问题
    我复现的第一个神经网络: LeNet
    java计算机毕业设计-食材采购平台-源码+数据库+系统+lw文档+mybatis+运行部署
    张高兴的 .NET IoT 入门指南:(八)基于 GPS 的 NTP 时间同步服务器
    【21天算法挑战赛】排序算法——直接插入排序
    Bean作用域
    OpenHarmony源码分析(二):系统安全
    pytorch编程用法记录
    小程序全局变量与组件内部实时监听全局变量的改变
    设计模式(十六)----结构型模式之代理享元模式
  • 原文地址:https://blog.csdn.net/ICanWin_lll/article/details/125514434