快速入门
JavaScript代码可以直接嵌在网页的任何地方,通常会把JavaScript代码放在HTML的<head>
中。由<script>...</script>
包含的代码就是JavaScript代码,它将直接被浏览器执行。
另一种方法就是把JavaScript代码放到一个单独的.js
文件中,然后在HTML中通过<script src="/js文件地址">...</script>
的方式引入这个文件。
**JavaScript中的注释符号是//
或/**/
,*JavaScript中严格区分大小写。**
若需要调试JavaScript代码,可以打开一个网页,然后按下F12打开开发者工具,点击控制台(Console)在>
里可以直接输入JavaScript代码,按回车后执行。按F12可关闭开发者工具。
在控制台中输入console.log(a)
可以查看变量a的内容,回车后显示的值就是变量内容。
本文中使用的是把JavaScript代码放到一个单独的.js
文件中的方法。因此先建立一个test.html文档,其内容如下:
1 |
|
建好test.html后,在test.html所在文件夹新建一个text.js文件,后续的JavaScript代码都在text.js中编写,控制台的代码在text.js里运行,需要页面显示的代码在test.html里运行。
基本语法
JavaScript的语法与Java类似,每个语句以;
结束,语句块用{...}
。语句块中具有以4个空格为单位的缩进。
练习题
分别利用行注释和块注释把下面的语句注释掉,使它不再执行:
1 | //alert('我不想执行'); |
数据类型
Number
JavaScript不区分整数和浮点数,统一用Number表示。
以下是合法的Number类型:
- 整数:123
- 浮点数:0.123
- 科学计数法:1.2345e3(即12345x1000)
- 复数:-123
- 无法计算结果时:NaN
- 无限大:Infinity
JavaScript里的十六进制用0x
前缀表示。
字符串
字符串是以单引号'
'或双引号"
"括起来的任意文本,引号本身不是字符串的一部分。如:‘abc'、“qwe”。
布尔值
布尔值与布尔代数的表示完全一致,一个布尔值只有true
、false
两种值。
&&
是与运算,||
是或运算,!
是非运算。
比较运算符
JavaScript允许对任意数据类型做比较。
注意相等运算符==
,JavaScript有两种比较运算符:
==
比较运算符:会自动转换数据类型再比较。===
比较运算符:不会自动转换数据类型。若数据类型不一致,返回false,若一直,再进行比较。
NaN
与所有值都不相等,包括他自己。
唯一能判断NaN为true的方法是通过isNaN()
函数。
JavaScript比较浮点数只能计算它们之差的绝对值,看是否小于某个阈值即:
1 | 1/3===(1-2/3);//false |
null和undefined
null
表示一个空的值,它和0以及空字符''
不同。0是一个数值,''
表示长度为0的字符串,null表示空。
undefined
表示值未定义,undefined
仅在判断函数参数是否传递的情况下有用。
数组
数组是一组按顺序排列的集合,集合的每个值称为元素。JavaScript的数组可以包括任意数据类型,如:
1 | [1,2,3.14,'Hello',null,true]; |
创建数组可以通过Array()
函数实现:
1 | new Array(1,2,3.14,'Hello',null,true); |
数组的元素可以通过索引来访问,起始值是0.
对象
JavaScript的对象是一组由键-值组成的无序集合:
1 | var person={ |
JavaScript对象的键都是字符串类型,值可以是任意数据。每个键又称为对象的属性。
要获取一个对象的属性,可以用对象变量.属性名
的方式,如person.name;
。
变量
变量在JavaScript中用一个变量名表示,变量名是大小写英文、数字、$
和_
组成,不能以数字开头。变量名也不能是JavaScript的关键字,如if、while等。变量名也可以用中文。
声明变量用var
语句,如:
1 | var a; |
=
号为赋值号,同一个变量可以反复赋值,可以是不同类型的变量,但只能声明一次:
1 | var a=123; |
要在控制台上显示变量的内容,用console.log(x)
语句。使用console.log()
代替alert()
的好处是避免弹出烦人的对话框。
strict模式
使用var声明的变量不是全局变量,它的范围被限制在该变量被声明的函数体内,同名变量在不同的函数体内互不冲突。
在strict模式下运行的JavaScript代码,强制通过var声明变量,未使用var声明变量就使用的,运行会报错。
启用strict模式的方法是在JavaScript代码的第一行写上:
1 | ; |
这是一个字符串,不支持strict模式的浏览器会把它当做一个字符串语句执行,支持strict模式的浏览器将会开启strict模式运行JavaScript。
字符串
转义字符\
可以转义很多字符,比如\n
表示换行,\t
表示制表符,\\
表示\
字符。
ASCII字符可以以\x##
形式的十六进制表示,如\x41;
便等同于A。
还可以用\u####
表示一个Unicode字符,如\u4e2d\u6587;
便等同于‘中文’。
多行字符串
由于多行字符串用\n
写起来比较麻烦,因此最新的ES6标准新增了一种多行字符串的方法,用反引号`表示,反引号里面的内容每次回车就会自动换行:
1 | `这是一个 |
模板字符串
要把多个字符串连接起来,可以用+
号连接:
1 | var name="张三"; |
当由很多变量需要连接时,用+
号比较麻烦,ES6新增了一种模板字符串,表示方法和多行字符串一样,但它会自动替换字符串中的变量:
1 | var name="张三"; |
操作字符串
字符串是不可变的,若对字符串的某个索引赋值,不会报错,但也没有任何效果。
toUpperCase
toUpperCase()
把一个字符串全部变为大写:
1 | var s="Hello"; |
toLowerCase
toLowerCase
把一个字符串全部变为小写:
1 | var s="Hello"; |
indexOf
indexof()
会搜索指定字符串出现的位置:
1 | var s='hello,world'; |
substring
substring()
返回指定索引区间的子串:
1 | var s='hello,world'; |
练习题
测试你的浏览器是否支持ES6标准,如果不支持,请把多行字符串用\n
重新表示出来:
1 | console.log(`多行 |
测试你的浏览器是否支持ES6模板字符串,如果不支持,请把模板字符串改为+
连接的普通字符串:
1 | var name = '小明'; |
数组
要取得数组的长度,可直接访问length
属性:
1 | var arr=[1,2,3.14,'Hello',null,true]; |
注意:直接给Array的length
赋一个新值会导致Array大小的变化:
1 | var arr=[1,2,3]; |
Array可以通过索引把对应的元素修改为新的值,通过索引赋值会直接修改Array。若索引超过了范围,同样会引起Array大小的变化:
1 | var arr=[1,2,3]; |
indexOf
与String类似,Array也可以通过indexof()
来搜索一个指定的元素位置:
1 | var arr=[10,20,'30','xyz']; |
slice
slice
对应String的substring()
,截取Array的部分元素,然后返回一个新的Array:
1 | var arr=['A','B','C','D','E','F','G']; |
若不给slice()
传递任何参数,它会从头到尾截取所有元素。
push和pop
push()向Array的末尾添加元素,pop()则把Array的最后一个元素删掉:
1 | var arr=[1,2]; |
unshift和shift
若要往Array的头部添加若干元素,使用unshift()
方法,shift()
方法则是把Array的第一个元素删掉:
1 | var arr=[1,2]; |
sort
sort()
可以对当前Array进行排序,它会直接修改当前Array的元素位置,直接调用是,按照默认顺序排序:
1 | var arr=['B','C','A']; |
reverse
reverse()
可以反转Array内的元素:
1 | var arr=[1,2,3]; |
splice
splice
方法可以从指定的索引开始删除元素,然后再从该位置添加元素:
1 | var arr=[1,2,3,4,5,6]; |
concat
concat()
方法把当前的Array和另一个Array连接起来,并返回一个新的Array:
1 | var arr=['A','B','C']; |
concat()
方法可以接收任意个元素和Array,并自动把Array拆开,然后全部添加到新的Array里:
1 | var arr=['A','B','C']; |
join
join()
方法把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串:
1 | var arr=['A','B','C',1,2,3]; |
若Array的元素不是字符串,将自动转换为字符串后再连接。
多维数组
若数组的某个元素又是一个Array,便形成了多维数组。
练习题
如何通过索引取到500
这个值:
1 | var arr = [[1, 2, 3], [400, 500, 600], '-']; |
在新生欢迎会上,你已经拿到了新同学的名单,请排序后显示:欢迎XXX,XXX,XXX和XXX同学!
:
1 | var arr = ['小明', '小红', '大军', '阿黄']; |
对象
JavaScript的对象是一种由若干键值组成的无序集合数据类型。
JavaScript用一个{...}
表示一个对象,键值对以xxx:xxx
形式声明,用,
隔开:
1 | var xiaoming={ |
可以通过对象.属性
来获取小明的属性:xiaoming.name;
。若属性名包括特殊字符,就必须使用''
括起来:
1 | var zhangsan={ |
访问这一特殊属性无法使用.
操作符,必须使用['xxx']
访问:
1 | zhangsan['middel-school']; |
对象的所有属性都是字符串,但属性值可以是任意数据类型。若访问不存在的属性会返回undefined
。
由于JavaScript的对象是动态类型,因此可以自由给对象添加或删除属性:
1 | var xiaoming={ |
用in
操作符可以检查对象是否拥有某个属性(包括继承属性):
1 | var xiaoming={ |
用hasOwnProperty()
方法可以可以检查对象自身是否拥有某个属性:
1 | var xiaoming={ |
条件判断
JavaScript使用if(){...}else{...}
来进行条件判断,如:
1 | var age=20; |
多行条件判断
使用多个if...else if...else...
组合可以进行更细致的判断:
1 | var age=3; |
JavaScript把null
、undefined
、0
、NaN
和空字符串''
视为false,其他值一概视为true。
练习题
小明身高1.75,体重80.5kg。请根据BMI公式(体重除以身高的平方)帮小明计算他的BMI指数,并根据BMI指数:
- 低于18.5:过轻
- 18.5-25:正常
- 25-28:过重
- 28-32:肥胖
- 高于32:严重肥胖
用if...else...
判断并显示结果:
1 | var height=parseFloat(prompt('请输入身高(m):')); |
循环
JavaScript的循环有两种,一种是for循环,另一种是while循环。
for循环
1 | var x=0; |
练习题
利用for
循环计算1 * 2 * 3 * ... * 10
的结果:
1 | var x=1; |
for循环的3个条件是可以省略的,for(;;)
将无限循环下去,为了避免死循环,此时可以使用break语句退出循环。
for...in
for循环的一个变体是for...in
循环,它可以把一个对象的所有属性依次循环出来:
1 | var a={ |
可用hasOwnProperty()
过滤掉继承属性:
1 | var a={ |
for...in
循环也可以直接循环出Array的索引:
1 | var a=['A','B','C']; |
while
while循环只有一个判断条件,条件满足就不断循环,条件不满足则退出循环:
1 | var x=0; |
do...while
do...while
与while循环的唯一区别在于,do...while
在每次循环完成时判断条件:
1 | var n=0; |
练习题
请利用循环遍历数组中的每个名字,并显示Hello, xxx!
。请尝试for
循环和while
循环,并以正序、倒序两种方式遍历:
1 | var arr = ['Bart', 'Lisa', 'Adam']; |
Map和Set
JavaScript的默认对象表示方式{}
可以视为其他语言中的Map的数据结构。但JavaScript的对象,其键必须是字符串,实际上Number或其他数据类型作为键也是合理的。
为解决这种情况,ES6规范引入了新的数据类型Map。
以下代码可以测试浏览器是否支持ES6规范,若报错则不支持:
1 | var m = new Map(); |
Map
Map是一组键值对的结构,具有极快的查找速度:
1 | var m=new Map([['Michael',95],['Bob',75],['Tracy',85]]); |
初始化Map需要两个二维数组,或者直接初始化一个空Map。Map具有以下方法:
1 | var m=new Map();//空Map |
由于一个key只能对应一个value,依次多次对一个key放入value,后面的值会把前面的值顶掉。
Set
Set和Map类似,也是一组key的集合,但Set不存储value。Set中没有重复的key。
创建一个Set,需要提供一个Array作为输入,或者直接初始化一个空Set:
1 | var s=new Set();//空Set |
Set具有以下方法:
1 | var a=new Set([1,2,3]); |
iterable
遍历Array可以采用下标循环,而Set和Map无法使用 下标。为了统一集合类型,ES6引入了iterable类型。Array、Map和Set都属于iterable类型。
具有iterable类型的集合可以通过for...of
循环来遍历,可以通过以下代码测试浏览器是否支持for...of
循环:
1 | var a = [1, 2, 3]; |
用for...of
循环遍历集合,用法如下:
1 | var a=['A','B','C']; |
当给Array
对象添加了额外的属性后,使用for ... in
循环会有意想不到的意外效果:
1 | var a = ['A', 'B', 'C']; |
for ... in
循环将把name
包括在内,但Array
的length
属性却不包括在内。
for ... of
循环则完全修复了这些问题,它只循环集合本身的元素:
1 | var a = ['A', 'B', 'C']; |
还可以使用ES5.1引入的iterable
内置forEach
方法,它接收一个函数,每次迭代就自动回调该函数:
1 | var a=['A','B','C']; |
Set
与Array类似,但Set
没有索引,因此回调函数的前两个参数都是元素本身。
Map
的回调函数参数依次为value
、key
和map
本身。
由于JavaScript的函数调用不要求参数必须一致,因此可以忽略部分参数,如只需要获得Array的element
。