截图软件: Snipaste
f1:截图(or fn+f1)
f3:定在屏幕上 (or fn+f3)
取色:shift切换
fn+esc:锁定功能键
画笔工具:
Ctrl +1 放大
Ctrl + 2 画图
画图的时候按住ctrl是矩形
画图的时候按住tab是椭圆
画图的时候按字母可以改变颜色:r 红色 b 蓝色 g 绿色 p 粉色 o 橙色
思维导图软件:XMind 8 Update 9
enter 同级
tab 下级
新建:创建
vscode插件:Easy LESS 语法报错检查,比如说同一个变量我用了两次let声明,并赋给不同的值
保存时格式化以及代码缩进两个字符 设置 -> 文本编辑器 -> 格式化 设置-> 常用设置 -> Editor:Tab Size -> 改为2
Live Server插件
基础语法
JavaScript 书写位置
1.内部 JavaScript
规范
:script标签写在</body>上面
我们将 <script> 放在
HTML文件的底部
附近的原因是浏览器会按照代码在文件中的
顺序加载
HTML。
如果先加载的 JavaScript 期望修改其下方的 HTML,那么它可能由于 HTML 尚未被加载而失效。
因此,将 JavaScript 代码放在 HTML页面的底部附近通常是最好的策略
2.外部 JavaScript
语法:
通过script标签,引入到html页面中。
![](https://img-blog.csdnimg.cn/direct/5f28e1041c7f4f69aaa332e4825bdd70.png)
1. script标签中间无需写代码,否则会被忽略!
2.
外部JavaScript会使代码更加有序,更易于复用,且没有了脚本的混合,
HTML 也会更加易读,因此这是个好的习惯。
3.代码比较多,就写在外部
3.内联 JavaScript
代码写在标签内部
语法:
![](https://img-blog.csdnimg.cn/direct/d174dc4436f146f190ce78ad222e284d.png)
注释
单行注释
符号:
//
作用:
//右边这一行的代码会被忽略
快捷键:
ctrl + /
块注释
符号:
/* */
作用:
在/* 和 */ 之间的所有内容都会被忽略
快捷键:
shift + alt + A
JavaScript结束符(
分号 ;
)可写可不写
JavaScript 输入输出语法
// 1. 文档输出内容
document.write('我是div标签')
// 2. 控制台打印输出 给 程序员
console.log('看看对不对')
// 弹窗
alert('你好')
// 3. 输入语句
prompt('请输入您的年龄:')
变量
目标:理解变量是计算机存储数据的“
容器
变量不是数据本身,它们仅仅是一个用于存储数值的容器。可以理解为是一个个用来装东西的纸箱子。
不提倡同时声明多个不同的变量
![](https://img-blog.csdnimg.cn/direct/d7374ec913b0425789d0d64b1e4bc28a.png)
// 3. 声明的同时直接赋值 变量的初始化
let age = 18
// let 不允许多次声明一个变量。会报错
let num = 20
let num = 23
![](https://img-blog.csdnimg.cn/direct/1498f4bc65a14789abf2d8620d0c6d76.png)
是通过
变量名
来获得变量里面的数据
// 输出用户名案例
// 1. 用户输入
// prompt('请输入姓名')
// 2. 内部处理保存数据
let uname = prompt('请输入姓名')
// 3. 打印输出
document.write(uname)
// 交换变量的值
// let if = 10 // 报错
let num1 = 'pink老师'
let num2 = '戚薇'
let temp
// 都是把右边给左边
temp = num1
num1 = num2
num2 = temp
console.log(num1, num2)
变量命名规则与规范
1. 规则:
不能用关键字
关键字:有特殊含义的字符,JavaScript 内置的一些英语词汇。例如:let、var、if、for等
只能用下划线、字母、数字、$组成,且
数字不能开头
字母严格
区分大小写
,如 Age 和 age 是不同的变量
2. 规范:
起名要有意义
遵守
小驼峰命名法
第一个单词首字母小写,后面每个单词首字母大写。例:userName
var 声明:
可以先使用 在声明 (不合理)
var 声明过的变量可以重复声明(不合理)
比如变量提升、全局变量、没有块级作用域等等
!! 不推荐
数组
在数组中,数据的编号也叫
索引或下标
// 2. 使用数组 数组名[索引号] 从0
// console.log(arr)
console.log(arr[0]) // 刘德华
console.log(arr[4])
// 3. 数组长度 = 索引号 + 1
console.log(arr.length) // 6
![](https://img-blog.csdnimg.cn/direct/060edc4730c14f51ba5965e631a65e12.png)
常量
概念:
使用 const 声明的变量称为“常量”。
使用场景:
当某个变量永远
不会改变
的时候,就可以使用 const 来声明,而不是let。
注意:
常量不允许重新赋值,声明的时候必须赋值(初始化)
![](https://img-blog.csdnimg.cn/direct/191fe3aed1a04cf59b7860ec96b6847e.png)
小技巧:
不需要重新赋值的数据使用const
总结:
let — 现在实际开发变量声明方式。
var — 以前的声明变量的方式,会有很多问题。
const — 类似于 let ,但是变量的值无法被修改。必须初始化(即声明的时候必须赋值),
const 声明的变量称为“常量”
数据类型
基本数据类型
number 数字型
string 字符串型
boolean 布尔型
undefined 未定义型
null 空类型
数字类型(Number)
JavaScript 中的正数、负数、小数等 统一称为 数字类型
总结
1. 算术运算符有那几个常见的?
+ - * / % ------
开发中经常作为某个数字是否被整除
2. 算术运算符优先级怎么记忆?
先乘除取余,后加减,有小括号先算小括号里面的
3. 取余运算符开发中的使用场景是?
来判断某个数字是否能被整除
![](https://img-blog.csdnimg.cn/direct/4b5df87cb33e40d29dbfe90263e81575.png)
对NaN做加减乘除的操作结果都是NaN
字符串类型(string)
通过单引号( '') 、双引号( "")或反引号( ` ) 包裹的数据都叫字符串
,单引号和双引号没有本质上的区别,推荐使用
单引号
。可以互相嵌套(单引号/双引号),必要时可以使用转义符 \,输出单引号或双引号
console.log('pink老师讲课非常有"基情"')
console.log("pink老师讲课非常有'基情'")
console.log('pink老师讲课非常有\'基情\'')
对应结果均是:
pink老师讲课非常有"基情"
拼接字符串和变量
内容拼接变量时,用
${
变量名
}(模板字符串)
包住变量,反引号``包含数据
// let age = 20
// // 模板字符串 外面用`` 里面 ${变量名}
// document.write(`我今年${age}岁了`)
let uname = prompt('请输入您的姓名:')
let age = prompt('请输入您的年龄:')
// 输出
document.write(`大家好,我叫${uname}, 我今年贵庚${age}岁了`)
布尔类型(boolean)
有两个固定的值 true 和 false,表示肯定的数据用 true(真),表示否定的数据用 false(假)
未定义类型(undefined)
只声明变量,不赋值的情况下,变量的默认值为 undefined,不知道是什么类型
工作中的使用场景:
我们开发中经常声明一个变量,等待传送过来的数据。
如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,来判断用户是否有数据传递过来
null(空类型)
JavaScript 中的 null 仅仅是一个代表“无”、“空”或“值未知”的特殊值
null 和 undefined 区别:
undefined 表示没有赋值
null 表示赋值了,但是内容为空
null 开发中的使用场景:
官方解释:把 null 作为尚未创建的对象
大白话: 将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null
// 计算有区别
console.log(undefined + 1) // NaN
console.log(null + 1) // 1
检测数据类型
通过 typeof
关键字检测数据类型
1.
作为运算符:
typeof x
(常用的写法)
2.
函数形式: typeof(x)
let num = 10
console.log(typeof num) // number
let str = 'pink'
console.log(typeof str) // string
let str1 = '10'
console.log(typeof str1) // string
let flag = false
console.log(typeof flag) // boolean
let un
console.log(typeof (un)) // undefined
let obj = null
console.log(typeof obj) // object
let num1 = prompt('请输入第一个数:')
console.log(typeof num1)
类型转换
JavaScript是弱数据类型: JavaScript也不知道变量到底属于那种数据类型,只有赋值了才清楚。
坑: 使用表单、prompt 获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。
![](https://img-blog.csdnimg.cn/direct/d7b598e3b73840b4a9815456c4cb4062.png)
此时需要转换变量的数据类型。
通俗来说,就是
把一种数据类型的变量转换成我们需要的数据类型
。
隐式转换
规则:
+ 号两边只要有一个是字符串,都会把另外一个转成字符串
除了+以外
的算术运算符 比如 - * / 等都会把数据转成数字类型
+号作为正号解析可以转换成数字型
任何数据和字符串相加结果都是字符串
![](https://img-blog.csdnimg.cn/direct/8091979bc8ba4d94a6e807c8256e71e7.png)
显式转换
转换为数字型
Number(数据)
转成数字类型
如果字符串内容里有
非数字
,转换失败时结果为 NaN(Not a Number)即不是一个数字
NaN也是number类型的数据,代表非数字
console.log(Number(NaN), '5555') // NaN
parseInt(数据)
只保留整数
parseFloat(数据)
可以保留小数
// 1. 用户输入 prompt 得到是字符串类型 要转换为 数字型
// 用+将prompt当中的输入结果字符串类型转化成数字型类型的
let num1 = +prompt('请输入第一个数字:')
let num2 = +prompt('请输入第二个数字:')
// 2. 输出
alert(`两个数相加的和是:${num1 + num2}`)
转换为字符型:
String(数据)
变量.toString(进制)
流程控制
运算符
= 赋值运算符
执行过程:将等号右边的值赋予给左边, 要求左边必须是一个容器
其他赋值运算符:
+=
-=
*=
/=
%=
一元运算符
自增:
符号:++
作用:让变量的值
+1
自减:
符号:--
作用:让变量的值
-1
通常用来计数
<script>
// let num = 10
// num = num + 1
// num += 1
// // 1. 前置自增
// let i = 1
// ++i
// console.log(i)
// let i = 1
// console.log(++i + 1) // 3 i先自加1,变成2之后,在和后面的1相加,所以结果是3
// 2. 后置自增
// let i = 1
// i++
// console.log(i)
// let i = 1
// console.log(i++ + 1) // 2,先运算,后面i在自增,此时的i值是2
// 了解
let i = 1
console.log(i++ + ++i + i) // 7 1 + 3 + 3 = 7
</script>
1.只需要一个表达式就可以运算的运算符叫一元运算符
比较运算符
比较运算符:
> : 左边是否大于右边
<: 左边是否小于右边
>=: 左边是否大于或等于右边
<=: 左边是否小于或等于右边
==: 左右两边值是否相等
===: 左右两边是否类型和值都相等
!==: 左右两边是否不全等
比较结果为boolean类型,即只会得到 true 或 false
对比:
= 单等是赋值
== 是判断
只要求值相等,不要求数据类型一样即可返回true
=== 是全等
要求值和数据类型都一样返回的才是true
开发中判断是否相等,强烈推荐使用 ===
注意点:
字符串比较,是比较的字符对应的ASCII码,从左往右依次比较
NaN不等于任何值,包括它本身,涉及到"NaN“ 都是false
尽量不要比较小数,因为小数有精度问题
不同类型之间比较会发生隐式转换
最终把数据隐式转换转成number类型再比较
所以开发中,如果进行准确的比较我们
更喜欢 ===
或者 !==
console.log(3 > 5)
console.log(3 >= 3)
console.log(2 == 2)
// 比较运算符有隐式转换 把'2' 转换为 2 双等号 只判断值
console.log(2 == '2') // true
// console.log(undefined === null)
// === 全等 判断 值 和 数据类型都一样才行
// 以后判断是否相等 请用 ===
console.log(2 === '2') // false
console.log(NaN === NaN) // NaN 不等于任何人,包括他自己
console.log(2 !== '2') // true
console.log(2 != '2') // false 只比较值,值都是2,类型一个是数值,一个是字符串
console.log('-------------------------')
console.log('a' < 'b') // true
console.log('aa' < 'ab') // true
console.log('aa' < 'aac') // true
console.log('-------------------------')
逻辑运算符
使用场景:
逻辑运算符用来解决多重条件判断
判断一个变量 num 是否大于5且小于10
正确写法: num > 5
&&
num < 10
![](https://img-blog.csdnimg.cn/direct/d69a298cf9f74391922e512e9d90d7d0.png)
需求:用户输入一个,判断这个数能被4整除,但是不能被100整除,满足条件,页面弹出true,否则弹出 false(重点是判断语句,以及判断语句得出的是true还是false)
// 1. 用户输入
let num = +prompt('请输入一个数字:')
// 2. 弹出结果
alert(num % 4 === 0 && num % 100 !== 0)
运算符优先级
![](https://img-blog.csdnimg.cn/direct/645c4a395b0d47dc9b636936693e955b.png)
一元运算符里面的
逻辑非优先级很高
逻辑与比逻辑或优先级高
![](https://img-blog.csdnimg.cn/direct/cdaa910bc7044c5089e5f6ce1177b37f.png)
语句
表达式和语句的区别
因为表达式可被求值,所以它可以写在赋值语句的右侧。
而语句不一定有值,所以比如 alert() for和break 等语句就
不能被用于赋值。
分支语句包含:
If分支语句
单分支使用语法:
![](https://img-blog.csdnimg.cn/direct/491f95c65cbc4bf2b280ed89456d07f2.png)
括号内的条件为
true
时,进入大括号里执行代码
小括号内的结果若不是布尔类型时,会发生隐式转换转为布尔类型
如果大括号只有一个语句,大括号可以省略,但是,俺们不提倡这么做
// 单分支语句
// if (false) {
// console.log('执行语句') // 不执行
// }
// if (3 > 5) {
// console.log('执行语句') // 不执行
// }
// if (2 === '2') {
// console.log('执行语句') // 不执行
// }
// 1. 除了0 所有的数字都为真
// if (0) {
// console.log('执行语句') // 不执行
// }
// 2.除了 '' 所有的字符串都为真 true
// if ('pink老师') {
// console.log('执行语句')
// }
// if ('') {
// console.log('执行语句') // 不执行
// }
// // if ('') console.log('执行语句') // 不执行,不推荐这样写
// 1. 用户输入
let score = +prompt('请输入成绩')
// 2. 进行判断输出
if (score >= 700) {
alert('恭喜考入黑马程序员')
}
console.log('-----------------')
双分支if语法:
![](https://img-blog.csdnimg.cn/direct/a1403a903629423c994e2475f246683e.png)
多分支if语法:
![](https://img-blog.csdnimg.cn/direct/2904f041deec4755937b0722b372b064.png)
三元运算符
符号:
? 与 : 配合使用
![](https://img-blog.csdnimg.cn/direct/45004ab2d58b44bab2d8e782580219e8.png)
判断2个数的最大值
// 1. 用户输入
let num1 = +prompt('请您输入第一个数:')
let num2 = +prompt('请您输入第二个数:')
// 2. 判断输出-三元运算符
// if (num1 > num2) {
// alert(num1)
// } else {
// alert(num2)
// }
num1 > num2 ? alert(`最大值是: ${num1}`) : alert(`最大值是: ${num2}`)
数字补0案例
需求:用户输入1个数,如果数字小于10,则前面进行补0, 比如 09 03 等
// let age = 18
// age = age + 1
// age++
// 1. 用户输入
let num = prompt('请您输入一个数字:')
// 2. 判断输出- 小于10才补0
// num = num < 10 ? 0 + num : num
// 此时的num是一个字符串,任何与字符串做加运算的,都会被转换成字符串
// num = num >= 10 ? num : 0 + num
num = num < 10 ? 0 + num : num
alert(num)
switch 语句
![](https://img-blog.csdnimg.cn/direct/f88a337b990a4913a125066f70790eae.png)
用于等值判断
需求:用户输入2个数字,然后输入 + - * / 任何一个,可以计算结果
// 1.用户输入 2个数字 + 操作符号 + - * /
let num1 = +prompt('请您输入第一个数字:')
let num2 = +prompt('请您输入第二个数字:')
let sp = prompt('请您输入 + - * / 其中一个:')
// 2. 判断输出 sp输入的运算符
switch (sp) {
case '+':
alert(`两个数的加法操作是${num1 + num2}`)
break
case '-':
alert(`两个数的减法操作是${num1 - num2}`)
break
case '*':
alert(`两个数的乘法操作是${num1 * num2}`)
break
case '/':
alert(`两个数的除法操作是${num1 / num2}`)
break
default:
alert(`请输入+-*/`)
}
循环结构
断点调试
断点:在某句代码上加的标记就叫断点,当程序执行到这句有标记的代码时会暂停下来
while 循环
![](https://img-blog.csdnimg.cn/direct/7ca8e4473d4c4a40ab3b353172ba9243.png)
小括号里的条件为true才会进入
循环体
执行代码
while大括号里代码执行完毕后不会跳出
,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到 小括号判断条件,直到括号内条件不满足,即跳出,所以需要这个终止条件,否则的话就会导致一直循环下去,造成死循环
while循环三要素是什么?
变量起始值
终止条件(没有终止条件,循环会一直执行(因为大括号里面的值一直为true),造成死循环)
变量变化量(用自增或者自减)
// // 1. 变量的起始值
// let i = 1
// // 2. 终止条件
// while (i <= 3) {
// document.write('我要循环三次 <br>')
// // 3. 变量的变化量
// i++
// }
// 1. 变量的起始值
let end = +prompt('请输入次数:')
let i = 1
// 2. 终止条件
while (i <= end) {
// 加了换行<br>
document.write('我要循环end次 <br>')
// 3. 变量的变化量
i++
}
循环退出
break:退出循环,
一般用于结果已经得到, 后续的循环不需要的时候可以使用
continue:结束本次循环,继续下次循环,
一般用于排除或者跳过某一个选项的时候,比如我跳过条件等于3的这个选项
简易ATM取款机案例
需求:用户可以选择存钱、取钱、查看余额和退出功能
// 1. 开始循环 输入框写到 循环里面
// 3. 准备一个总的金额
// 这个money的声明必须写在外面,否则的话,每次循环都会重新进行赋值
let money = 100
while (true) {
let re = +prompt(`
请您选择操作:
1.存钱
2.取钱
3.查看余额
4.退出
`)
// 2. 如果用户输入的 4 则退出循环, break 写到if 里面,没有写到switch里面, 因为4需要break退出循环
// 只要在这个 while循环当中,不输入4,那就不退出,继续执行语句
if (re === 4) {
break
}
// 4. 根据输入做操作
switch (re) {
case 1:
// 存钱
let cun = +prompt('请输入存款金额')
money = money + cun
break
case 2:
// 存钱
let qu = +prompt('请输入取款金额')
money = money - qu
break
case 3:
// 存钱
alert(`您的银行卡余额是${money}`)
break
}
}
数组
for循环语法
作用:
重复执行代码
好处:
把声明起始值、循环条件、变化值写到一起,让人一目了然
,
它是最常使用的循环形式
![](https://img-blog.csdnimg.cn/direct/d190fc6c165a440eaeef3d33c207b233.png)
了解
1.while(true) 来构造“无限”循环,需要使用break退出循环。
2.
for(;;) 也可以来
构造“无限”循环,同样需要使用break退出循环
// 无限循环
for (; ;) {
console.log(11)
}
总结
for循环和while循环有什么区别呢:
当如果明确了循环的次数的时候推荐使用for循环
当不明确循环的次数的时候推荐使用while循环
for循环和while循环有什么区别呢:
Ø
当如果明确了循环的次数的时候推荐使用for循环
Ø
当不明确循环的次数的时候推荐使用while循环
for 循环嵌套
![](https://img-blog.csdnimg.cn/direct/fa25446a031d4385976322b1da32da21.png)
九九乘法表
<style>
span {
display: inline-block;
width: 100px;
padding: 5px 10px;
border: 1px solid pink;
margin: 2px;
border-radius: 5px;
box-shadow: 2px 2px 2px rgba(255, 192, 203, .4);
background-color: rgba(255, 192, 203, .1);
text-align: center;
color: hotpink;
}
</style>
</head>
<body>
<script>
// 1. 外层循环控制行数
for (let i = 1; i <= 9; i++) {
// 2. 里层循环控制列数
for (let j = 1; j <= i; j++) {
document.write(`<span>${j} X ${i} = ${i * j}</span>`)
}
// 换行
document.write('<br>')
}
</script>
</body>
数组
为什么要数组?
思考:如果我想保存一个班里所有同学的姓名怎么办?放入到一个数组当中
场景:如果有多个数据可以用数组保存起来,然后放到一个变量中,
数组的基本使用
// 1. 字面量声明数组
// let arr = [1, 2, 'pink', true]
// 2. 使用new Array 构造函数声明 了解
// let arr = new Array(1, 2, 3, 4)
// console.log(arr)
数组是按顺序保存,所以每个数据都有自己的编号
计算机中的编号从0开始,所以小明的编号为0,小刚编号为1,以此类推
在数组中,数据的编号也叫
索引或下标
数组可以存储任意类型的数据
长度:数组中数据的个数,通过数组的length属性获得(arr.length)
数组求最大值和最小值
let arr = [2, 6, 1, 7, 400, 55, 88, 100]
// max里面要存的是最大值
let max = arr[0]
// min 要存放的是最小值
let min = arr[0]
// 遍历数组
for (let i = 1; i < arr.length; i++) {
// 如果max 比 数组元素里面的值小,我们就需要把这元素赋值给 max
// if (max < arr[i]) max = arr[i]
max < arr[i] ? max = arr[i] : max
// 如果min 比 数组元素大, 我们就需要把数组元素给min
// if (min > arr[i]) {
// min = arr[i]
// }
min > arr[i] ? min = arr[i] : min
}
// 输出 max
console.log(`最大值是: ${max}`)
console.log(`最小值是: ${min}`)
操作数组
![](https://img-blog.csdnimg.cn/direct/42e100909e5c43c4b4db41d922237cef.png)
数组.push()
方法将一个或多个元素添加到
数组的末尾
,并返回该数组的新长度
(重点)
arr.unshift(新增的内容)
方法将一个或多个元素添加到
数组的开头
,并返回该数组的新长度
数组. pop()
方法从数组中
删除最后一个元素
,并返回该元素的值
数组. shift()
方法从数组中
删除第一个元素
,并返回该元素的值
arr.splice(起,始位置, 删除的个数),指定删除数组元素
案例
根据数据生成柱形图
// 1. 四次弹框效果
// 声明一个新的数组
let arr = []
// 首先通过循环来得到每个盒子当中的数据,并且存入到数组当中
for (let i = 1; i <= 4; i++) {
// let num = prompt(`请输入第${i}季度的数据:`)
// arr.push(num)
arr.push(prompt(`请输入第${i}季度的数据:`))
// push记得加小括号,不是等号赋值的形式
}
// console.log(arr) ['123','135','345','234'] // 得到的就是字符串,因为prompt的返回值就是字符串
// 盒子开头
document.write(` <div class="box">`)
// 盒子中间 利用循环的形式 跟数组有关系
// 根据之前的到的数组,来渲染柱状图
for (let i = 0; i < arr.length; i++) {
document.write(`
<div style="height: ${arr[i]}px;">
<span>${arr[i]}</span>
<h4>第${i + 1}季度</h4>
</div>
`)
}
// 盒子结尾
document.write(` </div>`)
冒泡排序
数组. sort() 方法可以排序
// let arr = [5, 4, 3, 2, 1]
let arr = [2, 4, 3, 5, 1]
// for嵌套循环实现
// for (let i = 0; i < arr.length - 1; i++) {
// for (let j = 0; j < arr.length - i - 1; j++) {
// // 开始交换 但是前提 第一个数大于第二个数才交换
// if (arr[j] > arr[j + 1]) {
// // 交换2个变量
// let temp = arr[j]
// arr[j] = arr[j + 1]
// arr[j + 1] = temp
// }
// }
// }
// arr.sort() // 排序
// sort 升序排列,看返回的值是什么,a-b(前面的值减去后面的值)为true的话,说明前面的值更大,就交换数据,为false就不交换
// arr.sort(function (a, b) {
// return a - b
// })
// console.log(arr) //[1, 2, 3, 4, 5]
// sort() 降序排列,b-a(后面的值减去前面的值)为true的话,说明后面的值更大,就交换数据,为false就不交换
arr.sort(function (a, b) {
return b - a
})
console.log(arr) // [5, 4, 3, 2, 1]
函数
函数名命名规范
和变量命名基本一致
尽量小驼峰式命名法
前缀应该为动词
命名建议:常用动词约定
alert() 、 prompt() 和 console.log() 都是一些 js
函数
,只不过已经封装好了,直接使用
函数调用
调用方式: 函数名()
注意:声明(定义)的函数必须调用才会真正被执行,使用 () 调用函数
随时调用,随时执行,可重复调用
函数传参
![](https://img-blog.csdnimg.cn/direct/b47aa4f302714f01858c355987dc8243.png)
-参数默认值
![](https://img-blog.csdnimg.cn/direct/e74980f4c8c540508ddba30099b14f72.png)
函数封装
-求学生总分
// 1. 封装函数
// 给一个参数的默认值,这个地方给形参arr默认值为一个数组
function getArrSum(arr = []) {
// console.log(arr)
let sum = 0
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
console.log(sum)
}
getArrSum([1, 2, 3, 4, 5])
getArrSum([11, 22, 33])
getArrSum() // 0
函数返回值
有返回值的函数
return 后面代码不会再被执行,会立即结束当前函数,所以
return 后面的数据不要换行写
return函数可以没有 return,这种情况函数默认返回值为 undefined
return后面不接数据或者函数内不写return,函数的返回值是 undefined
// // 函数的返回值
// function fn() {
// return 20
// }
// // fn() 调用者 相当于执行了 fn() = 20
// // return 的值返回给调用者
// // console.log(fn())
// // let num = prompt('请输入数字')
// let re = fn()
// console.log(re)
function fn() {
// return //这个地方有没有return都返回undefined
}
let re = fn()
console.log(re) // undefined
函数返回值练习
// 3. 求任意数组的最大值和最小值,并且返回
function getArrValue(arr = []) {
// (1)先准备一个max变量存放数组的第一个值
let max = arr[0]
let min = arr[0] // 最小值
// (2) 遍历比较
for (let i = 1; i < arr.length; i++) {
// 最大值
if (max < arr[i]) {
max = arr[i]
}
// 最小值
if (min > arr[i]) {
min = arr[i]
}
}
// (3) 返回值 返回的是数组,注意一下这个地方,返回的是数组
return [max, min]
// return min
}
let newArr = getArrValue([11, 3, 55, 7, 29])
console.log(`数组的最大值是: ${newArr[0]}`)
在Javascript中 实参的个数和形参的个数可以不一致
如果形参过多 会自动填上undefined (了解即可)
如果实参过多 那么多余的实参会被忽略 (函数内部有一个arguments,里面装着所有的实参)
作用域
全局作用域。函数外部或者整个script 有效
局部作用域。也称为函数作用域,函数内部有效
变量有一个坑, 特殊情况:
(也即是局部作用域当中用到的变量)局部变量或者块级变量,没有let 声明,直接赋值的,也当
全局变量
看,但是强烈不推荐
但是有一种情况,函数内部的形参可以看做是局部变量。
变量的访问原则
只要是代码,就至少有一个作用域
l
写在函数内部的局部作用域
l
如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
l
访问原则:
在能够访问到的情况下 先局部, 局部没有在找全局,
采取
就近原则
的方式来查找变量最终的值
匿名函数
![](https://img-blog.csdnimg.cn/direct/0c4adf255d1b40729cf82259b8f898ab.png)
匿名函数
没有名字的函数, 无法直接使用。
使用方式:
1.函数表达式
将匿名函数赋值给一个
变量
,并且通过
变量名称
进行调用,我们将这个称为
函数表达式
![](https://img-blog.csdnimg.cn/direct/a3857ec678eb4720898a752a1d30c553.png)
// console.log(num)
// let num = 10
// 3 + 4
// num = 10
// 1. 函数表达式
fn(1, 2) //错误 函数表达式提前调用了
let fn = function (x, y) {
// console.log('我是函数表达式')
console.log(x + y)
}
// 函数表达式和 具名函数的不同 function fn() {}
// 1. 具名函数的调用可以写到任何位置
// 2. 函数表达式,必须先声明函数表达式,后调用
// function fun() {
// console.log(1)
// }
// fun()
2.立即执行函数
场景介绍:
避免全局变量之间的污染
注意: 多个立即执行函数要用
;
隔开(;可以写在函数前面,也可以写在函数后面),要不然会报错
立即执行函数
无需调用,立即执行,其实本质已经调用了
<script>
// flexible.js当中就是立即执行函数的写法,用这个立即执行函数把里面的代码包起来的原因是:因为这个是作为第三方的文件(插件)引进来的,如果不加这个立即执行函数,就会造成这里面代码的一些变量名和我们的一些变量名冲突
// let num = 10
// let num = 20
// (function () {
// console.log(11) // 11
// })()
// (function () {
// let num = 10
// })();
// (function () {
// let num = 20
// })();
// 1. 第一种写法
(function (x, y) {
console.log(x + y) // 3
let num = 10
let arr = []
})(1, 2);
// (function(){})();
// 2.第二种写法
// (function () { }());
(function (x, y) {
let arr = []
console.log(x + y) // 4
}(1, 3));
// 这样也是立即执行函数写法,给立即执行函数命名了的方式
(function zzz(x, y) {
let arr = []
console.log(x + y) // 4
}(1, 3));
// (function(){})()
// (function(){}())
</script>
转换时间案例
计算公式:计算时分秒
小时: h = parseInt(总秒数 / 60 / 60 % 24)
分钟: m = parseInt(总秒数 / 60 % 60 )
秒数: s = parseInt(总秒数 % 60)
// age = age + 1
// 1. 用户输入
let second = +prompt('请输入秒数:')
// 2.封装函数
function getTime(t) {
// console.log(t) // 总的秒数
// 3. 转换
// 小时: h = parseInt(总秒数 / 60 / 60 % 24)
// 分钟: m = parseInt(总秒数 / 60 % 60)
// 秒数: s = parseInt(总秒数 % 60)
let h = parseInt(t / 60 / 60 % 24)
let m = parseInt(t / 60 % 60)
let s = parseInt(t % 60)
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
// console.log(h, m, s)
return `转换完毕之后是${h}小时${m}分${s}秒`
}
let str = getTime(second)
document.write(str)
console.log(h)
3.逻辑中断
![](https://img-blog.csdnimg.cn/direct/1fc94858c12a4df08a68429edf63a003.png)
1.逻辑运算符里的短路
![](https://img-blog.csdnimg.cn/direct/1ccfb523b6084ac997a941742e5aaad3.png)
&&逻辑与与||逻辑或左右也可以写表达式
function fn(x, y) {
x = x || 0
y = y || 0
console.log(x + y)
}
fn(1, 2)
// fn()
// console.log(false && 22) // false
// console.log(false && 3 + 5) // false 一假则假
// let age = 18
// console.log(false && age++) // age++ 不执行 一假则假
// console.log(age) // 18
// console.log(true || age++) // true,逻辑或,一真得真,只要前面一个是真值那后面就不判断了
// console.log(age)
// console.log(11 && 22) // 都是真,这返回最后一个真值,逻辑与,两个都为真值的话,返回后面的一个值
// console.log(11 || 22) // 输出第一个真值
思考拓展:
2. 转换为Boolean型
显示转换:
1.Boolean(内容)
记忆
:
‘’ 、0、undefined、null、false、NaN 转换为布尔值后都是false, 其余则为 true
代码测验:
console.log(Boolean('pink')) // true
console.log(Boolean('')) // false
console.log(Boolean(0)) // false
console.log(Boolean(90)) // true
console.log(Boolean(-1)) // true 除了0之外都为真true,小数也是
console.log(Boolean(undefined)) // false
console.log(Boolean(null)) // false
console.log(Boolean(NaN)) // false
console.log('--------------------------')
let age
if (age) {
console.log(11) // 不执行 age为undefined
}
隐式转换:
![](https://img-blog.csdnimg.cn/direct/bef8fff56b954deca3ea80734f07a9f1.png)
对象
对象有属性和方法组成
属性:信息或叫特征(名词)。 比如 手机尺寸、颜色、重量等…
方法:功能或叫行为(动词)。 比如 手机打电话、发短信、玩游戏…
改
和
增
语法一样,判断标准就是对象有没有这个属性,
没有就是新增,有就是改
属性-查的另外一种写法
对于多词属性或则 - 等属性,点操作就不能用了。
我们可以采取: 对象[‘属性’] 方式, 单引号和双引号都阔以
![](https://img-blog.csdnimg.cn/direct/66601a3024244c2fa5a122ce1c347f0e.png)
总结:
1. 对象访问属性有哪两种方式?
点形式 对象.属性
[] 形式 对象[‘属性’]
2. 两种方式有什么区别?
点后面的属性名一定不要加引号
[] 里面的属性名一定加引号
后期不同使用场景会用到不同的写法
对象中的方法
方法的调用与对象的调用是一样的,都可以用.与['']来调用
遍历对象
![](https://img-blog.csdnimg.cn/direct/0e33cba12bb644f086f3846bb73ac38d.png)
一般不用这种方式遍历数组、主要是用来遍历对象
for in语法中的 k 是一个变量, 在循环的过程中依次代表对象的属性名
由于 k 是变量, 所以必须使用 [ ] 语法解析
一定记住:
k
是获得对象的
属性名
,
对象名[k]
是获得
属性值
// for in 我们不推荐遍历数组,因为k是字符串
// let arr = ['pink', 'red', 'blue']
// for (let k in arr) {
// console.log(k) // 数组的下标 索引号 但是是字符串 '0',所以不提倡
// console.log(arr[k]) // arr[k]
// }
// 1. 遍历对象 for in
let obj = {
uname: 'pink老师',
age: 18,
gender: '男'
}
// 2. 遍历对象
for (let k in obj) {
console.log(k) // 属性名 'uname' 'age'
// console.log(obj.uname)
// console.log(obj.k)
// console.log(obj.'uname')
// console.log(obj['uname']) 'uname' === k
console.log(obj[k]) // 输出属性值 obj[k]
}
内置对象-Math
介绍:
Math对象是JavaScript提供的一个“数学”对象
作用:
提供了一系列做数学运算的方法
Math对象包含的方法有:
random:生成0-1之间的随机数(包含0不包括1)
ceil:向上取整
floor:向下取整
max:找最大数
min:找最小数
pow:幂运算
abs:绝对值
console.log(Math.round(-1.5)) // -1
// 取整函数 parseInt('12px') // 12
// null 类似 let obj = {}
let obj = null // 这个变量要存一个对象,但是这个对象还没有准备好,就可以用null先替代一下,所以null叫空对象,用typeof检测就是object
内置对象-生成任意范围随机数
Math.random() 随机数函数, 返回一个0 - 1之间,并且包括0不包括1的随机小数
[0, 1)
如何生成0-10的随机数呢?
Math.floor(Math.random() * (10 + 1))
如何生成5-10的随机数?
Math.floor(Math.random() * (5 + 1)) + 5
l如何生成N-M之间的随机数
Math.floor(Math.random() * (M - N + 1)) + N
案例
猜数字游戏
// 1. 随机生成一个数字 1~10
// 取到 N ~ M 的随机整数
function getRandom(N, M) {
return Math.floor(Math.random() * (M - N + 1)) + N
}
let random = getRandom(1, 10)
// 2. 设定三次 三次没猜对就直接退出
let flag = true // 开关变量
for (let i = 1; i <= 3; i++) {
let num = +prompt('请输入1~10之间的一个数字:')
if (num > random) {
alert('您猜大了,继续')
} else if (num < random) {
alert('您猜小了,继续')
} else {
flag = false
alert('猜对了,真厉害')
break
}
}
// 写到for的外面来
if (flag) {
alert('次数已经用完')
}
生成随机颜色
// 1. 自定义一个随机颜色函数
function getRandomColor(flag = true) {
if (flag) {
// 3. 如果是true 则返回 #ffffff
let str = '#'
let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
// 利用for循环随机抽6次 累加到 str里面
for (let i = 1; i <= 6; i++) {
// 每次要随机从数组里面抽取一个
// random 是数组的索引号 是随机的
let random = Math.floor(Math.random() * arr.length)
// str = str + arr[random]
str += arr[random]
}
return str
} else {
// 4. 否则是 false 则返回 rgb(255,255,255)
let r = Math.floor(Math.random() * 256) // 55
let g = Math.floor(Math.random() * 256) // 89
let b = Math.floor(Math.random() * 256) // 255
return `rgb(${r},${g},${b})`
}
}
// 2. 调用函数 getRandomColor(布尔值)
// 会随机更改,但是格式是这样
console.log(getRandomColor(false)) // rgb(170,53,77)
console.log(getRandomColor(true)) // #472bd8
console.log(getRandomColor()) // #65a558
// let str = '#'
// str = str + 'f'
拓展-术语解释
![](https://img-blog.csdnimg.cn/direct/3ee05a5e0e774a438b340538b3a768bd.png)
目标:了解基本数据类型和引用数据类型的存储方式
简单类型又叫做基本数据类型或者
值类型
,复杂类型又叫做
引用类型
。
l
值类型:简单数据类型/基本数据类型,在存储时变量中
存储的是值本身
,因此叫做值类型
string ,number,boolean,undefined,null
l
引用类型:复杂数据类型,在存储时变量中
存储的仅仅是地址(引用)
,因此叫做引用数据类型
通过
new 关键字创建的对象
(系统对象、自定义对象),如 Object、Array、Date等
堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的
栈;
简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
引用数据类型存放到堆里面
1. 简单类型的内存分配
l
值类型(简单数据类型): string ,number,boolean,undefined,null
l
值类型变量的数据直接存放在变量(栈空间)中
![](https://img-blog.csdnimg.cn/direct/960c13b695b54bc3a80a807e1daf1882.png)
2. 复杂类型的内存分配
l
引用类型(复杂数据类型):通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
l
引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中
以上为学习时记的笔记,后期可能会改进!!!