JavaScript 基础
JavaScript 基础
函数
语法:
function name(参数 1, 参数 2, 参数 3) {
要执行的代码
}
例:
function myFunction(p1, p2) {
return p1 * p2; // 该函数返回 p1 和 p2 的乘积
}
函数调用
函数中的代码将在其他代码调用该函数时执行:
- 当事件发生时(当用户点击按钮时)
- 当 JavaScript 代码调用时
- 自动的(自调用)
函数返回
当 JavaScript 到达 return 语句,函数将停止执行。如果函数被某条语句调用,JavaScript 将在调用语句之后“返回”执行代码。
函数通常会计算出返回值。这个返回值会返回给调用者。
例:
var x = myFunction(7, 8); // 调用函数,返回值被赋值给 x
function myFunction(a, b) {
return a * b; // 函数返回 a 和 b 的乘积
}
// 运行后,x的值为 56
当然也可以通过函数更改HTML元素
例:把华氏度转换为摄氏度
<p id="demo"></p>
<script>
function toCelsius(f) {
return (5/9) * (f-32);
}
document.getElementById("demo").innerHTML = toCelsius(86);
</script>
<!--
结果:
30
-->
() 运算符调用函数
使用上面的例子,toCelsius 引用的是函数对象,而 toCelsius() 引用的是函数结果。
访问没有 () 的函数将返回函数定义:
<p id="demo"></p>
<script>
function toCelsius(f) {
return (5/9) * (f-32);
}
document.getElementById("demo").innerHTML = toCelsius;
</script>
<!--
结果:
function toCelsius(f) { return (5/9) * (f-32); }
-->
对象
JavaScript 变量是数据值的容器
值以名称:值对的方式来书写(名称和值由冒号分隔)。
JavaScript 对象是被命名值的容器。
这段代码把一个单一值(porsche)赋给名为 car 的变量
var car = "porsche";
对象也是变量。但是对象包含很多值。
var car = {type:"porsche", model:"911", color:"white"};
对象定义
var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};
// 或
var person = {
firstName:"Bill",
lastName:"Gates",
age:50,
eyeColor:"blue"
};
对象属性
(JavaScript 对象中的)名称:值对被称为属性。
var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};
| 属性 | 属性值 |
|---|---|
| firstName | Bill |
| lastName | Gates |
| age | 62 |
| eyeColor | blue |
对象方法
对象也可以有方法。
方法是在对象上执行的动作。
方法以函数定义被存储在属性中。
方法是作为属性来存储的函数。
var person = {
firstName: "Bill",
lastName : "Gates",
id : 678,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
| 属性 | 属性值 |
|---|---|
| firstName | Bill |
| lastName | Gates |
| age | 62 |
| eyeColor | blue |
| fullName | function() {return this.firstName + " " + this.lastName;} |
This
在函数定义中,this 引用该函数的“拥有者”。
在上面的例子中,this 指的是“拥有” fullName 函数的 person 对象。
换言之,this.firstName 的意思是 this 对象的 firstName 属性。
访问对象属性
objectName.propertyName
person.lastName;
// 或
objectName["propertyName"]
person["lastName"];
访问对象方法
objectName.methodName()
// 例:
name = person.fullName();
// 若不使用(),则返回函数定义
name = person.fullName;
注意
如果通过关键词 "new" 来声明 JavaScript 变量,则该变量会被创建为对象
请避免字符串、数值或逻辑对象。他们会增加代码的复杂性并降低执行速度。
var x = new String(); // 把 x 声明为 String 对象
var y = new Number(); // 把 y 声明为 Number 对象
var z = new Boolean(); // 把 z 声明为 Boolean 对象
事件
常见的HTML事件
| 事件 | 描述 |
|---|---|
| onchange | HTML 元素已被改变 |
| onclick | 用户点击了 HTML 元素 |
| onmouseover | 用户把鼠标移动到 HTML 元素上 |
| onmouseout | 用户把鼠标移开 HTML 元素 |
| onkeydown | 用户按下键盘按键 |
| onload | 浏览器已经完成页面加载 |
字符串
例:
var answer = "It's good to see you again!";
var answer = "He is called 'Bill'";
var answer = 'He is called "Bill"';
内建属性 length 可返回字符串的长度:
var txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var sln = txt.length;
转义符:\
| 代码 | 结果 | 描述 |
|---|---|---|
| ' | ' | 单引号 |
| " | " | 双引号 |
| \ | \ | 反斜杠 |
| 代码 | 结果 |
|---|---|
| \b | 退格键 |
| \f | 换页 |
| \n | 新行 |
| \r | 回车 |
| \t | 水平制表符 |
| \v | 垂直制表符 |
长代码行换行
如果某条 JavaScript 语句不适合一整行,那么最佳换行位置是某个运算符之后:
document.getElementById("text").innerHTML =
"Hello World!";
您也可以在字符串中换行,通过一个反斜杠即可:
document.getElementById("text").innerHTML = "Hello \
World!";
\ 方法并不是 ECMAScript (JavaScript) 标准。
某些浏览器也不允许 \ 字符之后的空格。
对长字符串换行的最安全做法(但是有点慢)是使用字符串加法:
document.getElementById("demo").innerHTML = "Hello" +
"Kitty!";
对象
JavaScript 字符串是原始值,通过字面方式创建:
var firstName = "Bill"
也可通过关键词 new 定义为对象(不建议):
var firstName = new String("Bill")
例
var x = "Bill";
var y = new String("Bill");
// typeof x 将返回 string
// typeof y 将返回 object
new 关键字使代码复杂化。也可能产生一些意想不到的结果:
当使用 == 相等运算符时,相等字符串是相等的;当使用 === 运算符时,相等字符串是不相等的,因为 === 运算符需要类型和值同时相等。
另外,JavaScript 对象无法进行对比,比较两个 JavaScript 将始终返回 false。
var x = new String("Bill");
var y = new String("Bill");
// (x === y) 为 false,因为 x 和 y 是不同的对象
常用方法
length 属性返回字符串的长度:
indexOf() 方法返回字符串中指定文本首次出现的索引(位置)(JavaScript 从零计算位置):
search() 方法搜索特定值的字符串,并返回匹配的位置:
注:indexOf() 与 search() 是不相等的
- search() 方法无法设置第二个开始位置参数。
- indexOf() 方法无法设置更强大的搜索值(正则表达式)。
提取部分字符串
- slice(start, end)
slice() 提取字符串的某个部分并在新字符串中返回被提取的部分。
该方法设置两个参数:起始索引(开始位置),终止索引(结束位置)。
var str = "Apple, Banana, Mango";
var res = str.slice(7,13);
// 结果:Banana
如果某个参数为负,则从字符串的结尾开始计数。
var str = "Apple, Banana, Mango";
var res = str.slice(-13,-7);
// 结果:Banana
如果省略第二个参数,则该方法将裁剪字符串的剩余部分:
var res = str.slice(7);
或者从结尾计数:
var res = str.slice(-13);
- substring(start, end)
substring() 类似于 slice()。
不同之处在于 substring() 无法接受负的索引。
- substr(start, length)
substr() 类似于 slice()。
不同之处在于第二个参数规定被提取部分的长度。
var str = "Apple, Banana, Mango";
var res = str.substr(7,6);
// 结果:Banana
如果省略第二个参数,则该 substr() 将裁剪字符串的剩余部分。
var str = "Apple, Banana, Mango";
var res = str.substr(7);
// 结果:Banana, Mango
如果首个参数为负,则从字符串的结尾计算位置。
var str = "Apple, Banana, Mango";
var res = str.substr(-5);
// 结果:Mango
替换字符串内容:replace()
replace() 方法用另一个值替换在字符串中指定的值:
str = "Please visit Microsoft!";
var n = str.replace("Microsoft", "W3School");
replace() 方法不会改变调用它的字符串。它返回的是新字符串。
默认地,replace() 只替换首个匹配,且对大小写敏感:
str = "Please visit Microsoft and Microsoft!";
var n = str.replace("Microsoft", "W3School");
// 结果:Please visit W3School and Microsoft!
如需执行大小写不敏感的替换,请使用正则表达式 /i(大小写不敏感):
str = "Please visit Microsoft!";
var n = str.replace(/MICROSOFT/i, "W3School");
请注意正则表达式不带引号。
如需替换所有匹配,请使用正则表达式的 g 标志(用于全局搜索):
str = "Please visit Microsoft and Microsoft!";
var n = str.replace(/Microsoft/g, "W3School");
转换大小写
通过 toUpperCase() 把字符串转换为大小写:
var text1 = "Hello World!"; // 字符串
var text2 = text1.toUpperCase(); // text2 是被转换为大写的 text1
var text3 = text1.toLowerCase(); // text3 是被转换为小写的 text1
字符串连接
除了使用加号,还可以使用concat() 连接多个字符串
var text1 = "Hello";
var text2 = "World";
text3 = text1.concat(" ",text2);
concat() 方法可用于代替加运算符。下面两行是等效的:
var text = "Hello" + " " + "World!";
var text = "Hello".concat(" ","World!");
所有字符串方法都会返回新字符串。它们不会修改原始字符串。
正式地说:字符串是不可变的:字符串不能更改,只能替换。
String.trim()
trim() 方法删除字符串两端的空白符:
提取字符串字符
- charAt(position)
charAt() 方法返回字符串中指定下标(位置)的字符串:
var str = "HELLO WORLD";
str.charAt(0); // 返回 H
- charCodeAt(position)
charCodeAt() 方法返回字符串中指定索引的字符 unicode 编码:
var str = "HELLO WORLD";
str.charCodeAt(0); // 返回 72
把字符串转换为数组
可以通过 split() 将字符串转换为数组:
var txt = "a,b,c,d,e"; // 字符串
txt.split(","); // 用逗号分隔
txt.split(" "); // 用空格分隔
txt.split("|"); // 用竖线分隔
如果省略分隔符,被返回的数组将包含 index [0] 中的整个字符串。
如果分隔符是 "",被返回的数组将是间隔单个字符的数组:
var txt = "Hello"; // 字符串
txt.split(""); // 分隔为字符
字符串搜索
- String.indexOf()
indexOf() 方法返回指定文本在字符串中第一次出现(的位置)的索引:
let str = "Please locate where 'locate' occurs!";
str.indexOf("locate") // 返回 7
- String.lastIndexOf()
lastIndexOf() 方法返回指定文本在字符串中最后一次出现的索引:
let str = "Please locate where 'locate' occurs!";
str.lastIndexOf("locate") // 返回 21
如果未找到文本,indexOf() 和 lastIndexOf() 都返回 -1:
这两种方法都接受第二个参数作为搜索的开始位置:
let str = "Please locate where 'locate' occurs!";
str.indexOf("locate", 15) // 返回 21
lastIndexOf() 方法向后搜索(从末尾到开头),意思是:如果第二个参数是 15,则从位置 15 开始搜索,一直搜索到字符串的开头。
let str = "Please locate where 'locate' occurs!";
str.lastIndexOf("locate", 15) // 返回 7
- String.search()
search() 方法在字符串中搜索指定值并返回匹配的位置:
let str = "Please locate where 'locate' occurs!";
str.search("locate") // 返回 7
indexOf() 和 search() 这两种方法并不相等。差别如下:
search()方法不能接受第二个起始位置参数。indexOf()方法不能采用强大的搜索值(正则表达式)。String.match()
如果字符串以指定值开头,则 startsWith() 方法返回 true,否则返回 false
startsWith() 方法区分大小写。
语法:`string.startsWith(searchvalue, start)
| 参数 | 描述 |
|---|---|
| searchvalue | 必需。需要搜索的值。 |
| start | 可选。默认为 0。开始搜索的位置。 |
let text = "Hello world, welcome to the universe.";
text.startsWith("Hello") // 返回 true
- String.endsWith()
如果字符串以指定值结尾,则 endsWith() 方法返回 true,否则返回 false
语法:string.endsWith(searchvalue, length)
| 参数 | 描述 |
|---|---|
| searchvalue | 必需。需要搜索的值。 |
| length | 可选。要搜索的长度。 |
var text = "Bill Gates";
text.endsWith("Gates") // 返回 true
多行字符串
模板字面量允许多行字符串
let text =
`The quick
brown fox
jumps over
the lazy dog`;
插值
let firstName = "Bill";
let lastName = "Gates";
let text = `Welcome ${firstName}, ${lastName}!`;
表达式替换
let price = 10;
let VAT = 0.25;
let total = `Total: ${(price * (1 + VAT)).toFixed(2)}`;
HTML 模板
let header = "Templates Literals";
let tags = ["template literals", "javascript", "es6"];
let html = `<h2>${header}</h2><ul>`;
for (const x of tags) {
html += `<li>${x}</li>`;
}
html += `</ul>`;
数字
注:JavaScript 数值始终是 64 位的浮点数
JavaScript 数值既可以带小数点,也可以不带:
var x = 3.14; // 带小数点的数值
var y = 3; // 不带小数点的数值
超大或超小的数可通过科学计数法来写:
var x = 123e5; // 12300000
var y = 123e-5; // 0.00123
整数(不使用指数或科学计数法)会被精确到 15 位。
var x = 999999999999999; // x 将是 999999999999999
var y = 9999999999999999; // y 将是 10000000000000000
小数的最大数是 17 位,但是浮点的算数并不总是 100% 精准:
var x = 0.2 + 0.1; // x 将是 0.30000000000000004
使用乘除法有助于解决上面的问题:
var x = (0.2 * 10 + 0.1 * 10) / 10; // x 将是 0.3
数字和字符串相加
JavaScript 从左向右进行编译。
JavaScript 的加法和级联(concatenation)都使用 + 运算符。
var x = 10;
var y = 20;
var z = x + y; // z 将是 30(一个数);因为 x 和 y 都是数,10 + 20 将被相加。
var x = "10";
var y = "20";
var z = x + y; // z 将是 1020(字符串)
如果您对一个字符串和一个数字相加,结果也是字符串级联:
var x = 10;
var y = "20";
var z = x + y; // z 将是 1020(一个字符串)
var x = "10";
var y = 20;
var z = x + y; // z 将是 1020(字符串)
var x = 10;
var y = 20;
var z = "The result is: " + x + y; // z 将是 1020(字符串)
var x = 10;
var y = 20;
var z = "30";
var result = x + y + z; // result 将是 3030(字符串);因为 z 是字符串,30 + "30" 被级联。
数字字符串
var x = 100; // x 是数字
var y = "100"; // y 是字符串
在所有(除了“ +” )数字运算中,JavaScript 会尝试将字符串转换为数字:
var x = "100";
var y = "10";
var z = x + y; // z 不会是 110(而是 10010)
var x = "100";
var y = "10";
var z = x / y; // z 将是 10
var x = "100";
var y = "10";
var z = x * y; // z 将是 1000
NaN(Not a Number)
NaN 属于 JavaScript 保留词,指示某个数不是合法数。
尝试用一个非数字字符串进行除法会得到 NaN(Not a Number):
var x = 100 / "Apple"; // x 将是 NaN(Not a Number)
isNaN() 课、可用来确定某个值是否是数:
var x = 100 / "Apple";
isNaN(x); // 返回 true,因为 x 不是数
数学运算中使用了 NaN,则结果也将是 NaN:
var x = NaN;
var y = 5;
var z = x + y; // z 将是 NaN
+ 组合
var x = NaN;
var y = "5";
var z = x + y; // z 将是 NaN5
NaN 是数,typeof NaN 返回 number:
typeof NaN; // 返回 "number"
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"
进制
JavaScript 会把前缀为 0x 的数值常量解释为十六进制。
var x = 0xFF; // x 将是 255。
不要用前导零写数字(比如 07)。
一些 JavaScript 版本会把带有前导零的数解释为八进制。
默认地,Javascript 把数显示为十进制小数。
但是您能够使用 toString() 方法把数输出为十六进制、八进制或二进制。
var myNumber = 128;
myNumber.toString(16); // 返回 80
myNumber.toString(8); // 返回 200
myNumber.toString(2); // 返回 10000000
常用方法
toString()
toString() 以字符串返回数值。
所有数字方法可用于任意类型的数字(字面量、变量或表达式):
var x = 123;
x.toString(); // 从变量 x 返回 123
(123).toString(); // 从文本 123 返回 123
(100 + 23).toString(); // 从表达式 100 + 23 返回 123
toExponential()
toExponential() 返回字符串值,它包含已被四舍五入并使用指数计数法的数字。
参数是可选的,如果没有设置,JavaScript 不会对数字进行舍入
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
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
把变量转换为数值
| 方法 | 描述 |
|---|---|
| Number() | 返回数字,由其参数转换而来。 |
| parseFloat() | 解析其参数并返回浮点数。 |
| parseInt() | 解析其参数并返回整数。 |
- Number() 方法
Number() 可用于把 JavaScript 变量转换为数值,如果无法转换数字,则返回 NaN。:
x = true;
Number(x); // 返回 1
x = false;
Number(x); // 返回 0
x = new Date();
Number(x); // 返回 1404568027739
x = "10"
Number(x); // 返回 10
x = "10 20"
Number(x); // 返回 NaN
用于日期的 Number() 方法
Number() 还可以把日期转换为时间戳,如果无法转换为数值,则返回 NaN :
umber(new Date("2019-04-15")); // 返回 1506729600000
- parseInt() 方法
parseInt() 解析一段字符串并返回数值。允许空格。只返回首个数字:
parseInt("10"); // 返回 10
parseInt("10.33"); // 返回 10
parseInt("10 20 30"); // 返回 10
parseInt("10 years"); // 返回 10
parseInt("years 10"); // 返回 NaN
- parseFloat() 方法
parseFloat() 解析一段字符串并返回数值。允许空格。只返回首个数字,如果无法转换为数值,则返回 NaN:
parseFloat("10"); // 返回 10
parseFloat("10.33"); // 返回 10.33
parseFloat("10 20 30"); // 返回 10
parseFloat("10 years"); // 返回 10
parseFloat("years 10"); // 返回 NaN
数值属性
| 属性 | 描述 |
|---|---|
| MAX_VALUE | 返回 JavaScript 中可能的最大数。 |
| MIN_VALUE | 返回 JavaScript 中可能的最小数。 |
| NEGATIVE_INFINITY | 表示负的无穷大(溢出返回)。 |
| NaN | 表示非数字值("Not-a-Number")。 |
| POSITIVE_INFINITY | 表示无穷大(溢出返回)。 |
MIN_VALUE 和 MAX_VALUE
MAX_VALUE 返回 JavaScript 中可能的最大数字。
var x = Number.MAX_VALUE;
MIN_VALUE 返回 JavaScript 中可能的最小数字。
var x = Number.MIN_VALUE;
POSITIVE_INFINITY
var x = Number.POSITIVE_INFINITY;
NEGATIVE_INFINITY
溢出时返回 POSITIVE_INFINITY:
var x = Number.NEGATIVE_INFINITY;
document.getElementById("demo").innerHTML = x; // 结果:Infinity
var x = 1 / 0; // 结果:Infinity
var x = -1 / 0; // 结果:Infinity
NaN - 非数字
var x = Number.NaN;
var x = 100 / "Apple"; // x 将是 NaN (Not a Number)
数字属性不可用于变量
数字属性属于名为 number 的 JavaScript 数字对象包装器。
这些属性只能作为 Number.MAX_VALUE 访问。
使用 myNumber.MAX_VALUE,其中 myNumber 是变量、表达式或值,将返回 undefined:
var x = 6;
var y = x.MAX_VALUE; // y 成为 undefined
数组
语法:
var array-name = [item1, item2, ...];
var cars = ["Saab", "Volvo", "BMW"];
var cars = [
"Saab",
"Volvo",
"BMW"
];
访问数组元素
var name = cars[0];
修改数组元素
cars[0] = "Opel";
实例:
注:[0] 是数组中的第一个元素。[1] 是第二个。数组索引从 0 开始。
var cars = ["Saab", "Volvo", "BMW"];
document.getElementById("demo").innerHTML = cars[0];
改变数组元素
cars[0] = "Opel";
访问完整数组
<p id="demo"></p>
<script>
var cars = ["Audi", "BMW", "porsche"];
document.getElementById("demo").innerHTML = cars;
</script>
<!-- P的内容:Audi,BMW,porsche -->
数组是对象
数组是一种特殊类型的对象。在 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;
数组属性
例:
var x = cars.length; // length 属性返回元素的数量
var y = cars.sort(); // sort() 方法对数组进行排序
访问第一个元素
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>";
}
text += "</ul>";
另一种方法,使用 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 属性向数组添加新元素(原理是例用索引从0开始):
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[fruits.length] = "Lemon"; // 向 fruits 添加一个新元素 (Lemon)
关联数组
很多编程元素支持命名索引的数组。
具有命名索引的数组被称为关联数组(或散列)。
JavaScript 不支持命名索引的数组。
在 JavaScript 中,数组只能使用数字索引。
var person = [];
person[0] = "Bill";
person[1] = "Gates";
person[2] = 62;
var x = person.length; // person.length 返回 3
var y = person[0]; // person[0] 返回 "Bill"
假如您使用命名索引,JavaScript 会把数组重定义为标准对象。
之后,所有数组的方法和属性将产生非正确结果。
var person = [];
person["firstName"] = "Bill";
person["lastName"] = "Gates";
person["age"] = 62;
var x = person.length; // person.length 将返回 0
var y = person[0]; // person[0] 将返回 undefined
数组和对象的区别
在 JavaScript 中,数组使用数字索引。
在 JavaScript 中,对象使用命名索引。
数组是特殊类型的对象,具有数字索引。
何时使用数组,何时使用对象?
- JavaScript 不支持关联数组
- 如果希望元素名为字符串(文本)则应该使用对象。
- 如果希望元素名为数字则应该使用数组。
如何识别数组
问题在于 JavaScript 运算符 typeof 返回 "object":
var fruits = ["Banana", "Orange", "Apple", "Mango"];
typeof fruits; // 返回 object
typeof 运算符返回 "object",因为 JavaScript 数组属于对象。
- 方案1
ECMAScript 5 定义了新方法 Array.isArray():
Array.isArray(fruits); // 返回 true
- 方案2
创建您自己的 isArray() 函数以解决此问题:
function isArray(x) {
return x.constructor.toString().indexOf("Array") > -1;
}
- 方案3
假如对象由给定的构造器创建,则 instanceof 运算符返回 true:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits instanceof Array // 返回 true
数组方法
把数组转换为字符串
toString() 把数组转换为数组值(逗号分隔)的字符串:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits.toString();
// 结果:Banana,Orange,Apple,Mango
join() 方法也可将所有数组元素结合为一个字符串。与 toString() 不同的地方在于可以规定分隔符
var fruits = ["Banana", "Orange","Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits.join(" * ");
// 结果: Banana * Orange * Apple * Mango
Popping 和 Pushing
从数组弹出项目,或向数组推入项目。
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x = fruits.pop(); // 从 fruits 删除最后一个元素("Mango"),并赋给 x
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"];
var x = fruits.shift(); // 从 fruits 删除第一个元素 "Banana",并赋值给 x
unshift() 方法(在开头)向数组添加新元素,并“反向位移”旧元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.unshift("Lemon"); // 向 fruits 添加新元素 "Lemon"
例用 unshift() 方法返回新数组的长度。
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.unshift("Lemon"); // 返回 5
更改元素
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[0] = "Kiwi"; // 把 fruits 的第一个元素改为 "Kiwi"
例用 length 属性提供了向数组追加新元素的简易方法:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[fruits.length] = "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() 方法返回一个包含已删除项的数组:
<button onclick="myFunction()">试一试</button>
<p id="demo1"></p>
<p id="demo2"></p>
<p id="demo3"></p>
<script>
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo1").innerHTML = "原数组:<br> " + fruits;
function myFunction() {
var removed = fruits.splice(2, 2, "Lemon", "Kiwi");
document.getElementById("demo2").innerHTML = "新数组:<br>" + fruits;
document.getElementById("demo3").innerHTML = "已删除项:<br> " + removed;
}
</script>
结果:
原数组:
Banana,Orange,Apple,Mango
新数组:
Banana,Orange,Lemon,Kiwi
已删除项:
Apple,Mango
通过参数设定,使用 splice() 能在数组中不留“空洞”的情况下移除元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(0, 1); // 删除 fruits 中的第一个元素
第一个参数(0)定义新元素应该被添加(接入)的位置。
第二个参数(1)定义应该删除多个元素。
其余参数被省略。没有新元素将被添加。
合并(连接)数组
concat() 方法通过合并(连接)现有数组来创建一个新数组:
var myGirls = ["Cecilie", "Lone"];
var myBoys = ["Emil", "Tobias", "Linus"];
var myChildren = myGirls.concat(myBoys); // 连接 myGirls 和 myBoys
// 结果:Emma,Isabella,Jacob,Michael,Ethan
concat() 方法不会更改现有数组。它总是返回一个新数组。
concat() 方法可以使用任意数量的数组参数:
var arr1 = ["Cecilie", "Lone"];
var arr2 = ["Emil", "Tobias", "Linus"];
var arr3 = ["Robin", "Morgan"];
var myChildren = arr1.concat(arr2, arr3); // 将arr1、arr2 与 arr3 连接在一起
// 结果:Emma,Isabella,Jacob,Michael,Ethan,Joshua,Daniel
concat() 方法也可以将值作为参数:
var arr1 = ["Cecilie", "Lone"];
var myChildren = arr1.concat(["Emil", "Tobias", "Linus"]);
// 结果:Emma,Isabella,Jacob,Michael,Ethan
裁剪数组
slice() 方法用数组的某个片段切出新数组。
本例从数组元素 1 ("Orange")开始切出一段数组:
<p id="demo"></p>
<script>
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1);
document.getElementById("demo").innerHTML = fruits + "<br><br>" + citrus;
</script>
结果:
Banana,Orange,Lemon,Apple,Mango
Orange,Lemon,Apple,Mango
slice() 方法创建新数组。它不会从源数组中删除任何元素。
本例从数组元素 3 ("Apple")开始切出一段数组:
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(3);
slice() 可接受两个参数,比如 (1, 3)。
如果结束参数被省略,比如第一个例子,则 slice() 会切出数组的剩余部分。
该方法会从开始参数选取元素,直到结束参数(不包括)为止;
<p id="demo"></p>
<script>
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1,3);
document.getElementById("demo").innerHTML = fruits + "<br><br>" + citrus;
</script>
结果:
Banana,Orange,Lemon,Apple,Mango
Orange,Lemon
自动 toString()
所有 JavaScript 对象都拥有 toString() 方法,
如果需要原始值,则 JavaScript 会自动把数组转换为字符串。
下面两个例子将产生相同的结果:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits.toString();
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits;
