API:http://www.w3school.com.cn/jsref/jsref_obj_array.asp
什么是数组?
一组数据。 (通常情况下,数据的类型是需要保持一致的)
在JS中, 数据类型是可以不统一的。
数组能保存什么数据?
没有任何限制 , 可以保存所有类型
如何创建一个数组?
//两种方式
var arr = new Array("小明", 30, "安阳");
//可以手动指定长度
var arr2 = new Array(5);
//但打印数组时,数组不显示内容, 每一位上都是undefined
// 注意是使用new Array时,若只有一个参数时表示的是数组的长度
//数组里保存了两个元素 5 和 3
var arr3 = new Array(5,3);
var arr4 = [1,2,3];//这种方式更为常见
数组的长度可变吗?
在普通编程语言当中,数组长度是不可变的。
而在JS当中,数组长度是可变的。
tips:
清空数组 arr.length = 0
截取数组前n为 arr.length = n;
我们删除元素,添加元素,不需要关心长度,它会自动变化
JS里面,也没有下标越界的概念
数组的下标为什么从0开始?
老外的习惯, 0也算是自然数
数组为什么是object类型?
JS是面相对象的语言
JS数组的本质,就是对象。 对象的本质,是哈希。 哈希的本质是数组
//原理: 在JS中,数组实际上是一个做了特殊处理的对象
var obj = {
"0" : 1,
"1" : 2,
"2" : 3,
"3" : 4,
"length" : 4
}
那么我们同样可以使用循环进行遍历
for(var i=0; i<obj.length; i++) {
console.log(obj[i]);
}
传入的参数是对象就放在堆里(栈里放的是堆的指针),不是对象就放在栈里
什么是哈希? hash
加密: 按照一定的规则,将原文转换,当这个规则不公开时,则为加密
MD5\SHA1
加密规则,必须保证不同的原文,转换后,会出现不同的密文, 当密文不同时,则可以肯定原文不同
举例: 云盘秒传文件
JS中数组的结构
[key:value, key:value]
var arr = new Array();
var arr2 = new Object();
arr[0] = arr2[0] = 100;
arr["age"] = arr2["age"] = 25;
for-in循环
var arr = [10,12,15,20,34];
for(var i=0; i<arr.length; i++){
console.log(arr[i]);
}
for(var i in arr){ //i是下标
console.log(arr[i]);
}
for-in也可以遍历对象
数组的常见API
//在末尾添加一个元素
arr.push(15);
//在开头添加一个元素
arr.unshift(99);
//在末尾获取并删除
arr.pop()
//
删除并返回数组的第一个元素
arr.shift();
arr = [1,2,3,4]
var str = arr.join("#");
// "1#2#3#4"
数组的默认排序
arr.sort();
arr.sort(function(pre,next){
return pre-next;
})
说明 http://www.w3school.com.cn/jsref/jsref_sort.asp
如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
- 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
- 若 a 等于 b,则返回 0。
- 若 a 大于 b,则返回一个大于 0 的值。
-
/*按照对象的年龄从大到小进行排序*/ function Man(name,age){ this.name=name; this.age=age; } var mans=[]; mans.push(new Man("小明",14)); mans.push(new Man("小红",28)); mans.push(new Man("小刚",19)); mans.sort(function(a,b){ return b.age-a.age; }); console.log(mans);
Q:如何判断某变量是否为数组数据类型? -
方法一.判断其是否具有“数组性质”,如push()方法。由于自己也可以给该变量定义push方法,所以这种方式并不准确
方法二.obj instanceof Array在某些IE版本中不正确
方法三.方法一二皆有漏洞,在ECMA Script5中定义了新方法Array.isArray(),保证其兼容性,最好的方法如下:
if(typeofArray.isArray==="undefined"){ Array.isArray = function(arg){ return Object.prototype.toString.call(arg)==="[object Array]" } }
冒泡排序算法
function select(arr){//冒泡排序
for(var i=0;i<arr.length-1;i++){
for(var j=0;j<arr.length-i;j++){
if(arr[j]>arr[j+1]){
var t=arr[j];
arr[j]=arr[j+1];
arr[j+1]=t;
}
}
console.log(arr);
}
}
select([12,9,38,44,98,7,35,59,49,88,38]);
选择排序算法
function select(arr){//选择排序
for(var i=0;i<arr.length-1;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
var t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
console.log(arr);
}
}
select([12,9,38,44,98,7,35,59,49,88,38]);
快速排序法
function quick_sort(arr){//快速排序
if(arr.length<=1)return arr;//当传入的数组长度为1或0时跳出
var midIndex=parseInt(arr.length/2);//中间值索引
var midValue=arr[midIndex];//中间值
var left=[];//比中间值小的放左边
var right=[];//比中间值大或等于的放右边
for(var i in arr){
if(i==midIndex)continue;//跳过中间值
arr[i]<midValue?left.push(arr[i]):right.push(arr[i]);
}
return quick_sort(left).concat(midValue,quick_sort(right));//返回结果
}
console.log(quick_sort([12,9,38,44,98,7,35,59,49,88,38]));
插入排序
当前元素的前面如果已经没有元素,则无需插入。
如果要插入的元素 < 前一个元素,则进行交换。
依次类推
var list =
[12,9,38,44,98,7,35,59,49,88,38];
function insertSort(arr){
for(var i=0; i<arr.length; i++){
var n = i;
while( arr[n] < arr[n-1] && n-1>=0 ){
var temp = arr[n];
arr[n] = arr[n-1];
arr[n-1] = temp;
n--;
}
}
return arr;
}
function insert_sort(arr){//插入排序
for(var i=0;i<arr.length;i++){
for(var j=i;j>0;j--){
if(arr[j]<arr[j-1]){
var tmp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=tmp;
}else{
break;
}
}
console.log(arr);
}
}
console.log(insert_sort([12,9,38,44,98,7,35,59,49,88,38]));
希尔排序
var list =[12,9,38,44,98,7,35,59,49,88,38];
function shell(arr){
var interval = parseInt(arr.length/2); //定义一个间隔
while(interval>=1){
console.log("间隔"+interval);
for(var i=0; i<arr.length; i++){
//插入排序
var index = i;
while(arr[index] < arr[index-interval] && index-interval>=0){ //按照间隔做插入排序
//交换
[arr[index], arr[index-interval]] = [arr[index-interval], arr[index]];
index -= interval;
}
}
console.log("结果: "+arr);
interval = parseInt(interval/2);
}
return arr;
}
function shell_sort(arr){//希尔排序
for(var j=parseInt(arr.length/2);j>=1;j=parseInt(j/2)){//j为步长,一般来说步长的确定没有严格的要求,但必须有为1的步长
for(var i=j;i<arr.length;i++){// 遍历数组
for(var k=i;k>0;k-=j){//对间隔为步长的元素进行插入排序
if(arr[k]<arr[k-j]){
var tmp=arr[k];
arr[k]=arr[k-j];
arr[k-j]=tmp;
console.log(arr);
}else{
break;
}
}
}
}
}
console.log(shell_sort([12,9,38,44,98,7,35,59,49,88,38]));
引用传递
var a = [1,2,3];
function add(arr){
arr[0]++;
}
add(a);
console.log(a); // [2,2,3]
伪数组如何转换为数组? (http://www.cnblogs.com/NTWang/p/6280447.html)
伪数组举例:
var list = document.getElementsByTagName("p");
var test = function(){
console.log(argument);//arguments就是伪数组
}
将伪数组转化为数组对象:
方法一、
var list = document.getElementsByTagName("p");
function toArray(list){ //遍历伪数组,返回新数组
var newList = [];
for (var i = 0; i < list.length; i++) {
newList.push(list[i]);
}
return newList;
}
console.log(toArray(list));
方法二、使用数组的slice()方法,使用call或者apply指向伪数组
var list = document.getElementsByTagName("p");
var newList = Array.prototype.slice.call(list);
console.log(newList);
slice函数
从某个已有的数组返回选定的元素 http://www.w3school.com.cn/jsref/jsref_slice_array.asp
Array.prototype.slice = function(start,end){//模拟实现slice
var result = [];
var start = start || 0;
//this指向调用的对象,可使用call或apply重定向
var end = end || this.length;
for(var i=0; i < end; i++){
result.push(this[i]);
}
return result;
}
方法三、原型继承
var list = document.getElementsByTagName("p");
list.__proto__ = Array.prototype;
console.log(list instanceof Array);
方法四、
ES6中数组的新方法 Array.from()
var list = document.getElementsByTagName("p");
console.log(Array.from(list) instanceof Array);
call方法
在JS里面,所有的函数,都属于对象
arr.slice();
function test(){
}
window.test();
既可以
对象.函数名()
也可以
函数.调用(对象); //JAVA反射机制
举例:
window.test();
test.call(window);
var arr = { };
arr.test(); // 错误!!!
test.call(arr); //正确!
等价于
arr.test();
list.slice(); //错误!
var newlist = [].slice.call(list); //等价于 list.slice()