JavaScript数组之概论

参考:http://www.cnblogs.com/dolphinX/p/3353590.html

数组是一段线性分配的内存,它是通过整数计算偏移量并访问其中的元素,所以数组是性能出色的数据结构,但JavaScript没有像此类数组一样的数据结构

作为替代,JavaScript提供一种拥有类数组(array-like)特性的对象。

JavaScript本质是Object,多提供了一个length 属性 && 继承Array

var a = {
  length:1
}
var arr = Array.prototype.slice.call(a,0);
console.log(Array.isArray(arr));
//返回 true 证明:只要有length 就能转为Array 参见附录,这样并不能证明什么

1数组的创建和length属性

1.1 数组创建(两种创建方式)

1.1.1字面量创建

var a = [];
var b = [2];//字面量创建 不管参数是几个 都无法像“new Array(3)”创建length为3的数组
var c = [1,2,3];

1.1.2 构造函数创建

var a=new Array();
var b= new Array(3);
var c = new Array("a","b");
var d = Array(3);  //可以省略 new
var e=Array("a","b");

1.1.3 数组判断

由于JavaScript的内置类型检测并不完全可靠(具体为什么不可靠,参见后续博客

所以Array 判断也是 原理 调用Object.protptype.toString()方法

参见:http://www.cnblogs.com/ziyunfei/archive/2012/11/05/2754156.html

function isArray(arr){
//判断是否是数组 Object.prototype.toString是一个[native code]
  return Object.prototype.toString.call(arr) ==="[object Array]"
}
var a = [];
isArray(a);//true

1.2 数组length

每个数组都有length属性,但和java不同,javascript数组length没有上界,可以自己手动改变length 大小,导致一系列问题,也是一些列美妙的开始

手动改变length

/*eg1*/
var a = [1,2,3];
console.log(a.length);//3
a.length = 100;
console.log(a.length);//100
/*eg2*
* 虽然直接对a[100]赋值不会影响a[4]或a[99],但数组的长度却受到影响,数组length属性等于数组中最大的index+1,我们知道数组的length属性同样是个可写的属性,当强制把数组的length属性值设置为小于等于最大index值时,数组会自动删除indexd大于等于length的数据,
/
var a = [1,2,3];
console.log(a.length);//3
a[100] = 100;
console.log(a.length);//101
console.log(a[99]);//undefined  如果数组未具体的赋值,则为"undefined"

var b = [1,2,3];
console.log(b);//VM1679:3 [1, 2, 3]
b.length = 2;
console.log(b);//VM1679:5 [1, 2]
/*eg3
* 本质上JavaScript数组是一个object对象 所以可以使用a[‘s‘] = ‘s‘来设置属性
* a[-10] = -10; 个人认为是设计不严谨 因为“-10”属性被当成属性(非array数字属性),但JavaScript Object 不能通过‘-10’来访问
*/
var a = [1,2,3];
console.log(a.length);//3
a[-10] = -10;
a[‘s‘] = ‘s‘;//
console.log(a.length);//3
console.log(a); //[1, 2, 3, -10: -10, s: "s"] 

2.数组的增删改查

2.1 添加和删除方法

2.1.1数组头部添加和删除(shift和unshift)

var arry = [1,2,3];
arry.unshift(4);
console.log(arry);
//[4, 1, 2, 3]
console.log(arry.shift());//4,注意:返回的是被删除的元素
console.log(arry);//[ 1, 2, 3]

2.1.2数组尾部添加和删除(push和pop)

var arry = [1,2,3];
console.log(arry.push(4));//4 尾部添加
console.log(arry);//[ 1, 2, 3, 4]
console.log(arry.pop());//4  尾部删除
console.log(arry);//[ 1, 2, 3]

2.1.3 数组中间(任意位置)添加和删除

使用splice 万能的方法 w3c splice 方法的解释

/*添加*/
var arry = [1,2,3];
//添加 注意 第二个参数为“0”
console.log(arry.splice(1,0,4));//[] 这个返回的值是 被删除的数组
console.log(arry);//[1, 4, 2, 3]
/*删除*/
var arry = [1,2,3];
console.log(arry.splice(1,1));
//注意删除参数(第一个参数:删除的第几位,从0开始,第二个表示删除几位)
console.log(arry);

2.2 更新

更新 也是用的是万能的 splice 方法 w3c splice 方法的解释

var arry = [1,2,3];
console.log(arry.splice(1,1,0));
console.log(arry);

2.3 查询

2.3.1 indexOf 和 lastIndexOf 方法

indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。

参考:indexOf

同样还有lastIndexOf方法

var fruits=["Banana","Orange","Apple","Mango","Banana","Orange","Apple"];
var a = fruits.indexOf("Apple",4);
console.log(a);//6

2.4 for 迭代方法

参考:《JavaScript权威指南》《JavaScript高级程序设计》

遍历有两大问题(当前水平),

1.性能

2.JavaScript 遍历中length特殊,可能是稀疏数组

var arg = [1,2,3];
for(var i=0;i<arg.length;i++){
//i<arg.length,每一次遍历都查询一次,所以需要优化
  console.log(arg[i]);
}
/***********优化后********/
for(var i=0,len=arg.length; i<len; i++){
  console.log(arg[i]);
}
/*
 * 上例,假设数组是稠密的,且所有的元素都是合法的。
 * 否则,在使用前应该先检测他们
 */
var arg = [1,2,3];
arg[4} = undefined;
arg.length = 10;//此处 特殊处理一下
for(var i=0,len=arg.length; i<len; i++){
  if(!arg[i]){//跳过null,undefined,不存在
  //if(arg[i] === undefined){//跳过undefined,不存在
  // if(!(i in arg)){//跳过不存在(如果 属性设置为undefined,in 返回true)
    continue;
  }
  console.log(arg[i]);
}
2.4.2 对稀疏数组处理(使用for/in循环)
2.4.2.1 基本方法
/*
 * 对稀疏数组处理
 * 使用for/in循环
 */
 //基本方法
var arg = [0,1];
arg[3] = 3;
arg[5] = 5;
for(var index in arg){
  console.log(arg[index]);
}
/**控制台打印
0
VM594:5 1
VM594:5 3
VM594:5 5
*/

与上面代码输出对比:

var arg = [0,1];
arg[3] = 3;
arg[5] = 5;
for(var i=0; i<arg.length; i++){
  console.log(arg[i]);
}
/** 控制台打印
0
VM595:5 1
VM595:5 undefined
VM595:5 3
VM595:5 undefined
VM595:5 5
*/
2.4.2.2 优化完善

for/in 循环 能够枚举继承的属性,如添加在Array.prototype的方法/属性,

因此,需要校验属性,过滤继承来的属性

可能出现的特殊情况:

//可能出现的特殊情况
var arg = [0,1];
arg[3] = 3;
arg[5] = 5;
arg.a = ‘a‘;//添加非数字属性
Array.prototype.proto = ‘proto‘;//添加继承 属性
for(var index in arg){
  console.log(arg[index]);
}
/**
0
VM604:7 1
VM604:7 3
VM604:7 5
VM604:7 a
VM604:7 proto
*/

解决上面可能出现的特殊情况:

var arg = [0,1];
arg[3] = 3;
arg[5] = 5;
arg.a = ‘a‘;//添加非数字属性
Array.prototype.proto = ‘proto‘;//添加继承 属性
for(var index in arg){
  //跳过继承属性
  if(!arg.hasOwnProperty(index)){ continue;}
  //跳过 非负整数的 index
  if(String(Math.abs(Number(index))) !== index){ continue;}//注意 for/in  返回的index 值为string
  console.log(arg[index]);
  //console.log(typeof(index));
}
/**
 * String(Math.abs(Number(index))) !== index 需要细细研究
 Number(index) 将 如‘1‘,‘2‘这种数字型 string转化为nmber,如非 数字型 string 则返回为 ‘NaN’
 for/in  返回的index 是String类型
*/

for/in 遍历数组顺序无法保证

ECMAAScript容许以不同顺序遍历,但一般具体浏览器的实现是升序,但有特列:

数组元素 拥有1对象属性 2.数组元素 参考下面代码:

var arg = [0,1];
arg[‘b‘] = ‘b‘;
arg[3] = 3;
arg[5] = 5;
arg.a = ‘a‘;//添加非数字属性
arg[4] = 4;//注意顺序
Array.prototype.proto = ‘proto‘;//添加继承 属性
for(var index in arg){
  console.log(arg[index]);
}
/** chrome 浏览器 控制台输出
VM431:9 0
VM431:9 1
VM431:9 3
VM431:9 4
VM431:9 5
VM431:9 b
VM431:9 a
VM431:9 proto
*/
2.4.3 ECMAAScript5 中数组的方法

ECMAAScript5 中定义了9个新数组方法(待后期)

3.常用方法

ECMAScript3在Array.prototype定义了一些操作数组的函数

3.1 join()

将所有的元素转换为字符串 并连接在一起,可以指定一个连接符

var arg = [0,1,5,6,10,15];
console.log(arg.join());//0,1,5,6,10,15 默认为“,”
console.log(arg.join(‘-‘));//0-1-5-6-10-15

该方法是String.split方法 的逆向过程

3.2 concat()

创建一个并返回一个新数组

可以理解为 连接个数组,并返回一个副本(也就是新数组)

w3c concat方法,讲的很清楚

var arg = [1,2,3];
//注意 可以是具体的值,也可以是数组
console.log(arg.concat(4,5));//[1, 2, 3, 4, 5]
console.log(arg);//[1, 2, 3]
console.log(arg.concat([4,5]));//[1, 2, 3, 4, 5]
console.log(arg);//[1, 2, 3]

3.3 slice()

方法可从已有的数组中返回选定的元素。

var arr = new Array(6)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
arr[3] = "James"
arr[4] = "Adrew"
arr[5] = "Martin"

console.log(arr.slice(2,4))
console.log(arr)
/** 控制台打印
VM2235:9 ["Thomas", "James"]
VM2235:10 ["George", "John", "Thomas", "James", "Adrew", "Martin"]
*/

3.4 toString 和 toLocaleString()

toString 方法和无参数的join()方法返回的字符串是一致的

w3c

4.数组排序方法

数组中有两个默认排序的方法

reverse()和sort();

但是,默认排序规则是,按照比较字母顺序来排序

下面 证明是按照字母顺序排序:

var arg = [0,1,5,10,15];
console.log(arg.sort());
//VM144:2 [0, 1, 10, 15, 5] 控制台打印

解决方案:

sort()方法接受一个function,该function 接受两个参数,

第一个 在第二个之前 return 负数,

如果相等 则返回为0

第一个 在第二个之后 return 正数,

var arg = [0,1,5,6,10,15];
console.log(arg.sort(function(v1,v2){
  return v2-v1;
}));
//[15, 10, 6, 5, 1, 0] 控制台打印

5.多维数组

JavaScript不支持正真的多为数组,因为数组本身就是一个对象,且数组的属性也可以为引用类型,所以,可以用数组的数组进行模拟多维数组。

下面实现一个9*9乘法口诀,来感受一下其中美妙

var table = new Array(10);
for(var i=1,len=table.length;i<len;i++){
  table[i] = new Array(10);
}
for(var i=1,len=table.length;i<len;i++){
  for(var j=1,len2=table[i].length;j<len2;j++){
    table[i][j] = i*j;
  }
}
console.log(table);
table[6][8];  //48

6.附录

var a = {
  a:‘aaa‘
}
debugger;
var arr = Array.prototype.slice.call(a,0);
console.log(Array.isArray(arr));//true 返回也是true,证明object被强转为Array,
//但属性“a”,被干掉,证明 只获得属性为number的
时间: 2024-11-08 22:52:13

JavaScript数组之概论的相关文章

javascript 数组的深度复制

javascript 数组的深度复制 一般情况下,使用 "=" 可以实现赋值.但对于数组.对象.函数等这些引用类型的数据,这个符号就不好使了. 1. 数组的简单复制 1.1 简单遍历 最简单也最基础的方式,自然是循环处理.示例: function array_copy(arr) { var out = [], i, len; if (out[i] instanceof Array === false){ return arr; } for (i = 0, len = arr.lengt

[前端JS学习笔记]JavaScript 数组

一.JavaScript数组的奇葩 大多数语言会要求数组的元素是同个类型, 但是JavaScript允许数组元素为多种类型. var arr = ["羽毛球", 666, {"json:":"666"}]; console.log(arr.length); 二.JavaScript 数组的两种声明 1.var arr = [元素]; var arr = ["坚持"]; 2.new Array(); 或者 var arr2 =

JavaScript 数组去重

JavaScript 数组去重 Why underscore (觉得这部分眼熟的可以直接跳到下一段了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. 阅读一些著名框架类库的源码,就好像和一个个大师对话,你会学到很多.为什么是 underscore?最主要的原因是 underscore 简短精悍(约 1.5k 行),封装了 100 多个有用的方法,耦合度低,非常适合逐个方法阅读,适合楼主这样的 JavaScript

javascript数组去重算法-----4(另一种写法)

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>javascript数组去重算法-----3</title> 6 </head> 7 <body> 8 <script> 9 var arr = [1,1,2,2,3,2,2,3,3,1,1,4,4,5

JQuery $.each遍历JavaScript数组对象实例

查看一个简单的jQuery的例子来遍历一个JavaScript数组对象. var json = [ {"id":"1","tagName":"apple"}, {"id":"2","tagName":"orange"}, {"id":"3","tagName":"banana&q

JavaScript数组方法对比(深度学习数组)

JavaScript数组方法对比 众所周知,JavaScript提供了许多对数组进行改变的方法,但是有些会对原数组进行影响,有些不会.下边就列举出来. 一.新增 影响原数组 array.push()  //向数组的末尾添加一个或更多元素,并返回新的长度. var array =[1,2,3,4,5]; array.push(6); // [1,2,3,4,5,6]; array.unshift() //向数组的开头添加一个或更多元素,并返回新的长度. var array =[1,2,3,4,5]

javascript数组顺序-----1冒泡的另一种比较好理解的写法

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>javascript数组冒泡排序法</title> 6 </head> 7 <body> 8 <script> 9 var array = [7, 9, 22, 11, 12, 13, 5, 4, 3,

javascript数组去重算法-----4(另一种写法__2)

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>javascript数组去重算法-----3</title> 6 </head> 7 <body> 8 <script> 9 var arr = [1,1,2,2,3,2,2,3,3,1,1,4,4,5

javascript数组去重算法-----5

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>javascript数组去重算法-----3</title> 6 </head> 7 <body> 8 <script> 9 var arr = [1,1,2,2,3,2,2,3,3,1,1,4,4,5