如何判断数组类型
- typeof ❌
对Array不起作用,会将结果判断为object,同理null - instanceof操作符:检测对象的原型链是否指向构造函数的prototype对象的,【不完美】
- 对象的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
- Object.prototype.toString
Object.prototype.toString.call(o) === '[object Array]';
- 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(value1value2){return 1;}
else {return 0}
}
arr.sort(compare);
alert(arr); //1,2,3,4,5,10
结果:
首先两两比较,若返回-1,位置不变继续下一组比较;返回+1则调换位置,此时不是接着下一组比较,而是与前一组比较,判断为-1或+1,如此循环,直到排序完成。