数组排序
利用数组自带的 sort 方法可以实现排序功能(默认升序),例如这样
var arr = [1, 3, 6, 2, 4];var sortArr = arr.sort(); // [1,2,3,4,6]
如果要降序排序的话,可以这样
var newArr = arr.sort(function (a1, a2) { return a2 - a1; // 后面大于前面的调换,就是降序排序});
不仅可以对数字数组排序,还可以对对象数组排序,例如
var arr = [ { name: 'kobe', age: 40 }, { name: 'james', age: 36 }, { name: 'durant', age: 38 },];var sortArr = arr.sort(function (a1, a2) { return a2.age - a1.age;});// [{"name":"kobe","age":40},{"name":"durant","age":38},{"name":"james","age":36}]
数组拷贝
常用的数组拷贝有 3 种方法
- for 循环
- concat
- slice
上面 3 个方法可以实现简单的浅拷贝,但是遇到对象数组,每一项会存在单个对象的引用,例如
var arr = [{ name: 1 }, { name: 2 }];var newArr = arr.slice();newArr[0].name = 200;console.log(arr[0].name); // 200var newArr2 = arr.concat();newArr2[0].name = 300;console.log(arr[0].name); // 300
上面修改 newArr 和 newArr2 对象的 name 会影响到原数组的数据,所以需要深拷贝来消除对象的引用
function depCopy(objectToBeCloned) { // 基本类型 if (!(objectToBeCloned instanceof Object)) { return objectToBeCloned; } var objectClone; // 判断类型 var Constructor = objectToBeCloned.constructor; switch (Constructor) { // 特殊对象 case RegExp: objectClone = new Constructor(objectToBeCloned); break; case Date: objectClone = new Constructor(objectToBeCloned.getTime()); break; default: objectClone = new Constructor(); } // 克隆属性 for (var prop in objectToBeCloned) { objectClone[prop] = depCopy(objectToBeCloned[prop]); } return objectClone;}// 验证代码var arr = [{ name: 1, hob: [2, 3] }];var newArr1 = depCopy(arr);newArr1[0]['hob'][1] = 3000;console.log(arr[0]['hob'][1]); // 3arr = [{ name: 1 }, { name: 2 }];var newArr2 = depCopy(arr);newArr2[0]['name'] = 2000;console.log(arr[0]['name']); // 1arr = [ [1, 3], [2, 4],];var newArr3 = depCopy(arr);newArr3[0][0] = 1000;console.log(arr[0][0]); // 1
还有一种更暴力的方法,不过缺点就是数组如果太大,解析时性能会有影响
JSON.parse(JSON.stringify(arr));
新建一个长度为 10000 的 *
字符串
最笨的方法,for 循环,如下
var str = '';for (var i = 0; i < 10000; i++) { str += '*';}
另一种超简单的写法:
var n = new Array(10000).join('*');
少用递归,多用循环
递归和循环大部分情况下是可以互换的,一个经典的例子就是斐波纳契数列,解决方法通常就是用递归来实现,例如这样
function fib(n) { if (n == 1 || n == 2) { return 1; } else { return fib(n - 1) + fib(n - 2); }}
代码是很简单,但是有一个严重的问题就是递归层次太深效率会非常慢,以上可以用循环来解决
function fib2(n) { if (n == 1 || n == 2) { return 1; } else { var sum = 0, start = 1, next = 1, index = 2; while (index < n) { sum = start + next; start = next; next = sum; index++; } return sum; }}
测试了一下,n = 40 时候效率差距是很大的,时间差距很啊,当 n 更大的时候,递归会导致浏览器卡死
数组的判断
var arr = [];1. Array.isArray(arr);2. arr instanceof Array3. arr.constructor === Array // null不适用4. var toString = Object.prototype.toString;toString.call(arr) === '[object Array]'
最后一个可以判断所有数据类型,兼容性高
数组最大和最小值
var numbers = [1, 4, -2, 42, 11, -33];var max = Math.max.apply(Math, numbers);var min = Math.min.apply(Math, numbers);