一、ECMAScript(JS基础)
1.简介
1.1定义和作用
是一种运行在客户端(浏览器)的编程语言,实现人机交互
组成:ECMAScript(JavaScript语言基础)、Web APIs(DOM(页面文档对象模型)、BOM(浏览器对象模型))
作用:网页特效(监听用户的一些行为让网页作出对应的反馈)、表单验证(针对表单数据的合法性进行判断)、数据交互(获取后台的数据渲染到前端)、服务端编程(node.js)
1.2书写位置(同CSS)
1.2.1 内部JavaScript
直接写在html文件里,用script标签包住
<body>
<script>
alert('警告')
</script>
</body>
1.2.2 外部JavaScript
代码写在以.js结尾的文件里,通过script标签引入html页面中
<script src="./js/my.js">
//不写语句,不生效
</script>
1.2.3 内联JavaScript
代码写在标签内部,VUE使用这种模式
<body>
<button onclick="alert('逗你玩---')">点击我</button>
</body>
1.3注释与结束符
单行注释;//,ctrl+/
块注释:/**/,shift+alt+a
结束符:;可写可不写,浏览器自动推断语句结束位置,要么全写要么都不写
必须要加分号的情况
`立即执行函数`(function () { })();
`使用数组解构`
let a = 1
let b = 2
;[b, a] = [a, b]
1.4 输入与输出语法
输出语法1:向body内输出内容,输出内容写标签也会解析为网络元素
<script>
document.write('我是div标签')
document.write('<h1>我是标题</h1>')
</script>
输出语法2:页面弹出警示对话框,标签不会解析,可以通过反引号直接原格式写进括号内,输出就是什么样
/*框内只有确认按钮*/
alert('内容')
输出语法3:控制台打印
console.log('控制台打印')
输入语法:显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字
/*框内有确认和取消按钮*/
prompt('请输入您的年龄:')
⭐html文档流顺序执行JavaScript代码,alert()和prompt()会跳过页面渲染先被执行
1.5 字面量
字面量(literal)是在计算机中描述的事物,如数字字面量,字符串字面量,数组字面量,对象字面量
1.6 script传值html
//1.通过搜索类名
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
table{
width: 1000px;
height: 100px;
border: 1px solid #000;
border-collapse:collapse;
}
th,td {
border: 1px solid #000;
width: 200px;
height: 50px;
text-align: center;
}
</style>
</head>
<body>
<table>
<caption>
<h1>订单确认</h1>
</caption>
<tr>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th>总价</th>
<th>收货地址</th>
</tr>
<tr>
<td>小米手机青春PLUS</td>
<td class="Price"></td>
<td class="Number"></td>
<td class="Total"></td>
<td class="Address"></td>
</tr>
</table>
<script>
let priceData = prompt('请输入商品单价')
let numData = prompt('请输入商品数量')
let totalData = priceData * numData
let addressData = prompt('请输入收货地址')
document.querySelector('.Price').innerHTML = priceData+'元'
document.querySelector('.Number').innerHTML = numData
document.querySelector('.Total').innerHTML = totalData+'元'
document.querySelector('.Address').innerHTML = addressData
</script>
</body>
//2.直接写进script,可以解析标签
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
table {
width: 200px;
height: 100px;
border: 1px solid black;
border-collapse: collapse;
}
td,th,caption {
border: 1px solid black;
text-align: center;
width: 200px;
}
</style>
</head>
<body>
<script>
let amount = prompt("请输入银行卡余额:")
let ele = prompt("请输入本月电费:")
let water = prompt("请输入本月水费:")
let Inter = prompt("请输入本月网费:")
let total = Number(ele) + Number(water) + Number(Inter)
let monny = amount - total
document.write(`
<table>
<caption><h3>账单</h3></caption>
<tr>
<th>本月电费:</th>
<td>${ele}元</td>
</tr>
<tr>
<th>本月水费:</th>
<td>${water}元</td>
</tr>
<tr>
<th>本月网费:</th>
<td>${Inter}元</td>
</tr>
<tr>
<th>本月总消费:</th>
<td>${total}元</td>
</tr>
<tr>
<th>银行卡剩余:</th>
<td>${monny}元</td>
</tr>
</table>`)
</script>
//3.若想改变style值,可以使用CSS行内式
//生成柱状图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 700px;
height: 300px;
border-left: 1px solid black;
border-bottom: 1px solid black;
display: flex;
margin:50px auto;
justify-content: space-around;
align-items: flex-end;
text-align: center;
}
.box>div{
width: 50px;
background-color: pink;
display: flex;
justify-content: space-between;
flex-direction: column;
}
.box div span{
margin-top: -20px;
}
.box div h4{
margin-bottom: -35px;
width: 70px;
margin-left: -10px;
}
</style>
</head>
<body>
<script>
let data = []
for(let i=0;i<4;i++){
data.push(prompt(`请输入第${i+1}个数据`))
}
document.write('<div class="box">')
for (let i=0;i<data.length;i++){
document.write(`
<div style="height: ${data[i]}px;">
<span>${data[i]}</span>
<h4>第${i+1}季度</h4>
</div>
`)
}
document.write('</div>')
</script>
</body>
</html>
2.变量与常量
变量:(1)定义:存储数据的’容器‘
(2)本质:是程序在内存中申请的一块用来存放数据的小空间
(3)命名规则与规范:规则必须遵守,规范为建议
规则:不能用关键字,如let,var,if,for;只能用下划线、字母、数字、$组成,数字不能开头;字母严格区分大小写
规范:起名有意义;小驼峰命名法(第一个单词首字母小写,后面首单词大写)
(4)基本使用:
//1.声明变量:let是关键字,即系统提供的专门用来声明变量的词语
let 变量名
//2.变量赋值:
变量名 = 值
//3.声明同时赋值
let 变量名 = 值
//4.变量更新:重新赋值,不能再次加let,重复声明了
let age=18
//5.声明多个变量:为了可读性,最好分开写
let age = 18,uname = 'Tom'
age=19
//6.使用数组:将一组数据存在单个变量名下
let 变量名 = []
console.log(变量名[下标])
⭐let和var的区别:旧JavaScript中使用var来声明,var可以先使用再声明,且可以重复声明,没有块级作用域,let解决var的这些问题
常量:某个值永远不会变时,使用const声明,如const G=9.8
常量不允许重新赋值,声明的时候必须赋值
复杂数据类型增删改查地址不变所以允许使用const,但是重新赋值其他数组改变对象会报错
常量值为对象时其属性和方法允许重新赋值。
3.关键字、标识符和保留字
术语 | 关键字 | 保留字 | 标识符 |
---|---|---|---|
解释 | js中有特殊意义的词汇 | js中无意义,但将来可能会有特殊意义 | 变量名、函数名的另一种叫法 |
举例 | let,var,function,if,else,switch,case,break | int,short,long,char | 无 |
4.数据类型
4.1 基本数据类型/简单类型/值类型
在存储时变量中存储的是值本身,栈空间中由操作系统自动分配释放存取函数的参数值,局部变量等
⭐js是一种弱数据类型语言,赋值时才知道是什么类型,表单、prompt获取数据默认是字符串类型
⭐控制台数字和布尔类型是蓝色,字符串和underfined为灰色
⭐typeof关键字检测数据类型:typeof x(常用)或者typeof(x)
number数字型:常与算数运算符联合使用,优先级左往右;计算报错NAN(not a number),NaN是粘性的,任何对NAN的操作都会返回NaN
string字符串型:双引和单引无本质上的区别,推荐用单引号;
反引号``创建多行而无需用+号;
引号前加\反义符号可以输出引号,+可以数字相加\字符相连;
单双引号可以互相嵌套但是不可以自己嵌套自己;
模板字符串:反引号包含${};
有字符串的加法:如果其中一个操作数为字符串那么JS会将另一个操作数也转换为字符串,例如""+1="1";
有字符串的减法:JS会尝试将两个操作数都转换为数字,空字符串为0,如果有一个操作数无法转为数字那么结果将是NAN,例如""-2=-2
boolean布尔型:true/false,通过Boolean()转换布尔类型中’‘、0、undefined、null、false、NAN都是false,其余都为true
undefined未定义型:只有一个值underfined,只声明变量不赋值的情况下出现,工作中常用于通过检测变量是否为underfined,判断用户是否有数据传输过来
underfined+underfined=NAN,
underfined经数字转换为NAN,例如uderfined+3=NAN
null空类型:underfined表示没有赋值,null表示赋值了但内容为空,常作为尚未创建的对象
null经数字转换为0,例如null+3=3
4.2 引用数据类型/复杂类型
在存储变量中存储的仅仅是地址引用,堆栈空间中由程序员分配释放,若程序员不释放,由垃圾回收机制回收,栈中放地址,真正对象放堆中
object 对象
5.数据转换
5.1 隐式转换
某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。
任何数据和字符串相加结果都是字符串,+作为正号解析则转为数字型,除了+以外的算数运算符都会转成数字类型
typeof '123'//string
typeof +'123'//number
null==undefined//true
null===undefined//false
5.2 显示转换
编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。
5.2.1 Number数值类型
通过 Number
显示转换成数值类型,当转换失败时结果为 NaN
(Not a Number)即不是一个数字。
<script>
let t = '12'
let f = 8
// 显式将字符串 12 转换成数值 12
t = Number(t)
// 结果为 20
console.log(t + f)
// 并不是所有的值都可以被转成数值类型
let str = 'hello'
// 将 hello 转成数值是不现实的,当无法转换成
// 数值时,得到的结果为 NaN (Not a Number)
console.log(Number(str))
</script>
parseInt只保留整数, parseFloat可以保留小数,toFixed指定保留小数位数
5.2.2 字符型
String(数据)
变量.toString(进制)
let myNumber = 11
let stringNunberOne = String(myNumber)
let stringNunberTwo = myNumber.toString(2)
6. 运算符
(1)赋值运算符:+=,-=,*=,/=,%=
(2)一元运算符:++num,num++ ;前置和后置单独使用时无区别,后置++用的比较多
(3)比较运算符:>,<,>=,<=,==,===(值和类型都等,开发推荐使用),!==;涉及到NAN都是false,NAN不等同于任何值包括自己;尽量不要比较小数,有精度问题;不同类型之间比较会发生隐式转换,最终为number
(4)逻辑运算符:&&,||,!
⭐运算符优先级(高到低):小括号(()),一元运算符(++,--,!),算术运算符(先*/%后+-),关系运算符(>,>=,<,<=),相等运算符(==,!=,===,!==),逻辑运算符(先&&后||),赋值运算符(=),逗号运算符(,)
⭐逻辑短路:&&左false短路,||左true短路
7. 语句
⭐表达式和语句
语句是一段可以执行的代码,不一定有值,比如alert(),for,break就不能被用于赋值
表达式可被求值,写在赋值语句右侧
⭐断点调试:学习时可以帮助更好的理解代码运行,工作时可以更快找到bug,在某句代码上加的标记就叫断点,当程序执行到这句有标记的代码时会暂停下来
浏览器打开调试界面
-
按F12打开开发者工具
-
点到源代码一栏 ( sources )
-
选择代码文件
7.1 分支语句
if分支语句(**重点):小括号内的结果若不是布尔类型时,会发生类型转换为布尔值,类似Boolean()
//单分支
if(条件表达式) {
// 满足条件要执行的语句
}
//双分支
if(条件表达式) {
// 满足条件要执行的语句
}else{
//不满足条件要执行的语句
}
//多分支
if(条件表达式) {
}else if(条件表达式) {
}else{
}
三元运算符:? 与 : 配合使用, 一些简单的双分支,可以使用 三元运算符(三元表达式),写起来比 if else双分支 更简单`
条件 ? 表达式1 : 表达式2
switch语句:适合于有多个条件的时候,也属于分支语句,大部分情况下和 if多分支语句 功能相同
//switch case语句一般用于等值判断, if适合于区间判断
//switch case一般需要配合break关键字使用 没有break会造成case穿透
//if 多分支语句开发要比switch更重要,使用也更多
//===不全等则执行default
switch (表达式) {
case 值1:
代码1
break
case 值2:
代码2
break
...
default:
代码n
}
7.2 循环语句
while循环
//循环三要素:1.初始值 (经常用变量)2.终止条件3.变量的变化量
//`break` 中止整个循环,一般用于结果已经得到, 后续的循环不需要的时候可以使用(提高效率)
//`continue` 中止本次循环,一般用于排除或者跳过某一个选项的时候
while (条件表达式) {
// 循环体
}
无限循环
/* 需求: 页面会一直弹窗询问你爱我吗?
(1). 如果用户输入的是 '爱',则退出弹窗
(2). 否则一直弹窗询问*/
//1.while(true) 来构造“无限”循环,需要使用break退出循环。(常用)
while (true) {
let love = prompt('你爱我吗?')
if (love === '爱') {
break
//2.for(;;) 也可以来构造“无限”循环,同样需要使用break退出循环。
for (; ;) {
let love = prompt('你爱我吗?')
if (love === '爱') {
break
}
}
for循环
for(变量起始值;终止条件;变量变化量){
//循环体
}
8 数组
数组:(Array)是一种可以按顺序保存数据的数据类型,属于对象类型
数据单元值类型:数组做为数据的集合,它的单元值可以是任意数据类型
使用场景:如果有多个数据可以用数组保存起来,然后放到一个变量中,管理非常方便
//1.声明语法:下标从0开始
let 数组名 = [数据1,数据2...]
let arr = new Array(数据1,数据2...)
//2.遍历数组:for循环
//3.增:
arr.push(新增内容)动态向数组的尾部添加一个单元
arr.unshift(新增内容)动态向数组头部添加一个单元
//4.删:
arr.pop()删除最后一个单元
arr.shift()删除第一个单元
arr.splice(操作的下标,删除的个数)动态删除任意单元
//5.改:重新赋值:数组名[下标]=值
//6.查:数组名[下标]
//7.排序:sort()方法
默认升序arr.sort(function(a,b){return a-b})
降序arr.sort(function(a,b){return b-a})
//8.冒泡排序
<script>
let arr = [1, 5, 3, 7, 9, 2, 4, 6, 8, 0]
for (let i = 0; i < arr.length - 1; i++) {
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
let temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
console.log(arr)
</script>
8.1 map方法
map 可以遍历数组处理数据,并且返回新的数组
map 也称为映射。映射是个术语,指两个元素的集之间元素相互“对应”的关系。
map重点在于有返回值,forEach没有返回值(undefined)
<body>
<script>
const arr = ['red', 'blue', 'pink']
// 1. 数组 map方法 处理数据并且 返回一个数组
const newArr = arr.map(function (ele, index) {
// console.log(ele) // 数组元素
// console.log(index) // 索引号
return ele + '颜色'
})
console.log(newArr)
</script>
</body>
8.2 join方法
join() 方法用于把数组中的所有元素转换一个字符串
// 小括号为空则逗号分割
console.log(newArr.join()) // red颜色,blue颜色,pink颜色
// 小括号是空字符串,则元素之间没有分隔符
console.log(newArr.join('')) //red颜色blue颜色pink颜色
console.log(newArr.join('|')) //red颜色|blue颜色|pink颜色
8.3 forEach遍历数组
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数
注意:
1.forEach 主要是遍历数组
2.参数当前数组元素是必须要写的, 索引号可选。
<body>
<script>
// forEach 就是遍历 加强版的for循环 适合于遍历数组对象
const arr = ['red', 'green', 'pink']
const result = arr.forEach(function (item, index) {
console.log(item) // 数组元素 red green pink
console.log(index) // 索引号
})
// console.log(result)
</script>
</body>
8.4 filter筛选数组
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
主要使用场景: 筛选数组符合条件的元素,并返回筛选之后元素的新数组
<body>
<script>
const arr = [10, 20, 30]
// const newArr = arr.filter(function (item, index) {
// // console.log(item)
// // console.log(index)
// return item >= 20
// })
// 返回的符合条件的新数组
const newArr = arr.filter(item => item >= 20)
console.log(newArr)
</scr