Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript的对象型数组(Array) #7

Open
yyzclyang opened this issue May 15, 2018 · 0 comments
Open

JavaScript的对象型数组(Array) #7

yyzclyang opened this issue May 15, 2018 · 0 comments

Comments

@yyzclyang
Copy link
Owner

yyzclyang commented May 15, 2018

1 概述

Array是JavaScript的原生对象,Array.prototype是数组的原型;同时也是一个构造函数,可以用new Array其来声明新数组(其实加不加new效果一样)。

var a = new Array(1,2);
var b = Array(1,2);

Array来声明数组有一个很大的问题,就是参数的不同会导致不同的结果
1个参数

//空参数
new Array(); //定义一个空数组 []

//正整数
new Array(3); //定义一个长度为3的数组,每个value都为空

//非正整数数值
new Array(-3); //报错
new Array(1.2); //报错

//非数值
new Array('yyzcl'); //定义一个长度为1的数组 ['yyzcl']

多个参数

new Array(1,2); //定义一个长度为2的数组 [1,2]
new Array('yyzcl','yang','18'); //定义一个长度为3的数组 ['yyzcl','yang','18']

添加属性
数组可随时向里面添加属性,但不会改变length的值

var a = new Array(1,2);
a.name = 'YyzclYang';

2 伪数组

2.1 概述

伪数组就是有类似数组的结构,length属性的对象

从图中可以看到,a其实是一个对象,但它的结构几乎和数组一样,并且可以使用数组的取值方式来取对象中的值

var a = {0:1,1:2,2:3,length:3};
a[0] // 1
a[1] // 2

2.2 区别

虽然伪数组和数组很像,但其还是有本质的区别,先来个内存图

var a = [1,2,3];
var b = {0:1,1:2,2:3,length:3};


从内存图可以看出,数组的__proto__是指向Array.prototype的,而伪数组的__proto__是直接指向Object.prototype
所以伪数组虽然结构和数组很相似,但是没有数组独有的一些方法函数

2.3 如何转为真数组

在JavaScript中,函数的隐藏变量arguments document.querySelectAllgetElementsByTagName 等,都是伪数组,它们无法使用数组的push等方法,除非现将其转为真数组
可以通过以下几种方式将伪数组转为真数组

2.3.1 Array.prototype.slice.call()

var a = {0:1,1:2,2:3,length:3};
Array.prototype.slice.call(a);

2.3.2 [].slice.call()

var a = {0:1,1:2,2:3,length:3};
[].slice.call(a);

2.3.3 Array.from()

var a = {0:1,1:2,2:3,length:3};
Array.from(a);

3 Array的几个API

3.1 forEach()和map()

语法

array.forEach(function(value, key, array){
    //do something
}, this)

其中this是可选参数,functionarray参数在某些情况下也可以不写
forEach()的用处是将数组中的每一组值以value-key的形式传递给function,调用函数执行一次
例如

var arr =  [1,2,3,4,5];
arr.forEach(function(value, key){
    console.log(key+' : '+value);
})

//结果为
0 : 1
1 : 2
2 : 3
3 : 4
4 : 5

map()forEach()很相似,不过map()会将函数运行结果返回

var arr =  [1,2,3,4,5];
arr.map(function(value,key){
    return value*2;
})

//结果为 [2,4,6,8,10]

3.2 sort()

sort()对数组的元素进行排序,并返回数组。sort排序不稳定。默认排序顺序是根据字符串Unicode码点。

var fruit = ['cherries', 'apples', 'bananas'];
fruit.sort(); 
// ['apples', 'bananas', 'cherries']

var scores = [1, 10, 21, 2]; 
scores.sort(); 
// [1, 10, 2, 21]
// 注意10在2之前,
// 因为在 Unicode 指针顺序中"10"在"2"之前

var things = ['word', 'Word', '1 Word', '2 Words'];
things.sort(); 
// ['1 Word', '2 Words', 'Word', 'word']
// 在Unicode中, 数字在大写字母之前,
// 大写字母在小写字母之前.

也可以给用下面的语法,给sort传递一个函数

arr.sort(function(a,b){})
  • 如果function(a, b)小于 0 ,那么 a 会被排列到 b 之前;
  • 如果function(a, b)等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);
  • 如果function(a, b)大于 0 , b 会被排列到 a 之前。
    -function(a, b)必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。

如果参与排序的是数字数组,可以用以下函数来进行升序排序

arr.sort(function(a, b) {
  return a - b;
})

注意:sort()会改变原数组,而其他API的使用则不会

var arr = [12,5,27,0,19,6];
arr.sort(function(a, b) {
  return a - b;
})
console.log(arr);

3.3 concat()

concat()是将两个或多个数组合并,且并不会影响原数组的值

var arr1 = [1,2,3];
var arr2 = [4,5,6];
arr1.concat(arr2); // [1,2,3,4,5,6]

也可以利用concat来复制数组,并且复制的数组并不等于原数组,因为他们的栈内存不同,指向不同的堆内存数据

var arr1 = [1,2,3];
arr3 = arr1.concat([]);
arr3 === arr1; // false

3.4 filter()

filter()是一个判断函数,返回能通过所提供函数测试的数组中的值

var arr = [1,2,3];
arr.filter(function(value, key) {
  return value >= 2;
})
// [2,3]

3.5 reduce()

首先看看reduce()的用法

arr.reduce(function(result,value){
  return parameter1;
},parameter0)

reduce对数组中的每一个元素应用一次函数
首先parameter0作为result的初始值传入,而每次对数组取元素时,都将上一次的返回值parameter1作为这次去数组元素时的result值传入
利用这一点,reduce可以做很多事,甚至是模仿别的API

3.5.1 求和

var arr = [1,2,3,4,5];
arr.reduce(function(sum,value){
  var s = sum + value;
  return sum += value;
},0)
// 15

这里当取数组的第一个元素是,sum=0,value=1,运行一次function之后,s变成1,并传递给sumsum变成1进行下一次函数的运行。

3.5.2 “模仿”map()

var arr1 = [1,2,3,4,5];
arr.reduce(function(arr,value){
  arr.push(value*2);
  return arr;
},[])
// [2,4,6,8,10]

3.5.3 “模仿”filter

var arr1 = [1,2,3,4,5];
arr.reduce(function(arr,value){
  if(value >= 3)
  arr.push(value);
  return arr;
},[])
// [3,4,5]

Array的API还有很多,就不在这里一一说明了,又想了解更多的可以点击这里

本文如有错误纰漏之处,欢迎指出。

@yyzclyang yyzclyang changed the title 2018.05.15 JavaScript的对象型数组(Array) JavaScript的对象型数组(Array) Aug 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant