4.1 语法基础
4.1.1 Javascript 简介
Javascript Web 是前端开发人员必备的三门技能中最重要的一门。
(1)HTML 定义网页内容
(2)CSS 描述网页布局
(3)JacaScript 处理网页行为
JavaScript 的特点
(1)JavaScript 是一种轻量级编程语言;
(2)JavaScript 可以插入 HTML 页面的编程代码;
(3)JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行;
(4)JavaScript 很容易学习
JavaScript 的用法
(1)HTML 中的脚本必须位于 <script></script> 标签中间;
(2)脚本可被放置在 HTML 页面的 <body> 和 <head> 部分中
4.1.2 输入与输出
我们使用 prompt(" 请输入你的内容 ") 来通过浏览器弹出一个输入框,从而让用户输入内容。具体方法如下:
(1)使用 window.alert() 弹出警告框;
(2)使用 document.write() 方法将内容写到 HTML 文档中,或者 document.writeln() 加上一个换行,虽然无法真正换行(因为 HTML 使用 <br/> 标签来换行);
//document.write() 向 HTML 文档中写入内容时,会覆盖掉文档中已经被渲染的内容,一般用这种方法调试页面,在真实的网页调试中很少使用。
(3)使用 innerHTML 写入到 HTML 元素中,比如 div 中。
(4)使用 console.log() 写入到浏览器的控制台。浏览器中使用 F12 启动调试模式,在调试窗口中点击 Console(控制台)来完成输出内容。
下面举例一个代码片段:
<!DOCTYPE
html
>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>js-example
</title>
<script>
var content =
prompt(
"请输入你的内容")
;
//输出变量 content 的值:
alert(
"你输入的内容是:" + content)
;
document.
write(
"你输入的内容是:" + content)
;
console.
log(
"你输入的内容是:" + content)
;
</script>
</head>
<body>
</body>
</html>
规则说明:
(1)js 的备注有两种方式://(单行注释)和 /**/ (多行注释);
(2)var:js 关键字,用以定义一个变量,为 variable 的缩写。如:var name = “周启明”;
(3)变量名称遵循驼峰原则(CamelRule);
(4)命名规则:不要使用拼音;少用数字和特殊符号;避免随意简写;最好使用英文单词。
4.1.3 变量与数据类型
变量名前加 var :该变量范围只适用于当前代码块;
变量名前不加 var:该变量为全局变量,在当前的 <script> 范围内都有效;
在 JS 中具备如下数据类型:(全部第一个字母大写)
(1)String:字符串;
(2)Number:数字;
(3)Boolean:布尔类型;
(4)Array:数组;
(5)Object:对象;
(6)Null:空;
(7)Undefined:未定义,表示不含有任何值,连 Null 都没有
我们还可以用 new 新建一个变量:如:var x = new Number;var y = new String 等。
数字运算符:+,-,*,/,%,++,—
赋值运算符:=,+=,-=,/=,%=
比较运算符:==,===(有啥区别?),!=,!==,>,<,>=,<=
逻辑运算符:&&(或),||(且),!(非)
数据类型的转换:
(1)将字符串转换为数字(前提是字符串里存放的确实是一个有效数字):
全局方法:Number(str);
将字符串转换为正数:parseInt(str);
将字符串转换为小数:parseFloat(str);
(2)将任意类型的变量或值转换为字符串:
全局方法:String(var);
4.1.4 分支语句
1,if…else 语句:
if(condition){
当条件为 true 时执行的代码
}
if(condition){
当条件为 true 时执行的代码
}else{
当条件为 false 时执行的代码
}
if(condition1){
当条件 1 为 true 时执行的代码
}else if(condition2){
当条件 2 为 true 时执行的代码
}
else{
当条件 1 和 条件 2 都不满足时执行的代码
}
2,switch 语句:
switch(表达式){
case 1:
执行代码块 1
break;
case 2:
执行代码块 2
break;
default:
值与 case 1 和 case 2 都不同时执行的代码
}
if…esle 语句和 switch 语句的区别:
- if…esle 语句适合判断范围类型的选择结构,如大于、小于等
- switch 语句适合 case 分支与 switch 中的表达式需要精确匹配时,但能用 switch 的都可以改成 if…esle 语句。
3,三元运算符:
(condition)?语句1:语句2;
4.1.5 循环语句
1,for 循环
for(初始值;循环条件;循环被执行后执行){
循环体;
}
2,while 循环
初始赋值;
while(条件){
循环体;
i++;
}
3,do while 循环(while 循环的变体,会在检查条件是否为真之前先执行一遍代码块)
do{
循环体;
}
while(条件);
一般 for 循环可以和 while 循环相互代替。通常优先使用 for 循环来处理可以明确知道循环次数的情况,while 循环处理不明确次数但是有明确的结束特征的循环。
break:终止整个循环;
continue:跳过当前这一次的循环,下一次循环继续执行。
4.1.7 数组与应用
1,定义:数组对象是使用单独的变量名来存储一系列的值。
2,定义数组的三种方法:
(1)常规法:
<script>
var
name =
new
Array()
;
//也可以在括号里添加一个数字,指定数组的长度
names[
0
]=
"张三"
;
names[
1
]=
"李四"
;
names[
2
]=
"王五"
;
names[
3
]=
"赵六"
;
</script>
(2)简洁方式:
<script>
var
name =
new
Array(
"张三"
,
"李四"
,
"王五"
,
"赵六"
)
;
//也可以在括号里添加一个数字,指定数组的长度
</script>
(3)更简洁方式:
<script>
var
name = [
"张三"
,
"李四"
,
"王五"
,
"赵六"
]
;
//注意这里圆括号变为英文中括号
</script>
3,数组的几个基本操作:
<script>
var name = [
"张三"
,
"李四"
,
"王五"
,
"赵六"]
;
document.
write(names[
0])
;
//输出数组的第一个元素,数组下标从 0 开始
document.
write(names.
indexOf(
"李四"))
;
//获取"李四"这个元素的下标,如无则为 -1
document.
write(names.
length)
;
//获取这个数组的总长度
</script>
删除数组的任意元素:
(1)pop():将数组当中的最后一个元素删除
(2)push():向数组的末尾增加一个新元素
删除数组任意元素的方法:将这个下标的数组元素取出,然后将后方所有元素向前移动一个下标。
<script>
var
index =
2
;
//删除下标为 2 的元素
var
temp = array[index]
;
//使用临时变量存储要被删除的变量
for
(
var
i=index
;
i<array.
length
-
1
;
i++){
array[i] = array[i+
1
]
;
//将后面每一个元素前移
}
array[i] = temp
;
array.
pop
()
;
//删除数组的最后一个元素
</script>
将两个数组连接在一起变成一个数组的方法:定义第三个数组,将第一个数组的元素赋值给第三个数组的前面部分,再将第二个数组的元素赋值给第三个数组。
(为什么这里的 i 元素没有设置为全局变量依然可以在下面的语句中生效?)
<script>
var
array1 = [
11
,
22
,
33
,
44
,
55
]
;
var
array2 = [
66
,
77
,
88
,
99
]
;
var
newarray =
new
Array()
;
//让新数组和数组1的元素一一对应
for
(
i
=
0
;
i
<array1.length
;
i
++){
newarray[
i
] = array1[
i
]
;
}
//让新数组的 i 下标继续增加,数组 2 的下标开始从头增加
for
(
j
=
0
;
j
<array2.length
;
i++
,
j
++){
newarray[i] = array2[
j
]
;
}
document.
write
(newarray)
;
</script>
4,数组的排序:(重要)
(1)冒泡排序:依次比较相邻的两个数,将小的数放在前面,将大的数放在后面,不断重复。
(看不懂。。。)
<!DOCTYPE
html
>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
Array-冒泡排序
</title>
</head>
<body>
<script>
var
a = [
12
,
34
,
23
,
56
,
69
,
38
,
47
]
;
//外循环,指定比较的轮数,总共是(长度-1)轮
for
(
i
=
0
;
i
<a.length
;
i
++){
//内循环,将相邻数组的值一一进行比较
for
(
j
=
0
;
j
<a.length-
1
;
j
++){
if
(a[
j
]<a[
j
+
1
]){
temp = a[
j
]
;
a[
j
] = a[
j
+
1
]
;
a[
j
+
1
] =
temp
;
}
}
}
</script>
</body>
</html>
(2)选择排序:每一次从待排序的数据元素中选出最小(最大)的一个元素,顺序放在已排好序的数列的最后,直到全部元素的数据排完。
5,数组的其他知识:
(1)二维数组:数组的数组;
(2)数组对象:数组对象即 Array 对象,相应的属性和方法如下:
Array 对象属性:
属性 | 描述 |
constructor
|
返回对创建此对象的数组函数的引用
|
length
|
设置或返回数组中元素的数目
|
prototype
|
使你也有能力想对象添加属性和方法
|
Array 对象方法:
方法 | 描述 |
concat()
| 连接两个或更多的数组,并返回结果 |
join()
|
把数组的所有元素放入一个字符串,元素通过指定的分隔符进行分隔
|
pop()
|
删除并返回数组的最后一个元素
|
push()
|
向数组的末尾添加一个或更多的元素,并返回新的长度
|
reverse()
| 颠倒数组中元素的顺序 |
shift()
|
删除并返回数组的第一个元素
|
slice()
|
从某个已有的数组返回选定的元素
|
sort()
|
对数组的元素进行排序
|
splice()
|
删除元素,并向数组添加新元素
|
toSource()
|
返回该对象的源代码
|
toString()
|
把数组转换为字符串,并返回结果
|
toLocaleString()
| 把数组转换为本地数组,并返回结果 |
unshift()
|
向数组的开头添加一个或更多的元素,并返回新的长度
|
valueOf()
|
返回数组对象的原始值
|
4.1.8 函数与应用
函数:由事件驱动的或者当它被调用时执行的可重复使用的代码块。
1,自定义函数语法:
function 函数名称(参数列表){
被执行代码;
返回值;
}
说明:函数的语法中
(1) function 必须有;
(2)函数名称必须有;
(3)参数列表可以没有或者有多个,用逗号隔开即可;
(4)被执行代码必须有;
(5)return 的值可有可无。
2,函数的种类:
(1)无参数无返回值的函数:
<script>
functin myfun1(){
document.
write
(
"无参数无返回值的函数<br>"
)
;
document.
write
(
"此类参数通常只为简化代码<br>"
)
;
}
//调用 myfun1 函数
myfun1()
;
</script>
(2)无参数有返回值的函数
:
<script>
function
myfun2
(){
document.
write
(
"无参数,有返回值的函数<br>"
)
;
var
age =
prompt
(
"请输入你的年龄"
)
;
if
(age<
60
){
return
"年轻人"
;
}
else
{
return
"老年人"
;
}
}
//调用 myfun1 函数
var
type =
myfun2
()
;
document.
write
(type)
;
</script>
(3)有参数无返回值的函数
:
<script>
// 函数的参数 a 和 b,叫形参
function
myfun3
(a
,
b){
document.
write
(
"有参数无返回值的函数<br>"
)
;
var
result = a + b
;
document.
write
(
"两个数的和为:"
+result)
;
}
//调用 myfun3 函数,100 和 500 叫实参,实参也可以是变量
myfun3
(
100
,
500
)
;
</script>
(4)有参数有返回值的函数
:
<script>
function
myfun4
(age){
document.
write
(
"有参数有返回值的函数<br>"
)
;
var
type
;
if
(age<
60
){
type =
"年轻人"
;
}
else
{
type =
"老年人"
;
}
return
type
;
}
//调用 myfun4 函数
document.
write
(
myfun4
(
65
))
;
</script>
3,函数的作用
(1)提升代码的可重用性
(2)更好区分代码的功能模块,提升可维护性
4,举例:获取数组的最大值:
<script>
function
getArrayMax(arr){
var max=arr[
0]
;
for(
var i=
1
;i<arr.
length
;i++){
if(max<arr[i]){
max = arr[i]
;
}
}
return max
;
}
var myarray = [
23
,
45
,
45
,
33
,
78
,
5
,
4
,
35
,
3]
;
var result =
getArrayMax(myarray)
;
document.
write(
"数组的最大值是"+ result)
;
</script>
5,JS 中的两种特殊情况:
(1)可选参数:调用 JS 的内置参数时,可以传递不同数量的实际参数,而不报错。
(2)匿名函数:语法如下:
<script>
(
function
(n){
for
(
var
i=
1
;
i<=n
,
i++){
document.
write
(i)
;
}
})(
10
)
;
</script>
函数本身没有名字,而是直接定义完函数后就运行该函数,并传递参数 10 给函数体。这样的函数只能运行一次。
4.1.9 TDD测试驱动开发
TDD 测试:Test-Driven development 测试驱动开发
本质:一个函数,是针对待测功能函数定制的测试函数。
TDD 目的:将手动测试改为自动测试
TDD 作用:找出功能函数的 bug,增加测试效率
1,编写功能函数架构
2,搜集测试数据(测试用例)
3,编写测试驱动(测试函数)
4,编写功能代码
5,测试找出 bug
6,修改 bug,再次测试,直到所有测试用例都已通过测试
测试驱动模板:
function testCheckNumber(value,except){
var actual = checkNumber(value);
if(actual==expect){
document.write("测试通过<br>");
}else{
document.write("测试不通过<br>");
}
}
如我们对曾经做过的“判断用户输入的字符串是否为一个数字”的代码进行测试:
<!DOCTYPE
html
>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>函数-有效数字检测(TDD测试)
</title>
</head>
<script>
function
check(string){
var m =
0
, flag =
true
;
//统计负号的个数
var n =
0
;
//统计小数点的个数
for(
var i=
0
;i<string.
length
;i++) {
var c = string.
charCodeAt(i)
;
//获取每个字符的 ASCII 码
//通过 ASCII 码检查,如果字符不是 0-9 的数字或者负号或者小数,则无效
if ((c >=
0 && c <
45) || (c ==
47) || (c >
57)) {
flag =
false
;
}
//每次出现负号或小数点,则计数器加一
if (c ==
45) m++
;
if (c ==
46) n++
;
}
//如果负号或者小数点的数量大于一个,则无效
if(m>
1) flag =
false
;
if(n>
1) flag =
false
;
//如果存在一个负号,而负号不在第一个位置,则无效
if((m==
1) && (string.
charCodeAt(
0)!=
45)) flag =
false
;
//如果存在一个小数点且在最后一位,则无效
if((n==
1) && (string.
charCodeAt(string.
length-
1)==
46)) flag =
false
;
//如果不存在负号,第一位是 0,则第二位不可以还是 0
if((m==
0) && (string.
charCodeAt(
0)==
48) && (string.
charCodeAt(
1)==
48)) flag =
false
;
//如果存在负号,且负号在第一位,且第二位是 0,则第三位不可以还是 0
if((m==
1) && (string.
charCodeAt(
0)==
45) && (string.
charCodeAt(
1)==
48) && (string.
charCodeAt(
2)==
48)) flag =
false
;
//如果不存在负号,0 在第一位,则第二位必须是小数点。如果不是则无效
if((m==
0) && ((string.
charCodeAt(
0)==
48)) && (string.
charCodeAt(
1)!=
46)) flag =
false
;
//如果存在负号,0 在第二位,则第三位必须是小数点。如果不是则无效
if((m==
1) && ((string.
charCodeAt(
1)==
48)) && (string.
charCodeAt(
2)!=
46)) flag =
false
;
//如果存在负号,则第二位不可以是小数点
if((m==
1) && ((string.
charCodeAt(
1)==
46))) flag =
false
;
return flag
;
}
function
textcheck(string
,expect){
var actual =
check(string)
;
if(actual == expect){
document.
write(string+
"测试结果:正确<br>")
;
}
else{
document.
write(string+
"测试结果:错误<br>")
;
}
}
textcheck(
"12345"
,
true)
;
textcheck(
"012345"
,
false)
;
textcheck(
"-12345"
,
true)
;
textcheck(
"-1.2345"
,
true)
;
textcheck(
"12.345"
,
true)
;
textcheck(
"0.12345"
,
true)
;
textcheck(
"-0.12345"
,
true)
;
textcheck(
"12345."
,
false)
;
textcheck(
".12345"
,
true)
;
textcheck(
"-.12345"
,
false)
;
textcheck(
".12-345"
,
false)
;
textcheck(
"..12345"
,
false)
;
textcheck(
"..--12345"
,
false)
;
textcheck(
"--12.345"
,
false)
;
</script>
<body>
</body>
</html>
4.2 对象与API
4.2.1 自定义对象
4.2.2 window 对象
9,定时器对象
在 JS 中,定时器对象主要通过 setInterval()(Interval,
[‘ɪntɚvl],间隔时间)和 setTimeOut() 实现的,两者都会开启队列机制,并在相应的时间延迟后触发某段代码被执行,或某个函数被调用
(1)setInterval():表示间隔多长时间后运行该 JS 程序,且只运行一次。语法为:
window.setInterval(“JS 代码或函数调用
”,毫秒数
);
(2)setTimeOut():表示间隔多长时间后运行一次,且重复运行,语法为:
window.setTimeOut(“JS 代码或函数调用
”,毫秒数
);
实例:
<script>
function
getTime
(){
var
time =
new
Date().
toLocaleTimeString
()
;
//(locale,[lo'kæl],场所)
document.
write
(time)
;
}
//表示每秒钟调用一次 getTime 函数。注意引号问题
setInterval
(
getTime
,
1000
)
;
//这种格式书写也可以
setInterval
(
"
getTime
()"
,
1000
)
;
</script>
setIntetval
除了可以调用函数以外,也可以直接在 setInterval 中编写定时执行的代码:
setInterval
(
"document.
write
(new Date().
toLocaleTimeString
())"
,
1000
)
;
清除或暂停计时器的方法:clearInterval() 或 clearTimeOut() 。
4.2.3 Document 对象
4.3 文档对象模型
4.3.1 查找 DOM 元素
操作 DOM 元素是JavaScript 最为核心的功能之一。
通过 JS 查找 HTML 文档元素的方法:
(1)document.getElementById():通过元素的 ID 号唯一识别到一个元素;
(2)document.getElementByName():因为 HTML 元素会有重名的 Name,此方法会返回一个集合,针对获取到的集合,可以使用数组的方式来遍历每一个元素;
(3)document.getElementByClassName(): 因为 HTML 元素会有重名的 Class 属性,此方法会返回一个集合,针对获取到的集合,可以使用数组的方式来遍历每一个元素;
(4)document.getElementByTagName(): 因为 HTML 元素会有重名的标签,此方法会返回一个集合,针对获取到的集合,可以使用数组的方式来遍历每一个元素;
<!DOCTYPE
html
>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
查找元素集合
</title>
<style>
.
myclass
{
width
:
300
px
;
height
:
150
px
;
background-color
:
#ff7448
;
font-size
:
30
px
;
text-align
:
center
;
vertical-align
:
middle
;
line-height
:
150
px
;
margin
:
5
px
;
float
:
left
;
}
</style>
<script>
function
fillText
{
var
adddiv =
document
.getElementByClassName(
"myclass"
)
;
for
(
var
i=
0
;
i<alldiv.
length
;
i++){
alldiv[i]
innerHTML
=
"
这是
div
内容:
"
+i+
1
;
}
}
</script>
</head>
<body
οnlοad=
"
fillText
()
"
>
<div
class =
"myclass"
></div>
<div
class =
"myclass"
></div>
<div
class =
"myclass"
></div>
<div
class =
"myclass"
></div>
</body>
</html>
4.3.2 新增 DOM 元素
针对 DOM 元素,除了查找以外,还有“新增”、“删除”和“修改”几类操作。我们学习如何新增,以 DIV 举例:
<!DOCTYPE
html
>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
新增 DOM 笔记
</title>
</head>
<script>
function
add
(){
for
(
var
i=
0
;
i<=
20
;
i++){
var
mydiv = document.
createElement
(
"div"
)
;
mydiv.style.width =
"100px"
;
mydiv.style.height =
"100px"
;
mydiv.style.backgroundColor =
"blue"
;
mydiv.style.position =
"fixed"
;
mydiv.style.top = Math.
random
()*
600
+
"px"
;
mydiv.style.left = Math.
random
()*
1200
+
"px"
;
document.body.
appendChild
(mydiv)
;
}
}
</script>
<body
οnlοad=
"
add
()
"
>
</body>
</html>
4.3.3 删除 DOM 元素
要删除一个 DOM 元素,我们只需要获取到这个元素,然后调用这个元素的 remove() 方法即可。
<script>
function
del
(){
var
alldiv = document.
getElementsByTagName
(
"div"
)
;
var
length = allSnow.
length
;
for
(
var
i=
0
;
i<length
;
i++){
alldiv[i].
remove
()
;
}
}
</script>
4.3.4 修改 DOM 属性
一个 HTML 元素通常有两种属性,一种是标签自带的原生 HTML 属性,一种是通过 CSS 设置的样式属性。
(1)【元素.属性=新值】这样的方式来修改原生属性的值;
(2)【元素.style.属性=新值】来修改 CSS 属性的值。