美文网首页
数组、深浅拷贝

数组、深浅拷贝

作者: 糕糕AA | 来源:发表于2019-06-27 14:10 被阅读0次

    如何判断数组类型

    1. typeof ❌
      对Array不起作用,会将结果判断为object,同理null
    2. instanceof操作符:检测对象的原型链是否指向构造函数的prototype对象的,【不完美】
    3. 对象的constructor属性 :alert(arr.constructor === Array); // true
      方法2、3不完美,在iframe中不共享原型链,会失败
    var iframe = document.createElement('iframe'); //创建iframe
           document.body.appendChild(iframe); //添加到body中
           xArray = window.frames[window.frames.length-1].Array;
           var arr = new xArray(1,2,3); // 声明数组[1,2,3]
           alert(arr instanceof Array); // false
           alert(arr.constructor === Array); // false 
    
    1. Object.prototype.toString👍
      Object.prototype.toString.call(o) === '[object Array]';
    2. Array.isArray() 👍
      ES5加入,为了检测对象是否是数组
      Array.isArray(arr);

    数组复制方法

    • var arr2 = Object.assign([], arr); 或 var arr2 = []; Object.assgin(arr2, arr);
    • var arr2 = arr.map(item => item);
    • 扩展运算符:var arr2 = [...arr];
    • 从原数组中截取,组成新数组:var arr4 = arr.slice(0);
    • concat[] 接上一个空数组,返回新数组: var arr4 = arr.concat([]);
    • for 循环遍历一个个赋值

    数组去重

    • indexOf方法:新建一个数组,遍历去要重的数组,当值不在新数组的时候(indexOf为-1)就加入该新数组中;
    • 排序后去除相邻:给传入的数组排序,排序后相同的值会相邻,然后遍历排序后数组时,新数组只加入不与前一值重复的值。
    • ES6 set数据结构:它类似于数组,但是成员的值都是唯一的,没有重复的值。Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。
      function unique5(arr){
      var x = new Set(arr);
      return [...x];
      }

    深拷贝 浅拷贝

    基本数据类型:undefined、null、boolean、number、string,直接存在栈(stack)中,单独存在,互相之间没有联系。

    引用类型:复杂数据类型Object,存储的是该对象在栈中引用,真实的数据存在堆内存中。引用类型的赋值只是给了堆内存对象中的引用指针,当一个改变后,另一个也会改变

    浅拷贝:浅拷贝只复制对象的第一层属性,第二层甚至更多层只拷贝其引用

    深拷贝:把一个对象中所有属性和方法一个个找到,并且在另一个对象中开辟相应空间,一个个存储到另一个对象中

    • 不完美深拷贝1:Object.assign(target, source):用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。 当我们不涉及到第二层或者更深层的包含复杂数据类型,可见Object.assign()方法是基本可行的,但是如果对象中包含另一层Object或者Array这样的引用类型,他们还是保存的指针,而不是真的复制出一个新的Object或者Array
    • 不完美深拷贝2:JSON.stringify()和JSON.parse()他无法实现对函数 、RegExp等特殊对象的克隆 2. 会抛弃对象的constructor,所有的构造函数会指向Object 3. 对象有循环引用,会报错
    • 手动实现(不成熟):
          function extend(source,targrt){
              for(var key in source){
                  var item = source[key]
                  if(item instanceof Array){
                      targrt[key] = []
                      extend(item,targrt[key])
                  }else if(item instanceof Object){
                      b[key] = {}
                      extend(item,b[key])
                  }else{
                      b[key] = item
                  }
              }
          }
    
    • 最佳深拷贝:Lodash的_.cloneDeep,Lodash是一个一致性、模块化、高性能的JavaScript实用工具库 ,判断的项目测20来项,不仅有数据类型的判断,还有浮点数的判断,多少位的浮点数的判断,反正就是很多判断,以及边界考虑。
    • var deep = _.cloneDeep(objects);
      

    数组sort方法使用、排序方式、V8为什么这样排序(22以下归并,以上快排)

    根据MDN上对Array.sort()的解释,默认的排序方法会将数组元素转换为字符串,然后比较字符串中字符的UTF-16编码顺序来进行排序。

    V8 引擎 sort 函数只给出了两种排序 归并 和 快排,数量小于10的数组使用 InsertionSort,比10大的数组则使用 QuickSort。v8引擎Array源码连接

    10以下举例:

    var arr=[1,3,10,4,2,5];
     function compare(value1,value2) {
     console.log(value1,value2,arr);
     if(value1<value2){return -1;}
     else if(value1>value2){return 1;}
     else {return 0}
     }
     arr.sort(compare);
     alert(arr);   //1,2,3,4,5,10</pre>
    
    结果: image

    首先两两比较,若返回-1,位置不变继续下一组比较;返回+1则调换位置,此时不是接着下一组比较,而是与前一组比较,判断为-1或+1,如此循环,直到排序完成。

    相关文章

      网友评论

          本文标题:数组、深浅拷贝

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