javascript之Array基础篇
整理了 Array 中很基础的要掌握的知识点,希望可以帮助初学者,也希望自己以后多用多融会贯通。
创建数组
- 使用Array构造函数:
var a=new Array();//创建一个空数组
var a=new Array(20);//创建给定数值的项数的数组
var a=new Array("a","b","c");//包含3个字符串值的数组
var a=Array();//可以省略new关键字
var a=Array(3);
给构造函数传递一个值也可以创建数组:
- 如果传递的数值,则会创建数值给定项数的数组
- 如果传递的是其他类型的参数,则会创建则会创建包含那个值的只有一项的数组
- 使用数组字面量表示法:
var a=['a','b','c'];//创建一个包含三个字符串的数组
var a=[];//创建一个空数组
不建议如图写法:
原因:<=IE8版本中的ECMAScript实现在数组字面量方面存在bug,a会成为一个包含3个项,其值为 [1,3,undefined] , [undefined,undefined,undefined] (这个结果与 new Array(3) 逻辑上相同)
数组长度length属性
数组的 length 属性不是只读的(不太清楚value特性的值为何总是数组第二项的值,而且当数组 length<=1 时,则 Object.getOwnPropertyDescriptor(a,length) 返回为 undefined ,知道的盆友感谢告知!)。
因此通过设置这个属性,可以从数组末尾移除项。但若将 length 设置为大于数组项数的值,后面的值会为 undefiend 。
var a=['a','b','c'];
a.length=2;
console.log(a[2]);//undefined
可以向数组中添加项
var a=['a','b','c'];
a[a.length]='d';//["a", "b", "c", "d"]
当把一个值放在超出当前数组大小的位置,数组会重新计算其长度。
var a=['a','b','c'];
a[99]='p';
a.length;//
a[3];//a[3]~a[98]都为undefined
检测数组
- a instanceof Array;//true 判断a是否为 Array 的实例
缺点: instanceof 假定当前只有一个全局执行环境。如果在网页中包含多个框架,那么存在两个以上不同的全局执行环境,从而存在两个以上不同版本 window ,不同版本的 Array 构造函数,如果从一个框架向另一个框架输入数组,那么传入的该数组和目标框架的数组可能有不同的构造函数,这样就不能判断是否是实例了。以上代码要返回 true ,a必须是一个数组且和 Array 构造函数在同一个全局作用域中,而 Array 又是 window 的属性。如果a是在另一个 frame 中定义的的数组,那么以上代码会返回 false 。写了个不同框架引用数据测试了一下,还牵扯到chrome由于同源策略出现的一些问题,感兴趣的请戳http://www.cnblogs.com/venoral/p/5232676.html
- Array.isArray(a);//true 不分环境,只判断最终确定的某个值到底是不是数组
- Object.prototype.toString.call(a) 原生数组的构造函数名 Array 与全局作用域无关,使用 toString() 可以保证返回一致的值。
在任何值上调用 Object 原生的 toString() 方法,都会返回一个 [object NativeConstructorName] 格式的字符串,每个类内部都有一个 [[class]] 属性,这个属性中就指定了上述字符串中的构造函数名。基于这一思路也可检测某个值是不是原生函数或正则表达式。但是不能检测非原生构造函数的构造函数名,自定义的任何构造函数都将返回 [object Object] 。
下面介绍的各种数组方法均来自 Array.prototype
转换方法
var a=['a','b','c'];
a.toString();//"a,b,c" 为了创建这个字符串会调用数组的每一项toString()方法,若为a.toLocaleString()则会调用数组每一项的toLocaleString()
a.valueOf();//["a","b","c"]
调用数组的 toString() 方法返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串,但调用 valueOf() 返回的还是数组
a.join();//"a,b,c"
a.join(undefined);//"a,b,c"
a.join('||');//"a||b||c"
join() 方法只接收一个参数,即用作分隔符的字符串,返回包含所有数组项的字符串。不给 join() 传任何值或传入 undefined (<=IE7会使用 undefined 分隔符)则使用逗号作为分隔符。
如果数组中的某一项值为 null 或 undefined ,那么该值在 join() , toLocaleString() , toString() , valueOf() 方法返回的结果中以空字符串表示。
a=[3,undefined,null,''];
a.toString();//"3,,,"
栈方法
push() 方法接受任意数量的参数(参数可以有多个,多参数添加顺序是从左到右),把他们逐个添加到数组末尾,返回修改后数组长度。
pop() 方法从数组末尾移除最后一项,减少数组 length ,返回移除的项。
队列方法
shift() 移除数组中第一个数并返回该项,同时将数组长度减一。结合使用 shift 和 push 方法可以像使用队列一样使用数组。
unshift() 在数组前端添加任意个项(多参数添加顺序先右后左)并返回新数组长度(<=IE7返回 undefined )。同时使用 unshift 和 pop 方法可以从相反方向模拟队列。
var a=['a','b','c'];
a.unshift('o','p','q');//6
a;["o", "p", "q", "a", "b", "c"]
重排序方法
reverse() 反转数组项的顺序,返回反转后的原数组。
sort() 方法按升序排列数组项,返回排序后的原数组。为了实现排序, sort() 方法会调用每个数组项的 toString() 转型方法,然后比较得到的字符串,以确定如何排序(个人觉得是按照ASCII表比较的, sort 内部比较排序算法的实现标准中并没有定义,可能是冒泡或快排,感兴趣可参考我另篇文章http://www.cnblogs.com/venoral/p/5180439.html)。即使数组中每一项都是数值, sort() 方法比较的也是字符串,看下面代码
再进行字符串比较时,“10"位于“5”的前面,对照ASCII表,“1”的十进制是49,“5”的十进制是53。因此 sort() 方法可以接收一个比较函数(接收两个参数)作为参数,以便认为指定哪个值位于哪个值前面。
var compare=function(value1,value2){
if(value1<value2) return -1;
else if(value1>value2) return 1;
else return 0
}
var a=[1,5,10,6];
a.sort(compare);//[1,5,6,10]
对于数值类型或其 valueOf() 方法会返回数值类型的对象类型,可以使用一个更简单的比较函数,这个函数只需要第二个值减第一个值就能产生降序结果(升序就是被减数和减数交换)。之所以能这样做是因为 sort() 内部根据返回的一个小于0,大于0,等于0来影响排序结果。
var compare=function(value1,value2){
return value2-value1;
}
var a=[1,5,10,6];
a.sort(compare);//[10, 6, 5, 1]
操作方法
concat() 基于当前数组中所有项创建一个新数组。这个方法会先创建当前数组的一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。
- 在没有传参的情况下,它只是复制当前数组并返回副本。
- 传给 concat() 方法的是一个或多个数组,该方法会将这些数组中的每一项都添加到结果数组中。
- 传递的值不是数组,这些值就会被简单的添加到结果数组的末尾。
slice() ,翻译过来为”切出“,它能够基于当前数组中一个或多个项创建一个新数组。 slice 方法接受1~2个参数,即要返回项的起始和结束位置。
- 不传参,返回复制原数组的一份新数组。
- 只有一个参数情况下,返回从该参数指定位置到当前数组末尾的所有项。
- 两个参数,返回起始位置和结束位置之间的项(但不包括结束位置)。
- 参数中有负数情况下,则用数组长度加上该负数来确定相应位置。如果结束位置小于起始位置则返回空数组。如果计算出来的位置还是负数,则也只是复制当前数组并返回副本。
splice() ,翻译过来为”拼接“,主要用途为向数组中部插入项,该方法的使用会改变原数组。 splice() 始终都会返回一个数组,该数组中包含从原始数组中删除的项(如没有删除项则返回空数组)
- 删除:可以删除任意数量的项,返回删除的项。
- 无参数,则不会删除任何项。
- 只有一个参数,则会删除该项到当前数组末尾的所有项。
- 两个参数:要删除的第一项的位置和要删除的项数。
- 参数中有负数情况下,则用数组长度加上该负数来确定相应位置。要删除的项数若为负则返回空数组。
- 插入:可以为指定位置插入任意数量的项,三个参数:起始位置,0(要删除的项数),要插入的项,如果要插入多个项,可以再传入任意多个项。
- 替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项。三个参数:起始位置,要删除的项数,要插入任意数量的项。
位置方法
indexOf() 和 lastIndexOf() ,都接受两个参数:要查找的项,表示查找起点位置的索引(可选)。返回要查找的项在数组中的位置,在没找到情况下返回-1。在比较第一个参数与数组中每项时会使用全等操作符。
indexOf() 从数组的开头(位置0)向后查找, lastIndexOf() 从数组末尾向前查找。
a=['a','b','c','d','e','b'];
a.indexOf('b',2);//
a.lastIndexOf('b',0);//-1
a.lastIndexOf('b',5);//
var person={name:'xx'};
var people1=[{name:'xx'}];
var people2=[person];
people1.indexOf(person);//-1
people2.indexOf(person);//
迭代方法
每个迭代方法都接收两个参数:要在每项上运行的函数,运行该函数的作用域对象(即影响this的值)。传入这些方法中的函数可以会接收3个参数:数组项的值,该项在数组中位置,数组对象本身。
根据使用方法的不同,这个函数执行后的返回值可能会也可能不会影响方法中的返回值。
- every() :如果该函数对每一项都返回 true ,则整个数组调用函数完后返回值为 true 。
- filter() :返回该数组会返回 true 的项的组成的数组。该方法对查询符合某些条件的所有数组项非常有用。
- forEach() :没有返回值。
- map() :返回每次函数调用的结果组成的数组。该方法适合创建包含的项与另一个数组一一对应的数组。
- some() :如果该函数对数组中任一项返回 true ,则返回 true 。
every() 和 some() 的区别:
a=["a", "b", "c", "d", "e", "b"];
a.every(function(item,i,array){
return typeof item=='string'
});//true
a.some(function(item,i,array){
return item=='b';
});true
//利用指定的函数确定是否在返回的数组中包含某项
a.filter(function(item,i,array){
return item=='b'
});//["b", "b"] //返回数组的每一项都是在原始数组中对应项的基础上运行传入的函数的结果
a.map(function(item,i,array){
return item+'xx';
});//["axx", "bxx", "cxx", "dxx", "exx", "bxx"]
归并数组方法
reduce() 和 reduceRight() ,这两个方法都会迭代数组中的所有项,然后构建一个最终返回的值。都接收两个参数:在每一项上调用的函数(接收4个参数:前一个值,当前值,项的索引,数组对象),作为归并基础的初始值(可选)。这个函数返回的任何值都会做为第一个参数自动传给下一项。
注意:若忽略传入初始值时,第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数是数组的第二项。
reduce() 从数组的第一项开始,逐个遍历到最后。
reduceRight() 从数组最后一项开始,向前遍历到第一项。
------分割线-----
在知乎上看到 如何不使用loop循环,创建一个长度为100的数组,并且每个元素的值等于它的下标? 其实原因是forEach会将数组中被删掉的项或未赋值的项跳过,不过由于forEach是后来才加进来的,可以修改它的源码啦,更多的可以参考下面MDN的链接。惊觉原来 Array 身上还有这么多方法,整理一下!
参考:《javascript高级程序设计》
javascript之Array基础篇的更多相关文章
- JavaScript 面向对象(一) —— 基础篇
学好JS的面向对象,能很大程度上提高代码的重用率,像jQuery,easyui等,这篇博客主要从细节上一步步讲JS中如何有效地创建对象,也可以看到常见的创建对象的方式,最后也会附上一些JS面向对象的案 ...
- Javascript DOM 01 基础篇
DOM基础 DOM是什么 答:文件对象模型(Document Object Model,简称DOM),DOM可以以一种独立于平台和语言的方式访问和修改一个文档的内容和结构!来自网络 ...
- JavaScript 面向对象(三) —— 高级篇
JavaScript 面向对象(一) —— 基础篇 JavaScript 面向对象(二) —— 案例篇 一.json方式的面向对象 首先要知道,js中出现的东西都能够放到json中.关于json数据格 ...
- JavaScript 面向对象(二) —— 案例篇
看案例前可以先看看基础篇:JavaScript 面向对象(一) —— 基础篇 案例——面向对象的选项卡:把面向过程的程序一步步改成面向对象的形式,使其能够更加的通用(但是通用的东西,一般会比较臃肿). ...
- 一步步学习javascript基础篇(3):Object、Function等引用类型
我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...
- JavaScript笔记基础篇(二)
基础篇主要是总结一些工作中遇到的技术问题是如何解决的,应为本人属于刚入行阶段技术并非大神如果笔记中有哪些错误,或者自己的一些想法希望大家多多交流互相学习. 1.ToFixed()函数 今天在做Birt ...
- 前端开发工程师 - 02.JavaScript程序设计 - 第1章.基础篇
第1章--基础篇 JS介绍 html 网页的内容:css 网页的样式:javascript 网页的行为 i.e. hello world <!DOCTYPE html> <html& ...
- 一步步学习javascript基础篇(0):开篇索引
索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...
- [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析
[WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析 标签: webkit内核JavaScriptCore 2015-03-26 23:26 2285 ...
随机推荐
- 如何选择Javascript模板引擎(javascript template engine)?
译者 jjfat 日期:2012-9-17 来源: GBin1.com 随着前端开发的密集度越来越高,Ajax和JSON的使用越来越频繁,大家肯定免不了在前台开发中大量的使用标签,常见到的例子如下: ...
- iOS开发——实战篇Swift篇&UItableView结合网络请求,多线程,数据解析,MVC实战
UItableView结合网络请求,多线程,数据解析,MVC实战 学了这么久的swift都没有做过什么东西,今天就以自己的一个小小的联系,讲一下,怎么使用swift在实战中应用MVC,并且结合后面的高 ...
- Cocos2d-x v3.0 新的事件调度方法 lambda表达式的使用
欢迎添� Cocos2d-x 交流群: 193411763 转载请注明原文出处:http://blog.csdn.net/u012945598/article/details/24603251 Coc ...
- 剑指 offer set 6 打印从 1 到 N 的所有数
总结 1. 求全排列的变形题, 有些隐晦, 没看出来
- RC4加密算法
RC4是Ron Rivest在1987年设计的密钥长度可变的流加密算法.它加解密使用相同的密钥,因此也属于对称加密算法.RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS可采用的算法之一. ...
- Android点击Button实现功能的几种方法
Android中Button控件应该算作是比较简单的控件,然而,它的使用频率却是非常的高,今天,我在这里总结了三种常用的点击Button实现其功能的方法. 1.很多时候,我们在 ...
- 记录一下bing的图片 - 升级版冰糖葫芦
记录一下bing的图片 - 升级版冰糖葫芦
- python代码查询港澳通行证办理进度
查询港澳通行证办理进度查询的python 3.3代码.利用socket请求相关网站,获得结果后利用正则找出办理进度.其实用urllib代码会更简洁,不过当时在下还不熟悉urllib~ 直接上代码: i ...
- Python Learning
这是自己之前整理的学习Python的资料,分享出来,希望能给别人一点帮助. Learning Plan Python是什么?- 对Python有基本的认识 版本区别 下载 安装 IDE 文件构造 Py ...
- C# unix时间戳转换
场景:由于业务需要和java 开发的xxx系统对接日志,xxx系统中用“1465195479100” 来表示时间,C# 里面需要转换做一下逻辑处理,见代码段. C#获取的unix时间戳是10位,原因是 ...