前端学习路线图
先附上一张前端学习路线图:
一、JavaScript基础
(一) Javascript的定义
Javascript是一门跨平台、面向对象的脚本语言,来控制网页的行为,它可以实现网页的交互
网页由三部分构成:
- 结构:Html
- 表现:Css
- 行为:Javascript
(二)Javascript的作用
- 网页特效(监听用户的一些行为让网页作出对应反馈)
- 表单验证(针对表单数据的合法性进行判断)
- 数据交互(获取后台的数据,渲染到前端)
- 服务端编程(node.js)类似一个可以做后端编程的样子
(三)Javascript的组成
ECMAScript
规定了js基础语法核心知识
例如:变量,分支语句,循环语句,对象等等。
Web APIs
- DOM:操作文档 例如:对页面元素进行移动,调整大小,添加删除等操作
- BOM:操作浏览器 例如:页面弹窗,检测窗口宽度,存储数据到浏览器等等
(四)Javascript的书写位置
javascript包括行内javascript,内部javascript,外部javascript
1.内部javascript (平时用得多)
直接写在html文件里,用script标签包着
规范:script标签写在</body>上面
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一次JS的alert练习</title>
</head>
<body>
<script>
alert("你好JS")
</script>
</body>
</html>
效果图:
注意:
我们将<script>标签放在HTML文件的底部附近的原因是浏览器会按照代码在文中的顺序加载HTML。
必须前面的html和css生效才能有后面的js的行为的生效,对吧
2.外部javascript (以后开发代码多用)
代码写在以.js结尾的文件里
规范:通过script标签引入到html文件里
示范:写一个.js的文件引入到.html的文件中
注意:
1.script标签中间无需代码,否则会被忽略
2.外部js使代码更加有序,更易于复用,且没有了脚本的混合,HTML也会变得更加易读
3.内联javascript
代码写在标签内部
此处了解即可,但是后面VUE会用到这种模式
(五)Javascript的写法
1.注释怎么写
分为单行注释和块注释
(1)单行注释
- 符号://
- 作用:在注释符号的右侧一行被忽略
- 快捷键:ctrl+/
(2)块注释
- 符号:/**/
- 作用:注释符号的中间的所有内容被忽略
- 快捷键:shift+alt+a
2.结束符怎么写
- 作用:使用英文的 ; 代表语句结束
- 实际情况:实际开发中,可写可不写,浏览器(javascript引擎)可以自动推断语句的结束
- 现状:在实际开发中,越来越多的人主张省略结束符
- 约定:为了风格统一,结束符要么每句都写,要么每句都不写(按照团队要求)
(六)Javascript的输入输出语法
1.输出语法
语法1:
document.write("要输出的内容")
作用:向body输出内容
注意:如果输出的内容写的是标签也会被解析成元素
例如:
如果是内容没有标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一次JS的alert练习</title>
</head>
<body>
<script>
document.write('一级标题')
</script>
</body>
</html>
如果内容里加标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一次JS的alert练习</title>
</head>
<body>
<script>
document.write('<h1>一级标题</h1>')
</script>
</body>
</html>
语法2:
alert('要输出的内容')
作用:页面弹出警示框
语法3:
console.log('控制台打印')
作用:控制台输出语法,程序员调试使用
console 控制台 log 日志
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一次JS的alert练习</title>
</head>
<body>
<script>
console.log('看看我写的对不对')
</script>
</body>
</html>
效果
页面上啥也没有。。。。
控制台上出现我们写的内容,所以这个是给程序员用来调试的东西
2.输入语法
prompt('要输入的内容')
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一次JS的alert练习</title>
</head>
<body>
<script>
prompt('请输入您的年龄')
</script>
</body>
</html>
效果:
用于用户输入信息,之后我们后台可以拿到数据,虽然但是现在还没学到如何拿到数据。
3.代码执行顺序
- 按照HTML文档流顺序执行javascript代码
- alert()和prompt()它们会跳过页面渲染先被执行
4.字面量
在计算机中,字面量是在计算机中描述的事/物
例如:
1000 是 数字字面量
‘我在学JS’ 是 字符串字面量
{} 是 对象字面量
[] 是 数组字面量
(七)变量
1.变量的定义
变量是计算机存储数据的容器
注意:变量不是数据本身,它只是一个容器
2.变量的基本使用
(1)变量的声明
要想使用变量,首先要创建变量
语法:let 变量名
- 变量名分为两部分:声明关键字,变量名
- let是声明关键字
例如:
let age
声明了一个age变量,age即变量的名称也称标识符
(2)变量的赋值
定义一个变量,然后初始化它,在变量名后面加上一个“=”,然后就是数值
“=”称为赋值符号
示例:如下就可以实现创建变量,变量赋值,输出
let age
age = 18
document.write(age)
赋值符号的两侧有空格显的专业!变量名 = 赋值
let age = 18
let name = '张真源'
(3)更新变量
变量赋值后,还可以通过简单的给它一个不同的值来更新它
示例:
let age = 18
age = 20
document.write(age)
但是,注意:let不允许多次声明一个变量
如下,错误示范错错错错错错
let age = 18
let age = 20
document.write(age)
(4)声明多个变量
多个变量之间用逗号隔开
let name = '张真源',age = 18
不提倡这么写!为了更好的可读性,请一行只声明一个变量
3.交互两个变量
案例:
现在有两个变量,num1里面放的是10,num2里面放的是20
最后变成num1里面存的是20,num2里面存的是10
分析:
使用一个临时变量来做中间存储
步骤:
- 声明一个临时变量temp
- 把num1的值赋值给temp
- 把num2的值赋值给num1
- 再把temp的值赋值给num2
临时变量不用自动销毁
代码如下:达到结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一次JS的alert练习</title>
</head>
<body>
<script>
let num1 = 10
let num2 = 20
let temp
temp = num1
num1 = num2
num2 = temp
document.write(num1,num2)
</script>
</body>
</html>
4.变量的本质
变量的本质是程序在内存中申请的一块用来存放数据的小空间
5.变量的命名规范和规则
(1)规则:
- 不能用关键字
- 只能有下划线,字母,数字,特殊符号$,且数字不能开头
- 字母严格区分大小写
(2)规范:
- 起名要有意义(尽量用name,age,score等,不要用a1,a2这些)
- 遵守小驼峰命名法--第一个单词字母小写,后面每个单词首字母大写,例如userName
6.小案例
案例题目:
- 弹出输入框:请输入你的姓名: 用变量保存起来
- 弹出输入框:请输入你的年龄: 用变量保存起来
- 弹出输入框:请输入你的性别: 用变量保存起来
- 页面分别输出刚才的三个步骤
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一次JS的alert练习</title>
</head>
<body>
<script>
let uname = prompt('请输入你的姓名:')
let age = prompt('请输入你的年龄')
let gender = prompt('请输入你的性别')
document.write(uname,age,gender)
</script>
</body>
</html>
(八)数组
数组(Array):一种将一组数据存储在单个变量名下的方式
1.数组的基本使用
(1)声明语法
let 数组名 = [数据1,数据2,数据3...]
示例:
let arr = [‘马嘉祺’,‘丁程鑫’,‘宋亚轩’]
数组是顺序排列的,编号从0开始
在数组中,数据的编号叫做索引或者下标
数组可以存储任意类型的数据
例如我要打印出“丁程鑫”
示例:
let arr = [‘马嘉祺’,‘丁程鑫’,‘宋亚轩’]
document.write(arr[1])
(2)小案例
定义一个数组,里面存放星期一,星期二....星期日共七天,在页面上输出:星期日
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一次JS的alert练习</title>
</head>
<body>
<script>
let arr = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
document.write(arr[6])
</script>
</body>
</html>
注意,数据与数据之间,每个逗号后面有一个空格,显得专业
(3)一些术语
- 元素:数组中保存的每个数据叫做元素
- 下标:数组中数据的编号
- 长度:数组中数据的个数,通过数组的length属性获得
示例:打印数组的长度
let arr = [‘马嘉祺’,‘丁程鑫’,‘宋亚轩’]
document.write(arr.length)
(九)常量
- 概念:使用 const 声明的变量称为常量
- 使用场景:当某个变量永远不会改变的时候,可以使用const来声明,而不是let
- 命名规范:和变量保持一致
- 常量使用:
const g = 9.8
document.write(g)
注意:常量不允许重新赋值,声明的时候必须赋值(初始化)
(十)数据类型
1.数据类型
JS数据类型整体分为两大类:基本数据类型和引用数据类型
(1)数字型num
即我们数学中的数字,整数,小数,正数,负数。
JS是一门弱数据类型的语言,变量到底属于哪一种类型,只有赋值了之后,才能够确认
let num = -1.24
数字数据类型经常和算数运算符一起使用
算术运算符主要包括:加(+),减(—),乘(*),除(/),取余(%)
(2) 字符串型string
只要使用单引号,双引号或者反引号包裹的数据都叫字符串,单引号双引号没有本质的区别
推荐使用单引号 ('a')
let str = '张真源'
注意事项:
- 无论单引号或是双引号必须成对使用
- 单引号或双引号可以互相嵌套,但是不宜自己嵌套自己(建议:外双内单,外单内双)
- 必要时可以使用转义字符 \ ,输出单引号或者双引号
(i)字符串的拼接
+运算符 可以实现字符串的拼接
可以实现数字相加,代码示例如下:
let num1 = 10
let num2 = 20
document.write(num1 + num2)
// 输出结果为 3
可以实现字符相连,代码示例如下:
let str1 = 'hello大家好'
let str2 = '我是TNT时代少年团张真源'
document.write(str1 + str2)
// 输出结果是 hello大家好我是TNT时代少年团张真源
(ii)模板字符串
语法:
- 必须用 ``(反引号)
- 内容拼接变量时,用 ${} 来包住变量
如下是字符串拼接法与模板字符串法的代码比较:
// 输出“我叫张真源我今年20岁了”
字符串拼接法如下:
let name = '张真源'
let age = 20
document.write('我叫' + name + '我今年' + age + '岁了')
模板字符串法如下:
let name = '张真源'
let age = 20
document.write(`我叫${name}我今年${age}岁了`)
相对于字符串的拼接,模板字符串更简单
(3)布尔型boolean
表示肯定或者否定时在计算机中对应的是布尔类型数据,它有两个固定的值 true 和 false
true和false也是字面量
代码示例如下:
let num1 = 1
let num2 = 2
document.write(num1<num2)
// 输出结果为 true
document.write(1>2)
// 输出结果为 false
(4)未定义型undefined
未定义是比较特殊的类型,只有一个值undefined
(i)什么情况出现未定义类型
只声明变量,不赋值的情况下,变量的默认值为undefined,一般很少直接为某个变量赋值为undefined
代码示例如下:
let age // 声明但未赋值
document.write(age)
// 输出为 undefined
(ii)工作中使用的场景
我们开发中经常使用一个变量,等待传递过来的数据
如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,就判断用户是否有数据传递过来
(5)空类型null
js中的null仅仅是代表“无”“空”“值未知”
代码示例如下:
let age = null
document.write(age)
// 输出为 null
(i)null和undefined的区别
- undefined表示声明变量但未赋值
- null表示赋值了,只是内容为空
(ii)null 开发中的使用场景
把null作为尚未创建的对象
意思就是:将来会有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null
2.检测数据类型
通过 typeof 关键字检测数据类型
语法:
- 作为运算符:typeof x(常用的写法)
- 函数形式: typeof(x)
有括号没括号得到的结果都一样,所以我们直接使用运算符语法
代码示例如下:
let age = 3
document.write(typeof age)
// 输出为 number
let name = '张真源'
document.write(typeof name)
// 输出为 string
3.数据类型转换
(1)定义
把一种数据类型的变量转换为我们需要的数据类型的变量
(2)为什么需要类型转换
js是弱数据类型:js也不知道变量到底数据哪种数据类型,只有赋值了才清楚
坑:使用表单,prompt获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法计算
(3)分类
分为显式转换和隐式转换
(i)隐式转换
某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换被称为隐式转换
规则:
- +,—,*,/ 都会将字符串类型自动的转变为数字类型(常规规则)
- 当+两边都有数据时,而有一边是字符串类型,就会将另一边也转换成字符串类型(+的特殊规则)
代码示例如下 :
let num = +'123'
console.log(num)
// 输出结果: 123 数字类型
let name = '张真源'
console.log(name)
// 输出结果: 张真源 字符串类型
let name2 = +'张真源'
console.log(name2)
// 输出结果:NaN 意思是 not a number
let score = 98
console.log('张真源' + score)
// 输出结果: 张真源98 字符串类型
缺点:
转换类型不明确,靠经验才能总结
小技巧:
- + 号作为正号解析可以转换成数字型
- 任何数据和字符串相加结果都是字符串
(ii)显式转换
编写程序时过度依靠系统内部的隐式转换是不严谨的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常需要对数据进行显式转换
自己写代码告诉系统该转成什么类型
转换成数字型
- Number(数据)
转成数字类型
如果字符串内容里有非文字,转换失败时结果为NaN即不是一个数字
NaN也是number类型的数据,代表非数字
- parseInt(数据) 只保留整数
- parseFloat(数据)可以保留小数
4.小案例
输入两个数,计算两者之和,打印到页面中
let num1 = prompt('请输入你的第一个数:')
let num2 = prompt('请输入你的第二个数:')
num3 = Number(num1) + Number(num2)
alert(`您的计算结果是${num3}`)
(十一)运算符
运算符包括赋值运算符,一元运算符,比较运算符,逻辑运算符
1.赋值运算符
定义:对变量进行赋值的运算符
已经学过的赋值运算符:将等号右边的值赋予给左边,要求左边必须是一个容器
其他赋值运算符:+= ,-= , *= , /= ,%=
以+=为例,示例代码如下:上下两者等效
let num = 1
num += 1
console.log(num)
// 输出结果: 2
let num1 = 1
num1 = num1 + 1
console.log(num1)
// 输出结果: 2
2.一元运算符
js的运算符可以根据所需的表达式的个数
一元运算符:正负号
自增一元运算符
- 符号:++
- 作用:让变量的值加上自身
自减一元运算符
- 符号:--
- 作用:让变量的值减上自身
(1)自增的分类
自增分为前置自增和后置自增
自增运算符的使用场景 :经常用于计数来使用,用来计算多少次
(i)前置自增
let num = 1
++num
console.log(num)
// 输出结果: 2
(ii)后置自增
let num = 1
num++
console.log(num)
// 输出结果: 2
(2)前置自增和后置自增的区别
单独来看并没有区别,但是还是有区别的,区别如下
前置自增代码如下:
let num = 1
console.log(++num + 1)
// 输出结果: 3
后置自增代码如下:
let num = 1
console.log(num++ + 1)
// 输出结果: 2
++在前是先加,++在后是后加
注意:
- 前置自增和后置自增独立使用时,二者并没有差别
- 一般开发中我们都是独立使用的
- 后面 i++后置自增会使用的相对较多,并且都是单独使用
3.比较运算符
使用场景:比较两个数据的大小,判断是否相等
比较运算符:
- > : 左边是否大于右边
- < :左边是否小于右边
- >= : 左边是否大于等于右边
- <= : 左边是否大于等于右边
- == :左右两边值是否相等
- === : 左右两边是否类型和值都相等
- !== : 左右两边是否不全等
注意:
- = 是赋值
- == 是判断
- === 是全等
- 开发中判断是否相等,强烈推荐使用 ===
代码示例如下:
console.log(2 == 2)
// 结果为;true
console.log(2 == '2')
// 结果为;true
console.log(2 === '2')
// 结果为;false
console.log(2 === 2)
// 结果为;true
console.log(undefined === null)
// 结果为;false
console.log(null === null)
// 结果为;true
console.log(NaN === NaN)
// 结果为; false NaN不等于任何人,也不等于它自己
4.逻辑运算符
5.运算符优先级
运算符优先级判断运算符执行的顺序
- 一元运算符里面的逻辑非优先级很高
- 逻辑与比逻辑或优先级高
(十二)语句
1.表达式和语句
表达式定义:表达式是可以被求值的代码,js引擎会将其计算出一个结果
语句定义:语句是一段可以执行的代码
(1)表达式和语句的区别
表达式:因为表达式可以被求值,所以它可以写在赋值语句的右侧
例如: num = 3 +4
语句:而语句不一定有值,所以比如alert() for 和 break 等语句就不能被用于赋值
例如 :alert() console.log()
某些情况下,也可以把表达式理解为表达式语句,因为它是在计算结果,但不是必须的成分(例如continue语句)
2.分支语句
分支语句可以让我们有选择性的执行我们的代码
分支语句包含:
- if分支语句
- 三元运算符
- switch语句
(1) if 语句
if 语句有三种使用:单分支,双分支,多分支
(i)单分支
语法:
if (条件) {
满足条件要执行的代码
}
- 括号内的条件为true时,进入大括号里执行代码
- 小括号内的结果若不是布尔类型时,会发生隐式转换转成布尔类型
- 如果大括号只有一个语句,大括号可以省略,但不提倡!
代码示例如下:
if (2) {
console.log('执行语句')
}
// 结果为 :执行语句
if (0) {
console.log('执行语句')
}
//没结果
if ('张真源很帅') {
console.log('执行语句')
}
// 结果为 :执行语句
if ('') {
console.log('执行语句')
}
//没结果
if (2 == 2) {
console.log('执行语句')
}
// 结果为 :执行语句
if (2 == '2') {
console.log('执行语句')
}
// 结果为 :执行语句
if (2 === '2') {
console.log('执行语句')
}
// 无结果
结论:
- 除了 0 以外所有数字都为真
- 除了' '(空字符串)以外,所有字符串都为真
(ii)双分支
语法:
if (条件) {
满足条件要执行的代码1
} else {
不满足条件要执行的代码2
}
案例:判断闰年
闰年:能被4整除但不能被100整除,或者被400整除的年份是闰年,否则都是平年
代码如下:
let year = +prompt('请输入')
if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) {
alert(`${year}是闰年`)
}
else {
alert(`${year}不是闰年`)
}
(iii)多分支
语法:
if (条件1) {
代码1
} else if (条件2){
代码2
} else if (条件3){
代码3
} else {
代码n
}
(2)三元运算符
- 使用场景: 其实是比if双分支更简单的写法,可以使用三元运算符
- 符号 : ?和 :搭配使用
- 语法:
条件 ? 满足条件执行的代码 : 不满足条件执行的代码
代码示例如下:
console.log(3 < 5 ? 3 :5) //结果: 3
// 3<5吗 如果true 输出3,如果false ,输出5
适用于条件比较简单的分支
(3)switch语句
语法:
switch (数据) {
case 值1:
代码1
break
case 值2:
代码2
break
case 值3:
代码3
break
default:
代码n
break
}
(4)switch和if使用场景的区分
- switch 通常处理 case 为比较确定值的情况,而 if 通常用于范围判断。
- 当分支语句较少时用 if 语句效率更高,当分支语句较多时用 switch 语句效率较高结构更清晰。
3.循环语句
(1)while 循环
循环:重复执行一些操作
whille循环就是在满足条件期间,重复执行某些代码
语法:
while (循环条件) {
循环体
}
循环三要素:变量起始值,终止条件,变量变化量
代码示例如下:
let i = 1
while (i <= 3) {
document.write(`执行第${i}次`)
i++
}
(2)循环退出
break:退出循环
continue: 结束本次循环
(3)简易ATM案例
案例需求:
代码示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一次JS的alert练习</title>
</head>
<body>
<script>
let money = 100
while (true){
let re = +prompt(`
请你选择操作:
1.存钱
2.取钱
3.查看余额
4.退出
`)
if (re == 4) {
break
}
switch(re) {
case 1:
let cun = +prompt('请输入存款金额:')
money += cun
break
case 2:
let qu = +prompt('请输入取款金额:')
money -= qu
break
case 3:
alert(`你的账户余额是${money}`)
break
}
}
</script>
</body>
</html>
注意:只有模板字符串才可以多行不受格式限制写。
(4)for循环
(i)for循环的基本使用
作用:重复执行代码
好处:把声明起始值,循环条件,变化值写在一起,让人一目了然
语法:
for (变量起始值;终止条件;变量变化值){
循环体
}
代码示例如下:输出三遍‘张真源好帅’
<script>
for (let i = 1;i <= 3; i++){
document.write('张真源好帅')
}
</script>
求1-100之间的偶数和,代码示例如下:
<script>
let i
let sum = 0
for (i = 1; i <= 100; i++){
if (i%2 === 0) {
sum += i
}
}
document.write(sum)
</script>
(ii)循环数组
for循环最大的价值:循环数组
代码示例如下:
<script>
let tnt = ['mjq','dcx','syx','lyw','zzy','yhx','hjl']
for (let i = 0;i <= 6;i++) {
document.write(tnt[i])
}
</script>
(iii)循环嵌套
- for循环嵌套: 一个循环里面再套一个循环,一般用在for循环里
语法:
for (外部声明记录循环次数的变量;循环条件;变化值) {
for (内部声明记录循环次数的变量; 循环条件; 变化值) {
循环体
}
}
代码案例:
<script>
for (let day = 1; day <= 3; day++ ) {
document.write(`第${day}天<br/>`)
for (let word = 1; word <= 5; word++ ) {
document.write(`记住第${word}个单词<br/>`)
}
}
</script>
(十三)数组
1.数组是什么?
数组:(Array)是一种可以按顺序保存数据的数据类型
使用场景:如果有多个数据可以用数组保存起来,然后放到一个变量中,管理非常方便。
2.数组的基本使用
(1)声明语法
let 数组名 = [数据1,数据2,数据3...数据n]
let arr = new Array(数据1,数据2,数据3,数据4)
- 数组可以存储任意类型的数据
- 数组是按顺序存储的
代码示例:
<script>
let tnt = ['mjq','jcx','syx','lyw','zzy','yhx','hjl']
</script>
(2)取值语法
数组名[下标]
- 通过下标取数据
- 取出来的是什么类型的数据,就根据这种类型的数据类型特点来访问
代码示例:
<script>
let tnt = ['mjq','jcx','syx','lyw','zzy','yhx','hjl']
document.write(tnt[4])
// zzy
</script>
(3)遍历数组
用循环把数组中的每个元素都访问到,一般用for循环
语法:
for (let i = 0; i < 数组名.length; i++) {
数组名[i]
}
代码示例:
<script>
let tnt = ['mjq','jcx','syx','lyw','zzy','yhx','hjl']
for (let i = 0; i < tnt.length; i++){
document.write(tnt[i])
}
</script>
(4)数组小案例
(i)求数组[2,6,1,7,4]的和以及平均值
代码示例;
<script>
let arr = [2,6,1,7,4]
let sum = 0
for (let i = 0; i < 5; i++) {
sum += arr[i]
}
document.write(`和是${sum}<br>`)
document.write(`平均值是${sum / arr.length}`)
</script>
(ii)求数组[2,6,1,77,52,,25,7]的最大值
代码示例如下:
<script>
let arr = [2,6,1,77,52,25,7]
let max = 0
for (let i = 0; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i]
}
}
document.write(`数组的最大值是${max}`)
</script>
(5)数组的操作
增,删,改,查
(i)查
通过数组[下标]的方式访问数组数据
(ii)改
重新赋值就可以啦
代码示例如下:
<script>
let arr = ['mjq','dcx','syx']
arr[0] = 'lyw'
document.write(arr)
// 打印结果:lyw,dcx,syx
</script>
(iii)增
- arr.push() :将一个或多个元素添加到数组的末尾,并返回该数组的新长度
代码示例如下:
<script>
let arr = ['mjq','dcx','syx']
document.write(arr.push('lyw','zzy','yhx','hjl'))
// 打印结果:7
</script>
如上返回新数组的长度
<script>
let arr = ['mjq','dcx','syx']
arr.push('lyw','zzy','yhx','hjl')
document.write(arr)
// 打印结果:mjq,dcx,syx,lyw,zzy,yhx,hjl
</script>
- arr.unshift() :将一个或多个元素添加到数组的开头,并返回该数组的新长度
代码示例如下:
<script>
let arr = ['mjq','dcx','syx']
document.write(arr.unshift('lyw','zzy','yhx','hjl'))
// 打印结果:7
</script>
如上返回新数组的长度
<script>
let arr = ['mjq','dcx','syx']
arr.unshift('lyw','zzy','yhx','hjl')
document.write(arr)
// 打印结果:lyw,zzy,yhx,hjl,mjq,dcx,syx
</script>
(iv)删
- arr.pop()可以从数组中删除最后一个元素,并返回该元素的值
<script>
let arr = ['mjq','dcx','syx','lyw','zzy','yhx','hjl']
document.write(arr.pop())
//打印结果:hjl
</script>
<script>
let arr = ['mjq','dcx','syx','lyw','zzy','yhx','hjl']
arr.pop()
document.write(arr)
//打印结果:mjq,dcx,syx,lyw,zzy,yhx
</script>
- arr.shift()可以从数组中删除最后一个元素,并返回该元素的值
<script>
let arr = ['mjq','dcx','syx','lyw','zzy','yhx','hjl']
document.write(arr.shift())
//打印结果:mjq
</script>
<script>
let arr = ['mjq','dcx','syx','lyw','zzy','yhx','hjl']
arr.shift()
document.write(arr)
//打印结果:dcx,syx,lyw,zzy,yhx,hjl
</script>
- arr.splice()可以删除指定元素
语法:
arr.splice(start,deleteCount)
里面两个属性值start:起始位置,deleteCount:删除几个元素
代码示例:
<script>
let arr = ['mjq','dcx','syx','lyw','zzy','yhx','hjl']
arr.splice(1,3)
document.write(arr)
//打印结果:mjq,zzy,yhx,hjl
</script>
(6)数组筛选案例
筛选[2,0,6,1,77,0,52,0,25,7]数组中大于等于10的数,并将其放入一个新数组
代码示例如下:
<script>
let arr1 = [2,0,6,1,77,0,52,0,25,7]
let arr2 = []
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] >= 10) {
arr2.push(arr1[i])
}
}
document.write(arr2)
</script>
注意:
创建新数组时不要犯错,一定要创建空数组,空数组,不要忘了中括号,不然就是一个新变量
let arr2 = []
(十四)函数
1.为什么需要函数
function:是被设计为执行特定任务的代码块
这么做的优势是实现代码复用
2.函数使用
(1)函数的声明语法
function 函数名() {
函数体
}
代码示例如下:
<script>
function TNT() {
document.write('TNT时代少年团')
}
</script>
(2)函数的命名规范
- 和变量命名基本一致
- 尽量小驼峰式命名
- 前缀应为动词
常用动词如下:
(3)函数的调用语法
函数名()
代码示例如下:
function TNT() {
document.write('TNT时代少年团')
}
TNT()
TNT()
TNT()
TNT()
</script>
结果为四遍‘TNT时代团’
注意:函数不调用自己不执行
(4)函数的传参
(i)声明语法
function 函数名(参数列表){
函数体
}
参数列表:
- 传入数据的列表
- 声明这个函数需要传入几个数据
- 多个数据之间用逗号隔开
(ii)调用语法
函数名(传递的参数列表)
传入多个数据用逗号隔开
(iii)形参和实参
在函数声明时小括号里的是形参
在函数调用时小括号里的是实参
尽量保持形参和实参个数一致
(iv)函数默认值
形参:可以看做变量,可以不给值,默认为Undefined
如果用户不输入实参,Undefined+Undefined结果是NaN
改进如下:当用户不输入实参时,可以给出参数默认值,可以默认参数值为0,这样更严谨
function getSum(x = 0,y = 0) {
document.write(x + y)
}
getSum()
这个默认值只会在用户未输入实参时,才会使用默认参数值
(5)函数返回值
(i)返回值的概念
当调用某个函数,这个函数会返回一个结果给我们,这就是有返回值的函数
代码示例:
let result1 = prompt('请输入你的年龄') //有返回值返回一个年龄数据
let result2 = parseInt('12px') //有返回值返回一个数值12
alert('我是弹框不需要返回值') //无返回值直接显示弹框
有些函数有返回值,有些函数没有返回值
自己设定的函数要自己按照需求设定返回值
(ii)设定返回值
当函数需要返回数据出去时,用return关键字
语法:
return 数据
代码示例:
<script>
function getTotalPrice(x = 0,y = 0) {
return x + y
}
let re = getTotalPrice(1000,2000)
document.write(re)
</script>
(iii)函数返回值案例
求两个数的最大值并返回
代码示例如下:
function getMax(x = 0,y = 0) {
return x > y ? x : y
}
let re = getMax(1000,2000)
document.write(re)
求任意数组的最大值:
<script>
function getArrMax(arr=[]) {
let max = arr[0]
for (let i = 1;i < arr.length;i++) {
if (max < arr[i]){
max = arr[i]
}
}
return max
}
let arrmax = getArrMax([3,2,6,7,11,10])
document.write(arrmax)
</script>
(iv)函数细节补充
- 函数命名原则:当有多个函数名相同时,后面覆盖前面!
- 参数不匹配问题:当形参多余实参,多余的形参赋予undefined;当实参多余形参,剩余的实参不参与运算,自动忽略即可。
- 函数一旦碰到return就不会往下执行了,函数的结束用return。
当然上述问题最好避免!最好函数名不重复,参数个数匹配。
(6)作用域
一段代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字的冲突。
作用域分为全局作用域和局部作用域:
- 全局作用域:作用于整个代码执行的环境(整个script文件)
- 局部作用域:作用于函数内的代码环境,因为跟函数有关系,也叫函数作用域。
(7)变量的访问原则
- 只要是代码,就至少有一个作用域
- 写在函数内部的局部作用域
- 如果函数中还有函数,那么在这个作用域中又可以诞生一个作用域
- 访问原则:在能够访问到的情况下,局部没有再找全局
(8)匿名函数
没有名字的函数,无法直接使用。
函数分为具名函数和匿名函数
使用方法:函数表达式和立即执行函数
(i)函数表达式
将匿名函数赋值给一个变量,并通过变量名称进行调用,我们将这个称为函数表达式
代码示例如下:
<script>
let fn = function(x,y) {
document.write(x+y)
}
fn(1,2)
</script>
具名函数与匿名函数的不同:
具名函数的调用可以写在任何位置,匿名函数的调用必须要先写表达式赋值给变量之后才能调用。
使用场景:
后期webAPI会使用
(ii)立即执行函数(常用)
使用场景:避免全局变量之间的污染
立即执行函数必须要加分号!
写法1:
(function(){})();
代码示例如下:
<script>
(function(){
document.write('时代少年团')
})();
(function(){
document.write('TNT')
})();
</script>
最后一个小括号相当于调用函数
代码示例如下:
<script>
(function(x,y){
document.write(x+y)
})(1,2);
</script>
写法2:
(function(){}());
代码示例:
<script>
(function(x,y){document.write(x+y)}(1,2));
</script>
3.综合案例
用户输入秒数,可以自动转换成时分秒
代码示例如下:
<script>
let second = +prompt('请输入你想知道的秒数:')
function getCalculate(t){
h = parseInt(t/3600)
m = parseInt((t-3600*h)/60)
s = t-3600*h-60*m
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
return `转换完毕后是${h}小时${m}分${s}秒`
}
let re = getCalculate(second)
document.write(re)
</script>
这个案例注意:
- 取整用 parseInt ,这里 / 只代表除不代表取整!
- 还有局部变量可以不声明但是会变成全局变量。
- prompt默认是字符串类型
- +可以把字符串类型转化成数字类型
- +左右只要有一边是字符串类型,就会把另一边数字类型转化成字符串类型(字符串的拼接)
(十五)逻辑中断
<script>
function fn(x,y){
x = x || 0
y = y || 0
document.write(x+y)
}
fn()
</script>
以上写法属于逻辑中断,类似于形参的默认值
1.逻辑运算符里的短路
短路:只存在于&&和||中,当满足一定条件会让右边代码不执行
- && 左边为false就短路
- || 左边为true就短路
原因:通过左边能得到整个式子的结果,因此没必要再判断右边
(十六)对象
1.什么是对象
对象(object):一种数据类型
可以理解为一种无序的数据集合,可以详细的描述某个事物
2.对象使用
(1)对象声明语法
let 对象名 = {}
let 对象名 = new Object()
实际开发中多使用第一种写法,推荐第一种写法。
(2)对象由属性和方法组成
属性:信息或者特征--名词
方法:功能或者行为--动词
(3)属性
- 属性都是成对出现的,包括属性名和值,它们之间使用英文 ; 间隔
- 多个属性之间用英文 , 分隔
- 属性就是依附在对象上的变量
- 属性名可以使用''或者“”,一般情况下省略,除非名称遇到特殊符号如空格,中横线等
let obj = {
uname: '张真源',
gender: '男',
age: 20
}
(4)对象的增删改查
(i)查
语法一:对象.属性
代码示例:
let goods = {
name: '小米10青春版',
num: '100012816024',
weight: '0.55kg',
address: '中国大陆'
}
document.write(goods.name)
document.write(goods.num)
document.write(goods.weight)
语法二:对象名['属性名']
用了特殊字符只能用这种方法来写,属性名为字符串时
后面常用到这一种方法
代码示例如下:
let goods = {
name: '小米10青春版',
num: '100012816024',
weight: '0.55kg',
address: '中国大陆',
'quality-yn':'合格'
}
document.write(goods['quality-yn'])
// 执行结果为 合格
属性名必须要加引号
(ii)改
语法:对象.属性名 = 新的属性值
代码示例:
let goods = {
name: '小米10青春版',
num: '100012816024',
weight: '0.55kg',
address: '中国大陆'
}
goods.address = '中国台湾'
document.write(goods.address)
(iii)增
语法:对象.属性名 = 新的属性值
let goods = {
name: '小米10青春版',
num: '100012816024',
weight: '0.55kg',
address: '中国大陆'
}
goods.quality = '合格'
document.write(goods.quality)
(iv)删(了解)
语法:delete 对象.属性名
代码示例:
let goods = {
name: '小米10青春版',
num: '100012816024',
weight: '0.55kg',
address: '中国大陆'
}
delete goods.weight
document.write(goods.weight)
// 执行结果 :undefined
(5)方法
- 数据行为性的信息称为方法
- 方法是由方法名和函数两部分构成,它们之间用 : 分隔
- 多个属性之间使用英文 , 分隔
- 方法是依附在对象中的函数
- 方法名可以使用“”或 ‘’,一般情况下省略,除非名称遇到特殊符号如空格,中横线等
调用:对象名.方法名()
代码示例如下:
let obj = {
uname: '张真源',
song: function () {
document.write('蝴蝶')
}
}
obj.song()
// 执行结果为 :蝴蝶
注意:对象外面的叫函数,对象里面的叫方法
3.遍历对象
前提:对象是无序的,无法用数组的有序下标进行遍历
解决: for .... in..
代码示例:
let obj = {
uname: '张真源',
song: '蝴蝶',
gender: '男',
age: 20
}
for (let k in obj) {
//document.write(k) // 执行结果是 属性名 'uname' 'song' 'gender' 'age'
// 可以得到字符串的属性名
//正常的document.write(obj.uname),但document.write(obj.k)相当于document.write(obj.'uname')
//错误但我们还有另一种查的方法document.write(obj['uname'])
document.write(obj[k])
// 执行结果 :张真源 蝴蝶 男 20
}
知识点:
- for in 语法中的k是一个变量,在循环的过程中依次代表对象的属性名
- 由于k是变量,所以必须使用 [ ] 语法解析
- 一定记住:k是获得对象的属性名,对象[k]是获得属性值
4.内置对象
(1)内置对象是什么
JavaScript内部提供的对象,包含各种属性和方法给开发者调用
(2)内置对象Math
- 介绍:Math对象是JavaScript提供的一个“数学”对象
- 作用:提供了一系列做数学运算的方法
- Math对象包含的方法有:random(生成0-1之间的随机数,包含0不包括1),ceil(向上取整),floor(向下取整),round(四舍五入),max,min,pow(幂运算),abs(绝对值)等等
想要了解更多math函数 ,可以登录“mdn”网站查看更多
代码示例:
<script>
console.log(Math.ceil(1.1))
// 执行结果: 2
console.log(Math.floor(2.9))
// 执行结果: 2
console.log(Math.max(1,3,11,6))
// 执行结果: 11
console.log(Math.min(1,3,11,6))
// 执行结果: 1
console.log(Math.pow(2,3))
// 执行结果: 8 2的3次方
console.log(Math.abs(-11.23))
//执行结果: 11.23 绝对值
</script>
(3)生成任意范围随机数
- Math.random() 是随机数函数,返回0-1之间,并且包括0不包括1的随机小数[0,1)
(i)如何取0-10之间的随机数
Math.floor(Math.random()*(10+1))
0-10之间的随机整数,包括0,10
(ii)如何取5-10之间的随机数
Math.floor(Math.random()*(5+1))+5
(iii)如何取N-M之间的随机数
Math.floor(Math.random()*(M-N+1))+N
可以看做一个函数,如下:
function getRandom(N,M) {
return Math.floor(Math.random()*(N-M+1))+N
}
后面使用时,可以直接复制这段代码取实参就行
(iv)小案例
<script>
let arr = ['red','green','blue','pink']
let random = Math.floor(Math.random()*4)
console.log(arr[random])
</script>
(4)案例---猜数字游戏
需求:程序随机生成1-10之间的1一个数字,用户输入一个数字:如果大于该数字,就提示,数字猜大了,继续猜;如果小于该数字,就提示,数字猜小了,继续猜;如果猜对了,就提示猜对了,程序结束。
代码示例:
<script>
function getRandom(N,M) {
return Math.floor(Math.random()*(M-N+1))+N
}
let random = getRandom(1,10)
console.log(random)
while(true){
let num = +prompt('请输入你猜的数字:')
if (num > random) {
alert('你猜大了')
}else if (num < random) {
alert('你猜小了')
}else {
alert('恭喜你,你猜对了')
break
}
}
</script>
(5)案例---随机颜色案例
需求:该函数接收一个布尔类型参数,表示颜色的格式是1十六进制还是rgb格式:如果参数传递的是true或者无参数,则输出一个随机十六进制的颜色;如果参数传递的是false,则输出一个随机rgb的颜色
提示:16进制颜色格式为:‘#ffffff’其中f可以是任意0-f之间的字符,rgb颜色格式为:‘rgb(255,255,255)’其中255可以是任意0-255之间的数字
代码示例:
<script>
function getRandomColor(flag=true) {
if (flag) {
let str = '#'
let arr = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
for (let i = 1;i <= 6;i++) {
let random = Math.floor(Math.random()*arr.length)
str += arr[random]
}
return str
}else {
let r = Math.floor(Math.random()*256)
let g = Math.floor(Math.random()*256)
let b = Math.floor(Math.random()*256)
return `rgb(${r},${g},${b})`
}
}
console.log(getRandomColor(true))
console.log(getRandomColor(false))
console.log(getRandomColor())
</script>
(6)补充
堆栈空间分配区别:
栈:由操作系统自动分配释放存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈,简单数据类型存放到栈里面
堆:存储复杂类型,一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。引用数据类型存放到堆里面
二、Web APIs
(一)Web APIs的基本认知
1.变量声明
建议用const,尽量用const,数组和对象使用const来声明
原因是:
- const语义化更好
- 很多变量我们声明的时候就知道他不会被更改了,就直接使用const
- 实际开发中,比如react框架,基本用const
- 有了变量先给const,如果发现它后面是要被更改,再改为const
注意:什么时候可以用const,什么时候不能用const
- const声明的值不能更改,而是const声明变量的时候需要里面进行初始化
- 但是对于引用数据类型,const声明的变量,里面存的不是值,是地址
2.作用和分类
- 作用:就是使用JS去操作HTML和浏览器
- 分类:DOM(文档对象模型),BOM(浏览器对象模型)
3.什么是DOM
- DOM(Document Object Model--文档对象模型)是用来呈现以及与任意html或xml文档交互的API
- 白话文:DOM是浏览器提供的一套专门用来操作网页内容的功能
- DOM作用:开发网页内容特效和实现用户交互
4.DOM树
- 将html文档以树状结构直观的表现出来,我们称之为文档树或者DOM树
- 描述网页内容关系的名词
- 作用:文档树直观的体现了标签与标签之间的关系