前端三层
- HTML 结构层 从语义的角度描述页面结构
- CSS 样式层 从美观的角度描述页面样式
- JavaScript 行为层 从交互的角度描述页面行为
JavaScript是什么
JavaScript是一种运行在客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。
浏览器就是一种运行JavaScript脚本语言的客户端,JavaScript的解释器被称为JavaScript引擎,为浏览器的一部分。
JavaScript的应用场景
JavaScript发展到现在几乎无所不能,常见的应用场景有:
- 1.网页特效
- 2.服务端开发(Node.js)
- 3.命令行工具(Node.js)
- 4.桌面程序(Electron)
- 5.App(Cordova)
- 6.控制硬件·物联网(Ruff)
- 7,游戏开发(cocos2d-js) 等等
JavaScript的组成
JavaScript是由ECMAScript,DOM和BOM三者组成的。DOM和BOM是在ECMAScript基础上进行的功能扩展。
ECMAScript标准
- JavaScript,JScript,ActionScript等脚本语言都是基于ECMAScript标准实现的。
- 在JavaScript,JScript和ActionScript中声明变量,操作数组等语法完全一样,因为它们都是ECMAScript。但是在操作浏览器对象等方面又有各自独特的方法,这些都是各自语言的扩展。
DOM
DOM是文档对象模型的简称,方便我们对html文档进行操作。它会将整个html看做一个文档模型,元素间的嵌套关系构成了文档树结构,使用该模型的文档树结构,我们就可以对整个html节点和内容进行一系列的操作。
BOM
BOM是浏览器对象模型的简称,集成了一系列操作浏览器功能的API,方便我们操作浏览器窗口。比如页面跳转,弹出对话框,获取屏幕分辨率等等。
JavaScript的书写语法
书写位置
- 写在行内
<input type="button" value="按钮" onclick="alert ('Hello world')" />
- 写在html中的
<script>标签中,常用
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
alert("Hello world");
</script>
</head>
- 写在外部js文件中,在页面引入
<script src="main.js"></script>
注意:引用外部js文件的<script>标签中不可书写JavaScript代码,自定义的JavaScript代码需要书写在另一个新的<script>标签中。
JavaScript注释语法
- 单行注释,使用//注释
<script>
//这是一个单行注释
</script>
- 块级(多行)注释,使用 /* */注释
<script>
/*
这是一个块级注释,
这是一个块级注释,
这是一个块级注释。
*/
</script>
alert语句
alert是警示警告的意思,该函数(方法)作用是在浏览器中弹出一个警示框。
<script>
alert("Hello world");//弹窗Hello world
</script>
prompt语句
prompt是提示的意思,该函数(方法)作用是弹出一个提示对话框,内部有一个提示语句和一个输入框,可以在输入框中根据提示任意输入内容。
<script>
prompt("请输入您的年龄", "");//第一个参数是提示语,第二个参数是默认值
</script>
console控制台
在大部分浏览器中,右键点击审查元素(检查),都可以打开开发者模式,快捷键F12,其中有一个console(控制台)的选项面板,在js中有非常重要的作用。
- 作用1:用于调试错误
- 作用2:可以直接在控制台直接写一些js语句,进行执行
- 作用3:js中有个内置对象console,内部封装了大量的属性和方法,可以通过调用这些方法执行我们想要输出的日志等内容。当我们进入控制台时就可以看到输出的内容了。
console.log("Hello world");
console.log("1", "2");
console.log(4 + 5);
数据类型
字面量
整数型
- 十进制是最基本的数值字面量格式,可以直接在代码中输入。
- 八进制字面值必须带前导0、0O、0o。八进制整数只能包括数字0-7。
- 十六进制前缀是0x或0×。后面可以包含数字(0.9)和字母a-f或A-F。 在进行算术计算时或者参与程序,所有八进制和十六进制的数字都会被转换成十进制。
浮点数
- 就是数学概念中的小数。
- 包含:整数、小数点、小数部分。
- 浮点数不区分进制,所有的浮点数都是十进制下的数字。
- 注意:如果浮点数是大于0小于1的,可以省略小数点前面的0不写。
精度问题
浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数。
例如:0.1+0.2结果不是0.3,而是0.30000000000000004
console.log(1.2);
console.log(-1.2);
console.log(1.2e3);//表示1.2*10^3
console.log(1.2e-4);//表示1.2*10^4
console.log(0.1 + 0.2);//结果会是0.30000000000000004,这是js的精度问题
特殊数
Infinity无穷
- Infinity:无穷的意思。首字母大写。
- 由于计算机计算能力有限,如果高于最大计算值直接显示为正无穷Infinity,如果低于最小 计算值直接显示为-Infinity。
- Infinity本身就是一个数字。
最小值:Number.MIN_VALUE,这个值为:5e-324
最大值:Number.MAX_VALUE,这个值为:1.7976931348623157e+308
无穷大:Infinity
无穷小:-Infinity
console.log(Infinity);//正无穷
console.log(-Infinity);//负无穷
NAN
NaN: not a num表示不是一个正常的数,但是还是一个Number类型的数字。这个数字没办法用前面的表示方法表示。
- NaN与任何值都不相等,包括他本身。
- isNaN():判断一个数据是不是一个NaN。
console.log(0 / 0);//结果就是NaN
console.log(isNaN(0 / 0));
字符串
- 字符串是由任意个数的有序或无序的字符组成的串,类似人类的语言,在JS中有自己特殊的与法。
- 组成:字母、汉字、特殊符号、空白等。
- 字符串字面量写法:是用一对单引号('')或双引号("")及引号内的字符构成、引号中间的字符可以有任意多个,也可以是没有字符的空字符串。
- 注意:字符串中如果字符包含了双引号,则其外部应该由单引号标示,反之相同。
转义字符
使用反斜杠 \ 实现显示特殊字符。
console.log("1");//显示字符串1
console.log("'2'");//显示字符串'2'
console.log("\"2\"");//显示字符串"2"
console.log("C:\\test");//显示路径字符串C:\test
变量声明及赋值
使用var关键字声明
- 规则(必须遵守的,不遵守会报错): 由字母、数字、下划线、$符号组成,不能以数字开头。 字母区分大小写,A和a示不同。 不能是关键字和保留字,关键字指的是js中有特殊功能的小词语,比如var、for等; 保留字指的是现在没有特殊功能,但是将来新语法中有可能作为关键字使用。
- 规范(建议遵守的,不遵守不会报错):
变量名必须有意义
遵守驼峰命名法。多个单词组合而成的,第一个单词首字母小写,后面单词的首字母需要大写。
例如:userName、userPassword。
使用 = 符号赋值
变量定义之后,初始时没有进行賦值,内部有一个默认存储的值叫undefined〈未定义), 表示变量内部未赋值,可以存储数据了。
var userName;// 声明变量userName, 默认值是undefined
userName = "Jack";// 将字符串"Jack"赋值给变量userName
var userName2 = "Rose";// 声明变量userName2并赋值为"Rose"字符串
var a = 1,
b = 2,
c = 3;//一个var关键字声明多个变量并赋值
简单数据类型
null类型
null本身是个空对象指针,如果声明的变量将来用来存储对象,最好将该变量初始化为null
复杂数据类型
typeof()检测数据类型
console.log(typeof(1));
console.log(typeof("1"));
console.log(typeof(undefined));
console.log(typeof(true));
console.log(typeof(null));
变量的数据类型
JavaScript语言是一门动态类型的语言,变量并没有一个单独的数据类型,而是会随着内部存储数据的变化,数据类型也会发生变化。
- 变量的数据类型,与内部存储数据有关。
- 将来使用变量时,需要知道内部存储的数据是什么类型,避免程序出错。
var a = 1
console.log(typeof(a));//显示为number类型
a = "Hello"
console.log(typeof(a));//显示为string类型
数据类型转换
转换成字符串类型
- .toString()方法
console.log(true.toString());//将bool类型的true转换成字符串true
var a = 1;
console.log(a.toString());//将number类型的1转换成字符串1
- String()方法。有些值没有toString()方法,这个时候可以使用String()。比如:undefined和null
console.log(String(1));
console.log(String(undefined));
console.log(String(null));
- +号拼接字符串方式。num+"",当+两边一个操作符是字符串类型,一个操作符是其它类型的时候,会先把其它类型转换成字符串再进行字符串拼接,返回字符串。
console.log(String(1 + "是唯一,The One"));
转换成数字类型
- Number()方法
console.log(Number("123"));//显示数字123
console.log(Number(""));//显示数字0
console.log(Number(" "));//显示数字0
console.log(Number(true));//显示数字1
console.log(Number(false));//显示数字0
console.log(Number(undefined));//显示NaN
console.log(Number(null));//显示数字0
- parseInt()方法
字符串转整数的方法。
作用:第一,对浮点数进行取整操作;第二,将字符串转为整数数字。 - 对数字取整功能,直接舍弃小数部分,只保留整数。
- 字符串中,必须是纯数字字符串或者数字字符开头的字符串,才能转换为正常数字,且只取整数部分,如果不是数字打头的字符串,会转换为NaN
console.log(parseInt(123.34));//显示数字123
console.log(parseInt("123"));//显示数字123
console.log(parseInt("123.34"));//显示数字123
console.log(parseInt("123abc"));//显示数字123
console.log(parseInt("a123"));//显示NaN
console.log(parseInt(""));//显示NaN
- parseFloat()方法
字符串转浮点数的方法。
作用:将字符串转为浮点数数字。
要求:满足浮点数数字字符必须在字符串开始,如果不在开始返回值都是NaN。
应用
转换成bool类型
- Boolean()方法
Boolean()可以用于任何数据类型,将其他数据类型转为布尔类型的值。
转为false:NaN、0、""空字符串、null、undefined 转为true:非0非NaN数字、非空字符串
运算符
算术运算符
有特殊值字面量参与的运算:
- NaN参与的运算:得到的结果都是NaN
- lnfinity参与的运算,视情况而定。
工作中并不会使用特殊值运算,没有实际应用的意义,但是要了解,以防面试遇到。
隐式转换在进行数字运算时结果和使用Number()方法转换结果一样。
// 字符串参与
console.log(1 + "2");
console.log(1 - "2");
console.log(1 * "2");
console.log(1 / "2");
console.log(1 % "2");
console.log(1 - "");
console.log(1 - " ");
console.log(1 - "12abc");
// 其他数据类型参与
console.log(1 + true);
console.log(1 + false);
console.log(1 + undefined);
console.log(1 + null);
比较运算符
也叫关系运算符。运算结果是true或false。
特殊值参与比较运算:
- NaN参与, 不等于和不全等于结果是true,其他的都得到false
- lnfinity参与的运算,视情况而定 其他数据类型参与比较运算(排除字符串与字符串的比较):
- 其他数据类型也会隐式转换为数字参与比较。 "123" → 123 | true → 1 | false → 0 | null → 0 | undefined → NaN | "0abc” → NaN
- null的判断比较特殊:null与0判断时,相等判断为false,>=和<=判断为true
- null==undefined结果为true,因为undefined派生于空指针,值上和null是相等的
console.log(1 == "1");// true
console.log(1 == true);// true
console.log(0 == false);// true
console.log(0 == "");// true
console.log(0 == " ");// true
console.log(0 == undefined);// false
console.log(0 == null);// false
console.log(1 > null);// true
console.log(0 >= null);// true
console.log(0 <= null);// true
console.log(undefined == null);// true
字符串与字符串比较
console.log(6 < "12");// true
console.log("6" < "12");// false
console.log("A" < "12");// false
console.log("A" < "a");// true
console.log("banner" < "banana");// false
比较符运算顺序 从前往后比较,先得出前面的比较结果,再将结果和后面进行比较。
console.log(3 > 2 > 1);// 先运算3>2 得到 true ,再运算 true > 1 得到最终结果false
逻辑运算符
除了布尔类型的值之外,其他数据类型的值也可以参与逻辑运算。运算过程中需要将操作数隐式转换为布尔类型的值,参与判断计算,最终运算结果还是原来的某个位置的数据。
所以,并不是所有逻辑运算返回结果都是布尔值,其他数据参与得到的就是数据本身。
console.log(null && "123");// 结果null
console.log(12 && "123");// 结果123
console.log(12 || "123");// 结果12
console.log(undefined || null);// 结果null
// 非运算的运算结果只能是 true 或false
console.log(!9);// 结果是false
逻辑运算符运算顺序
- 同种运算符从前往后运算。
- 综合运算顺序:非、与、或。
赋值运算符
赋值运算符必须有变量参与运算,赋值运算符会做两件事情:
- 第一,将变量中原始值参与对应数学运算,与右侧的数据。
- 第二,将运算结果再重新赋值给变量。
变量位于操作符的左侧。
var a = 5;
a += 3; // 等价于 a = a + 3
console.log(a);// 输出为8
a *= 6; // 等价于 a = a * 6
console.log(a);// 输出为48
// 递加
console.log(a++);// 先调用a输出为48,再运算a++得到a为49
console.log(++a);// 先运算++a得到a为50,输出为50
console.log(a);// 输出为50
一元运算符
// 定义变量
var a = 10,b = 20,c = 30;
// 计算一个综合的算式
var num = a++ + ++b + c++ + ++a;
console.log(num);// 转换成(a+(b+1)+c+(a+1)),输出73
console.log(a);// 输出12
console.log(b);// 输出21
console.log(c);// 输出31
运算优先级
流程控制语句
条件分支语句
if语句
// 案例:让用户输入自己的考试成绩,反馈给他是否及格的结果
var s = parseFloat(prompt("请输入您的成绩","67"));
// 判断:超过60分及格
if (s >= 60) {
alert("恭喜你,你及格了");
} else {
alert("很遗憾,你没有及格");
}
多分支if语句
var s = parseFloat(prompt("请输入您的成绩","67"));
if (s >= 85) {
alert("优秀");
} else if (s >= 75)
alert("良好");
} else if (s >= 60)
alert("及格");
} else {
alert("不及格");
}
if语句嵌套
// 用户输入
var sex = prompt("请输入您的性别","男");
var age = parseInt(prompt("请输入您的年龄","45"));
if (sex === "男") {
// 男性,年龄需要大于60岁
if (age >= 60) {
alert("恭喜你,可以享受人生了")
} else {
alert("忍忍吧,还要坚持坚持");
}
} else {
// 女性,年龄需要大于55岁
if (age >= 55) {
alert("恭喜你,幸福人生开始了")
} else {
alert("太难了,还得继续坚持");
}
}
三元表达式
虽然if语句可以模拟三元表达式,但是三元表达式有自己的优点:
- 二选一的情况下,三元表达式结构更加筒单。
- 三元表达式作为一个表达式参与程序时必须运算出结果才能参与,可以利用这个特点,将二选一结果赋值给一个变量。 所以,遇到给一个变量根据条件二选一赋值的情况,可以使用三元表达式。
// 给变量赋值,根据条件二选一时,使用三元表达式更简单
var a = 4;
var b = a >= 5 ? 1 : 0;//先判断条件a>=5得到false,那么表达式值为0
console.log(b);//输出0
switch语句
注意事项:
// 用户输入
var xingzuo = prompt("请输入您的星座","白羊座");
// 进行匹配
switch (xingzuo) {
case "白羊座":
alert("运势持续在线,将会是忙而充实的一天。");
break;
case "金牛座":
alert("你或许需要付出更多的努力,才能实现自己的大志。");
break;
case "双子座":
alert("你的脾气比较大,容易把负面情绪波及到最亲近的人。");
break;
case "巨蟹座":
alert("人际关系会给你带来一些便利,善加把握会得到很多。");
break;
default:
alert("对不起,数据库不全,不能找到您的星座");
break;
}
// 案例2: 输出对应月份的天数
var month = parseInt(prompt("请输入一个月份的数字","1"));
// 输出对应的天数
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
alert("这个月有31天");
break;
case 2:
alert("这个月有28天或29天");
break;
default:
alert("这个月有30天");
}
条件分支语句总结
实际工作中使用三种语句的情景:
- if语句:最常用的语句,所有的判断情况都能够书写。
- 三元达式:多用于绐变量赋值根据条件二选一的情况。
- switch语句:多用于给一个表达式去匹配多种固定值可能性的情况。
循环语句
for循环
应该掌握for循环运行的一个轨迹、路径,自己去推导for循环运行的过程, 这样就可以实现任意的for循环了。如下图,是按①→②→③→④→②……②→⑤顺序执行的。
注意:
- 小括号内部必须有两个分号。
- for循环{}后面不需要加分号。
- 如果②位置语句不写,相当于没有设置入口条件,或者条件永远为真,没法限制什么时候停止循环了,出现死循环。
- ③位置是循环的结构体,每次进入循环都要执行完后,才能执行语句④,③位置的语句是可以人为自定义的,甚至可以书写if语句。
- for循环嵌套if语句:表示既要能执行循环,还要满足if语句的条件。
- for循环嵌套for循环:外层循环执行一次,内层循环作为外层③位置的结构体,必须执行完所有的内层循环,才能进入外层循环下一次的④。
- 循环内的变量是全局变量,必须避免循环嵌套时起相同的变量名,内层和外层变量名必须不同,常用的变量名i,j,k
// for 循环内部嵌套 for 循环
for (var i = 1 ; i <= 4 ; i++) {
for (var j = 5; j <= 8 ; j++) {
console.log(i,j);
}
}
do while循环
先执行后判断条件。
注意:
- 如果循环中需要循环变量参与,循环变量必须定义在循环外面,否则会被重置。如果将循环变量写在结构体内,i的初始值每次都会被重置,容易出现死循环。
- 循环变量自加的过程需要写在{}循环体内部。变量自加过程写在输出语句前面和后面,结果是不同的。
- dowhile循环即便条件第一次测试就为假,也会执行一次结构体。
// 输出1到10之间
var i = 1;
do {
i++;
console.log(i);
} while (i <= 0);
while循环
// 输出1到10之间的数字
var i = 1;
while (i <= 10) {
i++;
console.log(i);
}
循环总结:
- 遇到必须先执行一次结构体的循环,使用dowhile循环。
- 先测试入口条件的循环,可以选择for循环或while循环。
break语句
- break语句的作用可以立即停止当前(本层)的for、dowhile、while循环。
- 根据一些条件设置break位置,直到循环能够执行到break语句立即停止执行,跳出循环。
// 找到一个这样的数字,就说明存在,所以不需要往后面继续验证
for (var i = 1 ; i <= 50 ;i++) {
if (i % 5 == 0) {
console.log(i);
break;
}
}
// 如果想终止外层循环,需要给外层循环添加一个名字
waiceng : for (var i = 1 ; i <= 4; i++) {
for (var j = 1 ; j <= 4; j++) {
console.log(i,j);
// 补充打断条件
if (j >= 2) {
break waiceng;
}
}
}
continue语句
遇到continue表示当前的一次循环数据不是我们想要的,会立即停止当前次的循环,立即进入下一次循环。 注意:
- 要根据特殊条件设置continue的位置。
- continue如果没有特殊指示只能进入自己的下一次循环,不能立即停止外层循环的这一次进入下一次。
- 控制外层循环的方式与break一样,都是添外层的标签名。
// 找到 1-30 之间不是 5 的倍数的数字进行输出
for (var i = 1 ; i <= 30 ; i++) {
// 排除 5 的倍数
if (i % 5 == 0) {
// 说明是 5 的倍数,不要往下进行输出
continue;
}
// 能够执行到这里,说明不是 5 的倍数
console.log(i);
}
// continue 要控制外层循环,需要给外层循环添加标签名
waiceng : for (var i = 1 ; i <= 4; i++) {
for (var j = 1 ; j <= 4; j++) {
// 补充打断这一次条件
if (j % 2 == 0) {
continue waiceng;
}
console.log(i,j);
}
}
总结: break和continue这两个语句的出现可以帮助我们大量的优化代码,减少了计算机的计算次数。
穷举思想
制作方法:
- for循环:外层使用for循环进行一一列举。
- if语句:内层用if语句进行判断,筛选需要的数据,如果满足条件就操作数据,如果不满足条件跳过看下一次循环的数据。
累加器
- 有时候需要的不是每个数据是什么,需要得到所有数据的加和,必须想办法将所有的数据的和存起来,就用到了累加器。
- 累加器本质就是变量。
- 实现累加的效果,就是利用循环,每次循环就将新的数据加到原始的变量中去,赋值过程是一个加等于赋值。
// 求 1-10 之间所有数字的和
var n = 0;
// 循环累加所有的数字
for (var i = 1 ; i <= 10 ; i++) {
// 将每一次的数据 i 要累加到 n 中去
n += i;
// console.log(n);
}
// 循环结束后就可以使用最终的累加结果
console.log(n);
注意:
- 累加器必须定义在循环外面的前面,如果定义在循环内部,每次循环都会将累加器重置,不能实现累加
- 累加器的初始值必须设置,而且必须设置为0,不会影响累加结果
- 使用最终累加结果时,必须在for循环结束后的外面,如果写在循环内部,循环没结束,并不是最终需要的值。
累乘器
和累乘器十分相似。
// 求 10 的阶乘
// 累乘器,初始值必须是 1
var mul = 1;
for (var i = 10 ; i >= 1 ; i--) {
mul *= i;
}
// 循环结束后使用累乘结果
console.log(mul);
注意:
- 累乘器必须定义在循环外部前面。
- 累乘器的初始值必须是1,1乘以任何数都等于本身。
- 累乘器最终结果必须在for循环结束后使用。