javascript权威指南-数组
作者:gcbeen
日期:2013年10月24日
一、Javascript数组
Javascript数组是无类型的:数组元素可以是任意类型,同一个数组中的不同元素可能有不同的类型,数组的元素可能是对象或其他数组。数组的实现是经过优化的,用数字索引来访问数组一般来说比访问常规对象属性要快很多。
数组继承自Array.prototype中的属性。
二、创建数组
数组直接量。
var empty = [];
var primes = [2, 3, 5, 7, 11];
var misc = [1.1, true, "a", ];
var base = 1024;
var table = [base, base + 1, base + 2, base + 3];
var b = [[1, {x: 1, y: 2}], [2, {x: 3, y: 4}]];
var count = [1, ,3];
var undefs = [,,] // 2个undefined元素
调用构造函数Array()创建数组。
var a = new Array();
var a = new Array(10);
var a = new Array(5, 4, 3, 2, 1, "testing, testing");
三、数组元素的读和写
var a = ["world"];
var value = a[0];
a[1] = 3.14;
i = 2;
a[i] = 3;
a[i + 1] = "hello";
a[a[i]] = a[0];
数组是对象的特殊形式。使用方括号访问数组元素就像用方括号访问对象的属性一样。Javascript将指定的数字索引值转换成字符串(索引值1变成“1”)然后将其作为属性名来使用。
索引值从数字转换为字符串,常规对象也会这么做。
var o = {};
o[1] = "one";
a[-1.23] = true; //这将创建一个名为“-1.23”的属性
a["1000"] = 0; //数组的第1001个元素
a[1.000] //和a[1]相等
数组索引仅仅是对象属性名的一种特殊类型,Javascript数组没有“越界”错误的概念。当试图查询任何对象中不存在的属性时,不会报错,只会得到undefined值。类似于对象。
四、稀疏数组
稀疏数组是包含从0开始不连续索引的数组。通常,数组的length属性值代表数组中元素的个数。如果数组是稀疏的,length属性值大于元素的个数。
var a = new Array(5);
var a = [];
a[1000] = 0;
当在数组直接量中省略值时不会创建稀疏数组。省略的元素是undefined。
var a1 = [,,,];
var a2 = new Array(3);
0 in a1 // true
0 in a2 // false
var a1 = [,];
var a2 = [undefined];
0 in a1;
0 in a2;
五、数组长度
length属性代表元素的个数或者最大索引值加1。
[].length;
['a', 'b', 'c'].length;
a = [1, 2, 3, 4, 5];
a.length = 3;
a.length = 0;
a.length = 5;
a = [1, 2, 3];
Object.defineProperty(a, "length", {writable: false});
a.length = 0; // a不会改变
六、数组元素的添加和删除
var a = [];
a[0] = "zero";
a[1] = "one";
var a = [];
a.push("zero");
a.push("one", "two"); // ["zero", "one", "two"]
a.unshift("-one"); // ["-one", "zero", "one", "two"]
var a = [1, 2, 3];
delete a[1];
1 in a // false:数组索引1并未在数组中定义
a.length // 3:delete操作不影响数组长度
var a = [1, 2, 3]
a.push(4);
a.pop(); // 4
a.unshift(-1);
a.shift(); // -1
a.splice();
七、数组遍历
for循环
var keys = Object.keys(o); // 获得o对象属性名组成的数组
var values = [];
var i,
len = keys.length;
for (i = 0; i < len; i += 1) {
if (!a[i]) {
continue;
}
var key = keys[i];
values[i] = o[key];
}
for/in循环处理稀疏数组
var index,
value;
for (index in sparseArray) {
if (!a.hasOwnProperty(i) ) {
continue;
}
value = sparseArray[index]
}
for (index in sparseArray) {
if (String(Math.floor(Math.abs(Number(i) ) ) ) === i ) {
// coding
}
}
for/in循环以不同的顺序遍历对象的属性。通常数组元素的遍历实现是升序的,但不能保证一定是这样。如果数组同时拥有对象属性和数组元素,返回的属性名很可能是按照创建的顺序而非数值大小顺序。
var data = [1, 2, 3, 4, 5];
var sumOfSquares = 0;
data.forEach(function (x) {
sumOfSquares += x * x;
});
sumOfSquares;
八、多维数组
var table = new Array(10);
var i,
tableLen = talbe.length,
row,
rowLen,
col;
for (i = 0; i < table.length; i += 1) {
table[i] = new Array(10);
}
for (row = 0; row < tableLen; row += 1) {
for (col = 0, rowLen = table[row].length; col < rowLen; col += 1) {
table[row][col] = row * col;
}
}
var product = table[5][7];
九、数组方法
//Array.join()方法是String.split()方法的逆向操作
var a = [1, 2, 3];
a.join();
a.join(" ");
a.join("");
var b = new Array(10);
b.join('-');
//Array.reverse()
var a = [1, 2, 3];
a.reverse().join() // "3,2,1"; a: [3, 2, 1]
//Array.sort()
var a = new Array("banana", "cherry", "apple");
a.sort();
var s = a.join(', '); // "apple banana cherry"
var a = [33, 4, 1111, 222];
a.sort();
a.sort(function (a, b) {
return a - b;
});
a.sort(function (a, b) {
return b -a;
});
a = ['ant', 'Bug', 'cat', 'Dog'];
a.sort();
a.sort(function (s, t) {
var a = s.toLowerCase(),
b = t.toLowerCase();
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
//Array.concat
var a = [1, 2, 3];
a.concat(4, 5);
a.concat([4, 5]);
a.concat([4, 5], [6, 7]);
a.concat(4, [5, [6, 7] ]);
//Array.slice()
var a = [1, 2, 3, 4, 5];
a.slice(0, 3); // 返回[1, 2, 3]
a.slice(3); // 返回[4, 5]
a.slice(1, -1); // 返回[2, 3, 4]
a.slice(-3, -2); // 返回[3]
//Array.splice():数组插入或删除元素的通用方法。
var a = [1, 2, 3, 4, 5, 6, 7, 8];
a.splice(4); // 返回[5, 6, 7, 8];a 是[1, 2, 3, 4]
a.splice(1, 2); // 返回[2, 3]; a 是[1, 4]
a.splice(1, 1); // 返回[4];a 是[1]
a.splice(0, 1); // 返回[1]; a 是[]
a.splice(0, 1); // 返回[]; a 是[]
// Array.push() Array.pop()
var stack = []; // stack:[]
stack.push(1, 2); // stack:[1, 2] 返回 2
stack.pop(); // stack:[1] 返回 2
stack.push(3); // stack: [1, 3] 返回 2
stack.pop(); // stack:[1] 返回 3
stack.push([4, 5]); // stack:[1, [4, 5]] 返回 2
stack.pop(); // stack:[1] 返回 [4, 5]
stack.pop(); // stack:[] 返回 1
// Array.unshift() Array.shift()
var a = []; // a:[]
a.unshift(1); // a:[1] 返回:1
a.unshift(22); // a:[22, 1] 返回:2
a.shift(); // a:[1] 返回:22
a.unshift(3, [4, 5]); // a:[3, [4, 5], 1] 返回:3
a.shift(); // a:[[4, 5], 1] 返回:3
a.shift(); // a:[1] 返回:[4, 5]
a.shift(); // a:[] 返回:1
//Array.toString()和Array.toLocaleString()
[1, 2, 3].toString(); // '1,2,3'
["a", "b", "c"].toString(); // 'a,b,c'
[1, [2, 'c'] ].toString(); // '1,2,c'
十、ECMAScript 5中的数组方法
// forEach()
var data = [1, 2, 3, 4, 5];
var sum = 0;
data.forEach(function (value) { sum += value; });
sum;
data.forEach(function (v, i, a) { a[i] = v + 1; } );
data;
function foreach(a, f, t) {
try {
a.forEach(f, t);
} catch (e) {
if () {
return;
} else {
throw e;
}
}
}
foreach.break = new Error("StopIteration");
// Array.map()
var a = [1, 2, 3];
b = a.map(function (x) {
return x * x;
});
// Array.filter()
var a = [5, 4, 3, 2, 1];
smallvalues = a.filter(function (x) {
return x < 3;
});
everyother = a.filter(function (x, i) {
return i % 2 == 0;
});
var dense = sparse.filter(functiin () {
return true;
});
a = a.filter(function (x) {
return x !== undefined && x != null;
});
// Array.every()
var a = [1, 2, 3, 4, 5];
a.every(function (x) {
return x < 10;
});
a.every(function (x) {
return x % 2 === 0;
});
// Array.some()
var a = [1, 2, 3, 4, 5];
a.some(function (x) {
return x % 2 === 0;
});
a.some(isNaN);
// Array.reduce()
var a = [1, 2, 3, 4, 5];
var sum = a.reduce(function (x, y) {
return x + y
}, 0);
var product = a.reduce(function (x, y) {
return x * y;
}, 1);
var max = a.reduce(function (x, y) {
return x > y ? x : y
});
//Array.reduceRight()
var a = [2, 3, 4];
var big = a.reduceRight(function (accumulator, value) {
return Math.pow(value, accumulator);
});
// Array.reduceRight()
function union(o, p) {
return extend(extend({}, o), p);
}
var objects = [{x: 1}, {y: 2}, {z: 3}];
var merged = objects.reduce(union); // {x: 1, y: 2, z: 3}
var objects = [{x: 1, a: 1}, {y: 2, a: 2}, {z: 3, a: 3}];
var leftunion = objects.reduce(union); // {x: 1, y: 2, z: 3, a: 1}
var rightunion = objects.reduceRight(union); // {x: 1, y: 2, z: 3, a: 3}
var a = [0, 1, 2, 1, 0];
a.indexOf(1); // 1
a.lastIndexf(1); // 3
a.indexOf(3); // -1 没有值为3的元素
function findall(a, x) {
var results = [],
len = a.length,
pos = 0;
while (pos < len) {
pos = a.indexOf(x, pos);
if (pos === -1) {
break;
}
results.push(pos);
pos = pos + 1;
}
}
十一、数组类型
Array.isArray([]); // true
Array.isArray({}); // false
[] instanceof Array // true
({}) instanceof Array // false
//当多窗口或窗体存在时 instanceof操作符检测无效
var isArray = Function.isArray || function (o) {
return typeof o === "object" && Object.prototype.toString.call(o) === "[object Array]";
};
十二、类数组对象
数组的特性。
- 当有新的元素添加到列表中时,自动更新length属性。
- 设置length为一个较小值将截断数组。
- 从Array.prototype中继承一些有用的方法。
- 其类属性为“Array”。
这些特性让Javascript数组和常规对象有明显的区别。但是它们不是定义数组的本质特性。一种常常完全合理的看法把拥有一个数值length属性和对应非负整数属性的对象看作一种类型的数组(类数组)。
var a = {};
var i = 0;
while (i < 10) {
a[i] = i * i;
i += 1;
}
a.length = i;
var total = 0,
j;
for (j = 0; j < a.length; j += 1) {
total += a[j];
}
function isArrayLike(o) {
if (o && typeof o === "object" && isFinite(o.length) && o.length >= 0 && o.length === Math.floor(o.length) && o.length < 4294967296 ) {
return true;
} else {
return false;
}
}
var a = {"0": "a", "1": "b", "2": "c", length: 3};
Array.prototype.join.call(a, "+");
Array.prototype.slice.call(a, 0);
Array.prototype.map.call(a, function () {
return x.toUpperCase();
});
Array.join = Array.join || function (a, sep) {
return Array.prototype.slice.call(a, from, to);
};
Array.slice = Array.slice || function (a, from, to) {
return Array.prototype.slice.call(a, from, to);
};
Array.map = Array.map || function (a, f, thisArg) {
return Array.prototype.map.call(a, f, thisArg);
};
十三、作为数组的字符串
var s = "test";
s.chartAt(0);
s[1];
var s = "JavaScript";
Array.prototype.join.call(s, " ");
Array.prototype.filter.call(s, function (x) {
return x.match(/[^aeiou]/);
}).join("");
字符串是不可变值,故当他们作为数组看待时,它们是只读的。如push(), sort(), reverse(), splice() 等数组方法会修改数组,它们在字符串上是无效的。不仅如此,使用数组方法修改字符串会导致错误:出错的时候没有提示。
blog comments powered by Disqus