Skip to main content

数字和数组

数据表示

书写 JavaScript 数值既可以带小数点,也可以不带:

var x = 3.14;    // 带小数点的数值
var y = 3; // 不带小数点的数值

超大或超小的数可通过科学计数法来写:

var x = 123e5;    // 12300000
var y = 123e-5; // 0.00123

不合法数 NaN

NaN 属于 JavaScript 保留词,指示某个数不是合法数。
尝试用一个非数字字符串进行除法会得到 NaN(Not a Number):

var x = 100 / "Apple";  // x 将是 NaN(Not a Number)

不过,假如字符串包含数值,则结果将是数:

var x = 100 / "10";     // x 将是 10

您可使用全局 JavaScript 函数 isNaN() 来确定某个值是否是数:

var x = 100 / "Apple";
isNaN(x); // 返回 true,因为 x 不是数

Infinity

Infinity (或 -Infinity)是 JavaScript 在计算数时超出最大可能数范围时返回的值。

var myNumber = 2;

while (myNumber != Infinity) { // 执行直到 Infinity
myNumber = myNumber * myNumber;
}

当除以 0(零)也会生成 Infinity

var x =  2 / 0;          // x 将是 Infinity
var y = -2 / 0; // y 将是 -Infinity

Infinity 是数:typeOf Infinity 返回 number。

typeof Infinity;        // 返回 "number"

数字属性

toString

toString() 以字符串返回数值。

所有数字方法可用于任意类型的数字(字面量、变量或表达式):

var x = 123;
x.toString(); // 从变量 x 返回 123
(123).toString(); // 从文本 123 返回 123
(100 + 23).toString(); // 从表达式 100 + 23 返回 123

toExponential

toExponential() 返回字符串值,它包含已被四舍五入并使用指数计数法的数字。

参数定义小数点后的字符数:

var x = 9.656;
x.toExponential(2); // 返回 9.66e+0
x.toExponential(4); // 返回 9.6560e+0
x.toExponential(6); // 返回 9.656000e+0

toFixed

toFixed() 返回字符串值,它包含了指定位数小数的数字:

var x = 9.656;
x.toFixed(0); // 返回 10
x.toFixed(2); // 返回 9.66
x.toFixed(4); // 返回 9.6560
x.toFixed(6); // 返回 9.656000

toFixed(2) 非常适合处理金钱

toPrecision

toPrecision() 返回字符串值,它包含了指定长度的数字:

var x = 9.656;
x.toPrecision(); // 返回 9.656
x.toPrecision(2); // 返回 9.7
x.toPrecision(4); // 返回 9.656
x.toPrecision(6); // 返回 9.65600

valueOf

valueOf() 以数值返回数值:

var x = 123;
x.valueOf(); // 从变量 x 返回 123
(123).valueOf(); // 从文本 123 返回 123
(100 + 23).valueOf(); // 从表达式 100 + 23 返回 123

parseInt

parseInt() 解析一段字符串并返回数值。允许空格。只返回首个数字:

parseInt("10");         // 返回 10
parseInt("10.33"); // 返回 10
parseInt("10 20 30"); // 返回 10
parseInt("10 years"); // 返回 10
parseInt("years 10"); // 返回 NaN

parseFloat

parseFloat() 解析一段字符串并返回数值。允许空格。只返回首个数字:

parseFloat("10");        // 返回 10
parseFloat("10.33"); // 返回 10.33
parseFloat("10 20 30"); // 返回 10
parseFloat("10 years"); // 返回 10
parseFloat("years 10"); // 返回 NaN

MIN_VALUE 和 MAX_VALUE

MAX_VALUE 返回 JavaScript 中可能的最大数字。

var x = Number.MAX_VALUE;

MIN_VALUE 返回 JavaScript 中可能的最小数字。

var x = Number.MIN_VALUE;

数组

JavaScript 数组用于在单一变量中存储多个值。

var cars = ["Saab", "Volvo", "BMW"];

创建数组

使用数组文本是创建 JavaScript 数组最简单的方法。

var array-name = [item1, item2, ...];

空格和折行并不重要。声明可横跨多行:

var cars = [
"Saab",
"Volvo",
"BMW"
];

可以使用 new 关键字声明:

var cars = new Array("Saab", "Volvo", "BMW");

但是,还是避免使用 Array 属性:

var points = new Array(40, 100, 1, 5, 25, 10); // 差
var points = [40, 100, 1, 5, 25, 10]; // 优

访问数组元素

我们通过引用索引号(下标号)来引用某个数组元素。

这条语句访问 cars 中的首个元素的值:

var name = cars[0];

这条语句修改 cars 中的首个元素:

cars[0] = "Opel";

应用实例:

var cars = ["Saab", "Volvo", "BMW"];
document.getElementById("demo").innerHTML = cars[0];

访问完整数组

通过 JavaScript,可通过引用数组名来访问完整数组:

var cars = ["Saab", "Volvo", "BMW"];
document.getElementById("demo").innerHTML = cars;

数组是对象

数组是一种特殊类型的对象。在 JavaScript 中对数组使用 typeof 运算符会返回 "object"。

但是,JavaScript 数组最好以数组来描述。

数组使用数字来访问其“元素”。在本例中,person[0] 返回 Bill:

var person = ["Bill", "Gates", 62];

对象使用名称来访问其“成员”。在本例中,person.firstName 返回 Bill:

var person = {firstName:"Bill", lastName:"Gates", age:19};

数组元素可以是对象

JavaScript 变量可以是对象。数组是特殊类型的对象。

正因如此,您可以在相同数组中存放不同类型的变量。

您可以在数组保存对象。您可以在数组中保存函数。你甚至可以在数组中保存数组:

myArray[0] = Date.now;
myArray[1] = myFunction;
myArray[2] = myCars;

数组属性和方法

length

length 属性返回数组的长度(数组元素的数目)。

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.length; // fruits 的长度是 4

访问第一个元素

fruits = ["Banana", "Orange", "Apple", "Mango"];
var first = fruits[0];

访问最后一个数组元素

fruits = ["Banana", "Orange", "Apple", "Mango"];
var last = fruits[fruits.length - 1];

遍历数组元素

遍历数组的最安全方法是使用 "for" 循环:

var fruits, text, fLen, i;

fruits = ["Banana", "Orange", "Apple", "Mango"];
fLen = fruits.length;
text = "<ul>";
for (i = 0; i < fLen; i++) {
text += "<li>" + fruits[i] + "</li>";
}

您也可以使用 Array.foreach() 函数:

var fruits, text;
fruits = ["Banana", "Orange", "Apple", "Mango"];

text = "<ul>";
fruits.forEach(myFunction);
text += "</ul>";

function myFunction(value) {
text += "<li>" + value + "</li>";
}

添加数组元素

向数组添加新元素的最佳方法是使用 push() 方法:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Lemon"); // 向 fruits 添加一个新元素 (Lemon)

也可以使用 length 属性向数组添加新元素:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[fruits.length] = "Lemon"; // 向 fruits 添加一个新元素 (Lemon)

数组方法

元素删除 Popping

pop() 方法从数组中删除最后一个元素

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.pop(); // 从 fruits 删除最后一个元素("Mango")

pop() 方法返回“被弹出”的值:

实例

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x = fruits.pop(); // x 的值是 "Mango"

元素添加 Pushing

push() 方法(在数组结尾处)向数组添加一个新的元素:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Kiwi"); // 向 fruits 添加一个新元素

push() 方法返回新数组的长度:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x = fruits.push("Kiwi"); // x 的值是 5

删除首个元素

位移与弹出等同,但处理首个元素而不是最后一个

shift() 方法会删除首个数组元素,并把所有其他元素“位移”到更低的索引。

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.shift(); // 从 fruits 删除第一个元素 "Banana" 并 返回 "Banana"

在首部添加元素

unshift() 方法(在开头)向数组添加新元素,并“反向位移”旧元素,返回新的数组长度:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.unshift("Lemon"); // 向 fruits 添加新元素 "Lemon" 返回 5

更改元素

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[0] = "Kiwi"; // 把 fruits 的第一个元素改为 "Kiwi"

删除元素

既然 JavaScript 数组属于对象,其中的元素就可以使用 JavaScript delete 运算符来删除:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
delete fruits[0]; // 把 fruits 中的首个元素改为 undefined

使用 delete 会在数组留下未定义的空洞。请使用 pop()shift() 取而代之。

拼接数组

splice() 方法可用于向数组添加新项:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2, 0, "Lemon", "Kiwi");

第一个参数(2)定义了应添加新元素的位置(拼接)。

第二个参数(0)定义应删除多少元素。

其余参数(“Lemon”,“Kiwi”)定义要添加的新元素。

splice() 方法返回一个包含已删除项的数组:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2, 2, "Lemon", "Kiwi");

合并(连接)数组

concat() 方法通过合并(连接)现有数组来创建一个新数组:

var myGirls = ["Cecilie", "Lone"];
var myBoys = ["Emil", "Tobias", "Linus"];
var myChildren = myGirls.concat(myBoys); // 连接 myGirls 和 myBoys

concat() 方法不会更改现有数组。它总是返回一个新数组。

concat() 方法可以使用任意数量的数组参数:

var arr1 = ["Cecilie", "Lone"];
var arr2 = ["Emil", "Tobias", "Linus"];
var arr3 = ["Robin", "Morgan"];
var myChildren = arr1.concat(arr2, arr3); // 将arr1、arr2 与 arr3 连接在一起

裁剪数组

slice() 方法用数组的某个片段切出新数组。

本例从数组元素 1 ("Orange")开始切出一段数组:

var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1);

结果:

Orange,Lemon,Apple,Mango

slice() 可接受两个参数,比如 (1, 3)。

该方法会从开始参数选取元素,直到结束参数(不包括)为止。

var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1, 3);

数组操作

数组排序

sort() 方法是最强大的数组方法之一。 sort() 方法以字母顺序对数组进行排序:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort(); // 对 fruits 中的元素进行排序

反转数组

reverse() 方法反转数组中的元素。

您可以使用它以降序对数组进行排序:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort(); // 对 fruits 中的元素进行排序
fruits.reverse(); // 反转元素顺序

数字排序

默认地,sort() 函数按照字符串顺序对值进行排序。 该函数很适合字符串("Apple" 会排在 "Banana" 之前)。 不过,如果数字按照字符串来排序,则 "25" 大于 "100",因为 "2" 大于 "1"。 正因如此,sort() 方法在对数值排序时会产生不正确的结果。 我们通过一个比值函数来修正此问题:

var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b});

使用相同的技巧对数组进行降序排序:

var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return b - a});

比值函数

比较函数的目的是定义另一种排序顺序。

比较函数应该返回一个负,零或正值,这取决于参数:

function(a, b){return a-b}

sort() 函数比较两个值时,会将值发送到比较函数,并根据所返回的值(负、零或正值)对这些值进行排序。

实例

当比较 40 和 100 时,sort() 方法会调用比较函数 function(40,100)。 该函数计算 40-100,然后返回 -60(负值)。 排序函数将把 40 排序为比 100 更低的值。 您可以使用下面的代码片段来测试数值和字母排序:

<button onclick="myFunction1()">以字母顺序排序</button>
<button onclick="myFunction2()">以数字顺序排序</button>

<p id="demo"></p>

<script>
var points = [40, 100, 1, 5, 25, 10];
document.getElementById("demo").innerHTML = points;

function myFunction1() {
points.sort();
document.getElementById("demo").innerHTML = points;
}
function myFunction2() {
points.sort(function(a, b){return a - b});
document.getElementById("demo").innerHTML = points;
}
</script>

以随机顺序排序数组

var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return 0.5 - Math.random()});

排序对象数组

var cars = [
{type:"Volvo", year:2016},
{type:"Saab", year:2001},
{type:"BMW", year:2010}];

我们需要对上面的年份进行排序:

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

比较字符串属性,先将其转化为小写字母:

cars.sort(function(a, b){
var x = a.type.toLowerCase();
var y = b.type.toLowerCase();
if (x < y) {return -1;}
if (x > y) {return 1;}
return 0;
});

数组迭代

Array.forEach()

forEach() 方法为每个数组元素调用一次函数(回调函数)。

var txt = "";
var numbers = [45, 4, 9, 16, 25];
numbers.forEach(myFunction);

function myFunction(value, index, array) {
txt = txt + value + "<br>";
}

txt 作为一个空字符串,实际上没有作用,只是为了让结果也成为字符串,本段代码实现了列表渲染的效果:

// 结果
45
4
9
16
25

注释:该函数接受 3 个参数:

  • 项目值
  • 项目索引
  • 数组本身

上面的例子只用了 value 参数。这个例子可以重新写为:

var txt = "";
var numbers = [45, 4, 9, 16, 25];
numbers.forEach(myFunction);

function myFunction(value) {
txt = txt + value + "<br>";
}

Array.map()

map() 方法通过对每个数组元素执行函数来创建新数组。

map() 方法不会对没有值的数组元素执行函数。

map() 方法不会更改原始数组。

这个例子将每个数组值乘以2:

var numbers1 = [45, 4, 9, 16, 25];
var numbers2 = numbers1.map(myFunction);

function myFunction(value, index, array) {
return value * 2;
}

// 可以省略为一个参数
function myFunction(value) {
return value * 2;
}
<!DOCTYPE html>
<html>
<body>

<h1>JavaScript Array.map()</h1>

<p>通过对每个数组元素执行函数来创建新数组。</p>

<p id="demo"></p>

<script>
var numbers1 = [45, 4, 9, 16, 25];
var numbers2 = numbers1.map(myFunction);

document.getElementById("demo").innerHTML = numbers2;

function myFunction(value, index, array) {
return value * 2;
}
</script>

</body>
</html>

经历上述代码之后,会创建一个每个元素都是原来二倍的数组。

90,8,18,32,50

Array.filter()

Array.filter() 是一个过滤器。 filter() 方法创建一个包含通过测试的数组元素的新数组。 这个例子用值大于 18 的元素创建一个新数组:

var numbers = [45, 4, 9, 16, 25];
var over18 = numbers.filter(myFunction);

function myFunction(value, index, array) {
return value > 18;
}

请注意此函数接受 3 个参数:

  • 项目值
  • 项目索引
  • 数组本身 在上面的例子中,回调函数不使用 index 和 array 参数,因此可以省略它们:
var numbers = [45, 4, 9, 16, 25];
var over18 = numbers.filter(myFunction);

function myFunction(value) {
return value > 18;
}

Array.reduce()

reduce() 方法在每个数组元素上运行函数,以生成(减少它)单个值。

reduce() 方法在数组中从左到右工作。另请参阅 reduceRight()。

reduce() 方法不会减少原始数组。

这个例子确定数组中所有数字的总和:

var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduce(myFunction);

function myFunction(total, value, index, array) {
return total + value;
}
完整代码
<!DOCTYPE html>
<html>
<body>

<h1>JavaScript Array.reduce()</h1>

<p>此例确定数组中所有数字的总和:</p>

<p id="demo"></p>

<script>
var numbers = [45, 4, 9, 16, 25];
var sum = numbers.reduce(myFunction);

document.getElementById("demo").innerHTML = "总和是:" + sum;

function myFunction(total, value, index, array) {
return total + value;
}
</script>

</body>
</html>

结果:

总和是:99

请注意此函数接受 4 个参数:

  • 总数(初始值/先前返回的值)
  • 项目值
  • 项目索引
  • 数组本身 上例并未使用 index 和 array 参数。可以将它改写为:
var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduce(myFunction);

function myFunction(total, value) {
return total + value;
}

reduce() 方法能够接受一个初始值:

var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduce(myFunction, 100);

function myFunction(total, value) {
return total + value;
}
<!DOCTYPE html>
<html>
<body>

<h1>JavaScript Array.reduce()</h1>

<p>此例确定数组中所有数字的总和:</p>

<p id="demo"></p>

<script>
var numbers = [45, 4, 9, 16, 25];
var sum = numbers.reduce(myFunction, 100);

document.getElementById("demo").innerHTML = "总和是:" + sum;

function myFunction(total, value) {
return total + value;
}
</script>

</body>
</html>

因为它已经携带了一个初始值,所以结果是 初始值 + 计算值 ,结果:

总和是:199

Array.reduceRight()

reduceRight() 方法在每个数组元素上运行函数,以生成(减少它)单个值。

reduceRight() 方法在数组中从右到左工作。另请参阅 reduce()。

reduceRight() 方法不会减少原始数组。

这个例子确定数组中所有数字的总和:

var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduceRight(myFunction);

function myFunction(total, value, index, array) {
return total + value;
}

请注意此函数接受 4 个参数:

  • 总数(初始值/先前返回的值)
  • 项目值
  • 项目索引
  • 数组本身 上例并未使用 index 和 array 参数。可以将它改写为:
var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduceRight(myFunction);

function myFunction(total, value) {
return total + value;
}

Array.every()

every() 方法检查所有数组值是否通过测试。

这个例子检查所有数组值是否大于 18:

var numbers = [45, 4, 9, 16, 25];
var allOver18 = numbers.every(myFunction);

function myFunction(value, index, array) {
return value > 18;
}

返回值:

false

请注意此函数接受 3 个参数:

  • 项目值
  • 项目索引
  • 数组本身 如果回调函数仅使用第一个参数(值)时,可以省略其他参数:
var numbers = [45, 4, 9, 16, 25];
var allOver18 = numbers.every(myFunction);

function myFunction(value) {
return value > 18;
}

Array.some()

some() 方法检查某些数组值是否通过了测试。

这个例子检查某些数组值是否大于 18:

var numbers = [45, 4, 9, 16, 25];
var someOver18 = numbers.some(myFunction);

function myFunction(value, index, array) {
return value > 18;
}

Array.find()

find() 方法返回通过测试函数的第一个数组元素的值。

这个例子查找(返回)大于 18 的第一个元素的值:

var numbers = [4, 9, 16, 25, 29];
var first = numbers.find(myFunction);

function myFunction(value, index, array) {
return value > 18;
}

返回值:

25

Array.findIndex()

findIndex() 方法返回通过测试函数的第一个数组元素的索引。

这个例子查找大于 18 的第一个元素的索引:

var numbers = [4, 9, 16, 25, 29];
var first = numbers.findIndex(myFunction);

function myFunction(value, index, array) {
return value > 18;
}

返回值:

3