飞道的博客

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

420人阅读  评论(0)

一.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. }


转载:https://blog.csdn.net/ICanWin_lll/article/details/125514434
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场