文章目录
前言
小白JavaScript学习笔记
一、JavaScript 基础第一天
学习目标
- 理解变量是存储数据的“容器”
- 理解什么是数据并知道数据的分类
- 知道 JavaScript 数据类型转换的特征
1.1JavaScript介绍
1.1.1JavaScript 是什么
1. JavaScript (是什么?)
是一种运行在客户端(浏览器)的编程语言,实现人机交互效果。
2. 作用(做什么?)
– 网页特效 (监听用户的一些行为让网页作出对应的反馈)
– 表单验证 (针对表单数据的合法性进行判断)
– 数据交互 (获取后台的数据, 渲染到前端)
– 服务端编程 (node.js)
node.js运行表
3. JavaScript的组成(有什么?)
ECMAScript:
规定了js基础语法核心知识。
比如:变量、分支语句、循环语句、对象等等
Web APIs :
DOM 操作文档,比如对页面元素进行移动、大小、添加删除等操作
BOM 操作浏览器,比如页面弹窗,检测窗口宽度、存储数据到浏览器等等
JavaScript权威网站: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
总结:
- JavaScript是什么?
JavaScript 是一种运行在客户端(浏览器)的编程语言- JavaScript组成是什么?
ECMAScript( 基础语法 )、web APIs (DOM、BOM)
1.1.2JavaScript 书写位置
1. 内部 JavaScrip
直接写在html文件里,用script标签包住
规范:script标签写在</body>上面
拓展:alert(‘你好,js’) 页面弹出警告对话框
注意事项:
我们将 <script> 放在HTML文件的底部附近的原因是浏览器会按照代码在文件中的顺序加载 HTML。如果先加载的 JavaScript 期望修改其下方的 HTML,那么它可能由于 HTML 尚未被加载而失效。因此,将 JavaScript 代码放在 HTML页面的底部附近通常是最好的策略。
2. 外部JavaScript
代码写在以.js结尾的文件里
语法:通过script标签,引入到html页面中。
**注意事项: **
1.script标签中间无需写代码,否则会被忽略!
2.外部JavaScript会使代码更加有序,更易于复用,且没有了脚本的混合,HTML 也会更加易读,因此这是个好的习惯
3. 内联 JavaScript
代码写在标签内部
语法:
总结:
- JavaScript三种书写位置?
内部
外部
行内- 注意事项:
书写的位置尽量写到文档末尾 </body> 前面
外部 js 标签中间不要写代码,否则会被忽
1.1.3JavaScript 的注释
1.1.4JavaScript的结束符
作用: 使用英文的 ; 代表语句结束
实际情况: 实际开发中,可写可不写, 浏览器(JavaScript 引擎) 可以自动推断语句的结束位置
现状: 在实际开发中,越来越多的人主张,书写 JavaScript 代码时省略结束符
**约定:**为了风格统一,结束符要么每句都写,要么每句都不写(按照要求.)
总结:
- JavaScript 注释有那两种方式?
单行注释 //
多行注释 /* */- JavaScript 结束符注意点
结束符是?
分号 ;
结束符可以省略吗?
Yes,但为了风格统一,结束符要么每句都写,要么每句都不写
1.1.5输入和输出语法
输出语法:
输出和输入也可理解为人和计算机的交互,用户通过键盘、鼠标等向计算机输入信息,计算机处理后再展示结果给用户,这便是一次输入和输出的过程。
输入语法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 语法一:向body内输出内容,如果输出的内容写的是标签,也会被解析成网页元素
document.write('要输出的内容')
document.write('<h1>我是</h1>')
//语法二:页面弹出井盖对话框
alert('要出的内容')
//语法三:控制台输出语法 ,程序员调试使用
console.log('控制台打印')
//3输入语句
prompt("请输入您的年龄")
</script>
</body>
</html>
输入输出练习案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
alert("你好 JS")
document.write("JavaScript 我来了!")
console.log("它~会魔法吧~")
</script>
</body>
</html>
1.1.6字面量
1.2变量
1.2.1变量是什么
1. 变量:
白话:变量就是一个装东西的盒子。
通俗:变量是计算机中用来存储数据的“容器”,它可以让计算机变得有记忆
注意:变量不是数据本身,它们仅仅是一个用于存储数值的容器。可以理解为是一个个用来装东西的纸箱子.
总结:
- 变量是怎么理解?
计算机中用来存储数据的“容器”,简单理解是一个个的盒子。- 变量有什么作用呢?
用来存放数据的。注意变量指的是容器而不是数据。- 你还能想到那些生活中的变量?
HTML标签
教室
宿舍
1.2.2 变量基本使用☆
1. 变量的声明
2. 变量的赋值
1. 声明变量:
要想使用变量,首先需要创建变量(也称为声明变量或者定义变量)
语法:
let 变量名
声明变量有两部分构成:声明关键字、变量名(标识)
let 即关键字 (let: 允许、许可、让、要),所谓关键字是系统提供的专门用来声明(定义)变量的词语
举例:
let age
我们声明了一个age变量
age 即变量的名称,也叫标识符
2. 变量赋值:
定义了一个变量后,你就能够初始化它(赋值)。在变量名之后跟上一个**“=”,然后是数值
注意:是通过变量名来获得变量里面的数据
简单点,也可以声明变量的时候直接完成赋值操作,这种操作也称为 变量初始化**。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//声明一个变量
let age
//赋值
age = 18
//
let name="junhao"
//输出
alert(age)
document.write(name)
console.log(age)
</script>
</body>
</html>
总结:
- 变量用什么关键字来声明?
let- 变量通过什么符号来赋值?
= 这个符号我们也称为 赋值运算符- 开发中我们经常声明的同时可以直接赋值?
案例:
需求:
- 声明一个变量,用于存放用户购买的商品 数量 ( num ) 为 20 件
- 声明一个变量,用于存放用户的 姓名 ( uname ) 为 ’张三’
- 依次控制台打印输出两个变量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//声明一个变量
let age
//赋值
age = 18
//
let name="junhao"
//输出
alert(age)
document.write(name)
console.log(age)
//案例:
let num=20
let uname="张三"
console.log(num)
console.log(uname)
</script>
</body>
</html>
3. 更新变量:
变量赋值后,还可以通过简单地给它一个不同的值来更新它。
注意: let 不允许多次声明一个变量
4. 声明多个变量:
变量赋值后,还可以通过简单地给它一个不同的值来更新它
总结:
- 变量赋值之后如何更新新值?
直接给它一个不同的值来更新它- 我们提倡同时声明多个不同的变量吗?
不提倡, 可读性不好
变量案例1-弹出姓名
需求: 浏览器中弹出对话框: 请输入姓名, 页面中输出:刚才输入的姓名
分析:
①:输入:用户输入框:prompt()
②:内部处理:保存数据
③:输出: 页面打印document.write()
<script>
let name = prompt("请输入姓名")
document.write(name)
</script>
变量案例2- 交换变量的值:
需求:
有2个变量: num1 里面放的是 10, num2 里面放的是20
最后变为 num1 里面放的是 20,num2 里面放的是10
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let num1 = prompt("请输入第一个数")
let num2 = prompt("请输入第二个数")
let temp
temp = num1
num1 = num2
num2 = temp
document.write("第一个数为:" + num1)
document.write("第二个数为:" + num2)
</script>
</body>
</html>
1.2.3变量的本质
内存计算机中存储数据的地方,相当于一个空间
变量本质:是程序在内存中申请的一块用来存放数据的小空间
1.2.4变量命名规则与规范
规则:必须遵守,不遵守报错
规范:建议,不遵守不会报错,但不符合业内通识
1.规则:
不能用关键字
关键字:有特殊含义的字符,JavaScript 内置的一些英语词汇。例如:let、var、if、for等
只能用下划线、字母、数字、$组成,且数字不能开头
字母严格区分大小写,如 Age 和 age 是不同的变量
2. 规范:
起名要有意义
遵守小驼峰命名法
第一个单词首字母小写,后面每个单词首字母大写。例:userName
变量练习-输出用户信息:
需求:让用户输入自己的名字、年龄、性别,再输出到网页
分析:
①:弹出输入 框(prompt): 请输入您的姓名 (uname): 用变量保存起来。
②:弹出输入框(prompt) : 请输入您的年龄 (age): 用变量保存起来。
③:弹出输入框(prompt) : 请输入您的性别(gender): 用变量保存起来。
④:页面分别 输出 (document.write) 刚才的 3 个变
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let uname = prompt("请输入您的姓名")
let age = prompt("请输入您的年龄")
let gender = prompt("请输入您的性别")
document.write("姓名:" +uname +"年龄:" + age + "性别:" + gender)
</script>
</body>
</html>
1.2.5变量拓展-let和var的区别
let 和 var 区别:
在较旧的JavaScript,使用关键字 var 来声明变量 ,而不是 let。var 现在开发中一般不再使用它,只是我们可能再老版程序中看到它。let 为了解决 var 的一些问题。
var 声明:
1. 可以先使用 在声明 (不合理)
2. var 声明过的变量可以重复声明(不合理)
3. 比如变量提升、全局变量、没有块级作用域等等
结论:
var 就是个bug,别迷恋它了,以后声明变量我们统一使用 let
1.2.6变量拓展-数组
数组 (Array) —— 一种将 一组数据存储在单个变量名下 的优雅方式
1. 声明语法:
- 数组是按顺序保存,所以每个数据都有自己的编号
- 计算机中的编号从0开始,所以小明的编号为0,小刚编号为1,以此类推
- 在数组中,数据的编号也叫索引或下标
- 数组可以存储任意类型的数据
2. 取值语法:
- 通过下标取数据
- 取出来是什么类型的,就根据这种类型特点来访问
3. 一些术语:
**元素:**数组中保存的每个数据都叫数组元素
**下标:**数组中数据的编号
**长度:**数组中数据的个数,通过数组的length属性获得
数组使用:
<script>
//1.声明数组
let names = ["小明","老六","老七","老大","老三","老六","星期日"]
//2.使用数组
console.log(names) //["小明","老六","老七","老大","老三","老六","星期日"]
console.log(names[0]) //小明
</script>
数组取值案例:
需求:定义一个数组,里面存放星期一、星期二…… 直到星期日(共7天),在控制台输出:星期日
<script>
let names = ["小明","老六","老七","老大","老三","老六","星期日"]
console.log(names[6])
</script>
1.3常量
概念:使用 const 声明的变量称为“常量”。
使用场景:当某个变量永远不会改变的时候,就可以使用 const 来声明,而不是let。
命名规范:和变量一致
常量使用:
注意: 常量不允许重新赋值,声明的时候必须赋值(初始化)
小技巧:不需要重新赋值的数据使用const
使用:
<script>
//常量声明
const PI = 3.14
console.log(PI)
//常量不可重复赋值
PI = 3.15(错误的)
console.log(PI)
//常量声明的时候必须赋值
const PI(错误的)
</script>
总结:
let — 现在实际开发变量声明方式。
var — 以前的声明变量的方式,会有很多问题。
const — 类似于 let ,但是变量的值无法
1.4数据类型
数据类型☆
检测数据类型
计算机程序可以处理大量的数据,为什么要给数据分类?
1. 更加充分和高效的利用内存
2. 也更加方便程序员的使用数
JS 数据类型整体分为两大类:
基本数据类型
引用数据类
1.4.1 数据类型 – 数字类型(Number)
即我们数学中学习到的数字,可以是整数、小数、正数、负数(与java还是有不同的)。
JavaScript 中的正数、负数、小数等 统一称为 数字类型
注意事项:
JS 是弱数据类型,变量到底属于那种类型,只有赋值之后,我们才能确认
Java是强数据类型 例如 int a = 3 必须是整数
数字可以有很多操作,比如,乘法 * 、除法 / 、加法 + 、减法 - 等等,所以经常和算术运算符一起。数学运算符也叫算术运算符,主要包括加、减、乘、除、取余(求模)。
+:求和
-:求差
*:求积
/:求商
%:取模(取余数)
开发中经常作为某个数字是否被整除
同时使用多个运算符编写程序时,会按着某种顺序先后执行,我们称为优先级。
JavaScript中 优先级越高越先被执行,优先级相同时以书从左向右执行。
乘、除、取余优先级相同
加、减优先级相同
乘、除、取余优先级大于加、减
使用 () 可以提升优先级
总结: 先乘除后加减,有括号先算括号里面的~~~
总结:
- 算术运算符有那几个常见的?
+ - * / %- 算术运算符优先级怎么记忆?
先乘除取余,后加减,有小括号先算小括号里面的- 取余运算符开发中的使用场景是?
来判断某个数字是否能被整
计算圆的面积
需求:对话框中输入圆的半径,算出圆的面积并显示到页面
分析:
①:面积的数学公式: π*r²
②:转换为JavaScript写法 : 变量 * r * r
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let pi = 3.1415
let r = prompt("请输入圆的半径:")
let S = pi * r * r
console.log(S)
</script>
</body>
</html>
1.4.2 数据类型 – 字符串类型(string)
通过单引号( ‘’) 、双引号( “”)或反引号( ` ) 包裹的数据都叫字符串,单引号和双引号没有本质上的区别,推荐使用单引号。
注意事项:
1. 无论单引号或是双引号必须成对使用
2. 单引号/双引号可以互相嵌套,但是不以自已嵌套自已(口诀:外双内单,或者外单内双)
3. 必要时可以使用转义符 \,输出单引号或双引
字符串拼接:
场景: + 运算符 可以实现字符串的拼接。
口诀:数字相加,字符相连
<script>
//字符串拼接
console.log("计算机" + "科学与技术")
let age = 22
console.log("我今年" + age + "岁了")
</script>
模板字符串
使用场景
拼接字符串和变量
在没有它之前,要拼接变量比较麻烦
语法:
`` (反引号)
在英文输入模式下按键盘的tab键上方那个键(1左边那个键)
内容拼接变量时,用 ${ } 包住变
<script>
let age = 18
document.write(`我今年${age}岁了`)
</script>
总结:
- JavaScript中什么样数据我们知道是字符串类型?
只要用 单引号、双引号、反引号包含起来的就是字符串类型- 字符串拼接比较麻烦,我们可以使用什么来解决这个问题?
模板字符串, 可以让我们拼接字符串更简便- 模板字符串使用注意事项:
用什么符号包含数据?
反引号
用什么来使用变量?
${变量名}
页面输出用户信息案例
<script>
let name = prompt("请输入名字")
let age = prompt("请输入年龄")
document.write(`大家好,我叫${name},今年${age}s岁了`)
</script>
1.4.3 数据类型 – 布尔类型(boolean)
表示肯定或否定时在计算机中对应的是布尔类型数据。
它有两个固定的值 true 和 false,表示肯定的数据用 true(真),表示否定的数据用 false(假)。
<script>
//true false 是布尔型字面量
let iscool = true
console.log(iscool)//true
console.log(3>4) //false
</script>
1.4.4数据类型 – 未定义类型(undefined)
未定义是比较特殊的类型,只有一个值 undefined。
什么情况出现未定义类型?
只声明变量,不赋值的情况下,变量的默认值为 undefined,一般很少【直接】为某个变量赋值为 undefined
工作中的使用场景:
我们开发中经常声明一个变量,等待传送过来的数据。
如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,就判断用户是否有数据传递过来
1.4.5数据类型 – null(空类型)
JavaScript 中的 null 仅仅是一个代表“无”、“空”或“值未知”的特殊值
null 和 undefined 区别:
undefined 表示没有赋值
null 表示赋值了,但是内容为空
null 开发中的使用场景:
官方解释:把 null 作为尚未创建的对象
大白话: 将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null
<script>
//true false 是布尔型字面量
let iscool = true
console.log(iscool)//true
console.log(3>4) //false
console.log(undefined + 1) //NaN
console.log(null + 1) //1
</script>
总结:
- 布尔数据类型有几个值?
true 和 false- 什么时候出现未定义数据类型?以后开发场景是?
定义变量未给值就是 undefined
如果检测变量是undefined就说明没有值传递过来- null 是什么类型? 开发场景是?
空类型
如果一个变量里面确定存放的是对象,如果还没准备好对象,可以放个null
1.4.6 控制台输出语句和检测数据类型
控制台输出语句:
控制台语句经常用于测试结果来使用。
可以看出数字型和布尔型颜色为蓝色,字符串和undefined颜色为灰色
通过 typeof 关键字检测数据类型
typeof 运算符可以返回被检测的数据类型。它支持两种语法形式:
- 作为运算符: typeof x (常用的写法)
- 函数形式: typeof(x)
换言之,有括号和没有括号,得到的结果是一样的,所以我们直接使用运算符的写法
<script>
let num = 10
console.log(typeof num)
let str = 'pink'
console.log(typeof str)
let str1 = '10'
console.log(typeof str1)
let flag = false
console.log(typeof flag)
let un
console.log(typeof (un))
let obj = null
console.log(typeof obj)
let num1 = prompt('请输入第一个数:')
console.log(typeof num1)
</script>
1.5类型转换
为什么要类型转换
隐式转换
显式转换
1.5.1 为什么需要类型转换
JavaScript是弱数据类型: JavaScript也不知道变量到底属于那种数据类型,只有赋值了才清楚。
坑: 使用表单、prompt 获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。
此时需要转换变量的数据类型。
通俗来说,就是把一种数据类型的变量转换成我们需要的数据类型。
1.5.2 隐式转换
某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。
规则:
+号两边只要有一个是字符串,都会把另外一个转成字符串
除了+以外的算术运算符 比如 - * / 等都会把数据转成数字类型
缺点:
转换类型不明确,靠经验才能总结
小技巧:
+号作为正号解析可以转换成数字型 console.log(+“123”) //123(数字)
任何数据和字符串相加结果都是字符串
1.5.3 显式转换
编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。
为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。
概念:
自己写代码告诉系统该转成什么类型
转换为数字型
Number(数据)
转成数字类型
如果字符串内容里有非数字,转换失败时结果为 NaN(Not a Number)即不是一个数字
NaN也是number类型的数据,代表非数字
parseInt(数据)
只保留整数
parseFloat(数据)
可以保留小数
编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。
为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。
概念:
自己写代码告诉系统该转成什么类型
转换为字符型:
String(数据)
变量.toString(进制)
<script>
let str = '123'
console.log(Number(str)) //数字123
console.log(Number('pink')) //不可以转
// let num = Number(prompt('输入年薪')) //显示转换
// let num = +prompt('输入年薪') //隐式转换num是数字
// console.log(Number(num)) //显示转换
// console.log(num) //num是字符串
console.log(parseInt('12px')) //12只保留整数
console.log(parseInt('12.34px')) //12
console.log(parseInt('12.94px')) //12
console.log(parseInt('abc12.94px')) //12
// -------------------
console.log(parseFloat('12px')) // 12
console.log(parseFloat('12.34px')) // 12.34
console.log(parseFloat('12.94px')) // 12.94
console.log(parseFloat('abc12.94px')) // 12.94
</script>
总结:
- 类型转换的概念
一种数据类型转成别的类型, JavaScript是弱数据类型,很多情况计算的时候,需要转换数据类型- 隐式转换
系统自动做转换- 显式转换
自己写代码告诉系统转成什么类型
Number
4.字符串内容里有非数字得到NaN
Strin
输入2个数,计算两者的和,打印到页面中
<script>
// 1. 用户输入 prompt 得到是字符串类型 要转换为 数字型
let num1 = +prompt('请输入第一个数字:')
let num2 = +prompt('请输入第二个数字:')
// 2. 输出
alert(`两个数相加的和是:${num1 + num2}`)
</script>
1.6实战案例
1.6.1用户订单信息案例
需求:用户输入商品价格和商品数量,以及收货地址,可以自动打印订单信息
分析:
①:需要输入3个数据,所以需要3个变量来存储 price num address
②:需要计算总的价格 total
③:页面打印生成表格,里面填充数据即可
④:记得最好使用模板字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
h2 {
text-align: center;
}
table,
th,
td {
border: 1px solid #000;
}
/* 合并相邻边框 */
table {
border-collapse: collapse;
height: 50px;
margin: 0 auto;
text-align: center;
}
th {
padding: 5px 30px;
}
</style>
</head>
<body>
<h2>订单确认</h2>
<script>
//用户输入
let name = prompt("请输入商品名称:")
let price = +prompt("请输入商品价格:")
let num = +prompt("请输入商品数量:")
let address = prompt("请输入收货地址:")
//计算总额
let total = price * num
//页面打印渲染
document.write(`
<table>
<tr>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th>总价</th>
<th>收获地址</th>
</tr>
<tr>
<td>${name}</td>
<td>${price}</td>
<td>${num}</td>
<td>${total}</td>
<td>${address}</td>
</tr>
</table>
`)
</script>
</body>
</html>
1.7常见错误
二、JavaScript 基础第二天
2.1运算符
2.2.1赋值运算符
赋值运算符:对变量进行赋值的运算符
已经学过的赋值运算符:= 将等号右边的值赋予给左边, 要求左边必须是一个容器
其他赋值运算符:
+=
-=
*=
/=
%=
使用这些运算符可以在对变量赋值时进行快速操作
<script>
let num = 1
num = num + 1
console.log(num) //num=2
//赋值运算符写法
let number = 1
number += 1
console.log(number) //number = 2
</script>
总结:
- = 赋值运算符执行过程?
将等号右边的值赋予给左边, 要求左边必须是一个容器- += 出现是为了简化代码, 比如让 let num = 10 ,num 加5 怎么写呢?
num += 5
2.2.2一元运算符
众多的 JavaScript 的运算符可以根据所需表达式的个数,分为一元运算符、二元运算符、三元运算符
二元运算符:
一元运算符:
我们可以有更简便的写法了~~~
1.自增:
符号:++
作用:让变量的值 +1
2.自减:
符号:–
作用:让变量的值 -1
使用场景:经常用于计数来使用。 比如进行10次操作,用它来计算进行了多少次了
自增运算符的用法:
面试题:
<script>
let i = 1
console.log(i++ + ++i + i) //7--运行i++结果是1,i++运行完之后i=2,再运行++i,此时++i=3,i=3
</script>
- 前置自增和后置自增独立使用时二者并没有差别!
- 一般开发中我们都是独立使用
- 后面 i++ 后置自增会使用相对较多,并且都是单独使用
总结:
1.只需要一个表达式就可以运算的运算符叫一元运算符
2. 自增运算符也是为了简化写法,每次自加1,使用场景是什么?
经常用于计数来使用。用来计算多少次
3. 实际开发中,我们一般都是单独使用的,后置++ 更多
2.2.3比较运算符
比较运算符的介绍
使用场景:比较两个数据大小、是否相等
实际运用例:
<script>
console.log(3 > 5) //false
console.log(3 >= 3) //ture
console.log('2' == 2)//ture
// 比较运算符有隐式转换 把'2' 转换为 2 双等号 只判断值
console.log(2 == '2') // true
console.log(2 === '2')
console.log(NaN === NaN) //false NaN 不等于任何人,包括他自己
console.log(2 !== '2') // true
console.log(2 != '2') // false
console.log('-------------------------')
console.log('a' < 'b') // true
console.log('aa' < 'ab') // true
console.log('aa' < 'aac') // true
console.log('-------------------------')
</script>
总结:
- = 和 == 和 === 怎么区别?
= 是赋值
== 是判断 只要求值相等,不要求数据类型一样即可返回true
=== 是全等 要求值和数据类型都一样返回的才是true
开发中,请使用 ===- 比较运算符返回的结果是什么?
结果只有2个, true 或者 false
2.2.4逻辑运算符
1.提问:如果我想判断一个变量 num 是否大于5且小于10,怎么办?
错误写法: 5 < num < 10
2.使用场景:逻辑运算符用来解决多重条件判断
正确写法: num >5 && num<10
逻辑运算符:
<script>
//&&一个为假就假
console.log(true && true)
console.log(false && true)
console.log("---------------")
//||一个是真就为真
console.log(true || true)
console.log(false || true)
console.log(false || false)
//!相反
console.log(!true)
console.log(!false)
</script>
总结:
- 逻辑运算符有那三个?
与(&&) 或(||) 非(!)- 判断一个变量 num 是否大于5且小于10怎么写?
num > 5 && num<10
判断一个数是4的倍数,且不是100的倍数
需求:用户输入一个,判断这个数能被4整除,但是不能被100整除,满足条件,页面弹出true,否则弹出false
分析:
①:用户输入
②:判断条件, 看余数是不是0,如果是0就是能被整除,余数不是0,则不能被整除
<script>
//用户输入
let number = +prompt("请输入一个数:")
alert(number%4 === 0 && number%100 !== 0)
</script>
2.2.5运算符优先级
2.2语句
2.2.1表达式和语句
表达式:
表达式是可以被求值的代码,JavaScript 引擎会将其计算出一个结果。
语句:
语句是一段可以执行的代码。
比如: prompt() 可以弹出一个输入框,还有 if语句 for
区别:
表达式:因为表达式可被求值,所以它可以写在赋值语句的右侧。
表达式 num = 3 + 4
语句:而语句不一定有值,所以比如 alert() for和break 等语句就不能被用于赋值。
语句 alert() 弹出对话框 console.log() 控制台打印输出
某些情况,也可以把表达式理解为表达式语句,因为它是在计算结果,但不是必须的成分 (例如continue语句)
2.2.2分支语句
程序三大流程控制语句:
以前我们写的代码,写几句就从上往下执行几句,这种叫顺序结构
有的时候要根据条件选择执行代码,这种就叫分支结构
某段代码被重复执行,就叫循环结构
分支语句:
分支语句可以让我们有选择性的执行想要的代码
分支语句包含:
1.If分支语句
2.三元运算符
3.switch 语句
2.2.2.1.If分支语句
1. if语句
if语句有三种使用:单分支、双分支、多分支
单分支使用语法
括号内的条件为true时,进入大括号里执行代码
小括号内的结果若不是布尔类型时,会发生隐式转换转为布尔类型
如果大括号只有一个语句,大括号可以省略,但是,俺们不提倡这么做~
注意:小括号内如果只是一个数字,如果不是0,负数,正数都为真
小括号内字符串除了空字符串,都为真
练习:
单分支课堂案例1:用户输入高考成绩,如果分数大于700,则提示恭喜考入黑马程序员
<script>
let num = +prompt("请输入高考成绩")
if(num > 570){
document.write("恭喜你考入XX大学")
}
</script>
双分支if语法:
判断用户登录案例:
需求:用户输入,用户名:pink,密码:123456, 则提示登录成功,否则提示登录失败
分析:
①:弹出输入框,分别输入用户名和密码
②:通过if语句判断,如果用户名是pink,并且密码是123456,则执行if里面的语句,否则执行else
里面的语句。
<script>
let name = prompt("请输入用户名")
let password = prompt("请输入密码")
if(name === "pink" && password === "123456"){
document.write("登陆成功")
}else{
document.write("登陆失败")
}
</script>
判断闰年案例
需求:让用户输入年份,判断这一年是闰年还是平年并弹出对应的警示框
分析:
①:能被4整除但不能被100整除,或者被400整除的年份是闰年,否则都是平年
②:需要逻辑运算符
<script>
let year = +prompt("请输入你要查询的年份:")
if(year%4 === 0 && year%100 !== 0 || year%400 === 0){
document.write(`${year}年是闰年`)
}else{
document.write(`${year}年不是闰年`)
}
</script>
多分支if语法:
使用场景: 适合于有多个结果的时候, 比如学习成绩可以分为: 优 良 中
输入成绩案例:
需求:根据输入不同的成绩,反馈不同的评价
注:
①:成绩90以上是 优秀
②:成绩70~90是 良好
③:成绩是60~70之间是 及格
④:成绩60分以下是 不及格
<script>
let score = +prompt("请输入成绩")
if(score >= 90){
alert("成绩为优秀")
}else if(score >=70 && score < 90){
alert("成绩为良好")
}else if(score >=60 && score < 70){
alert("成绩为及格")
}else{
alert("成绩为不及格")
}
</script>
2.2.2.2.三元运算符
使用场景: 其实是比 if 双分支 更简单的写法,可以使用 三元表达式
符号:? 与 : 配合使用
语法:
一般用来取值
判断2个数的最大值案例
需求:用户输入2个数,控制台输出最大的值
分析:
①:用户输入2个数
②:利用三元运算符输出最大值
<script>
let a = 10
let b = 20
a > b ? document.write(a) : document.write(b) //20
//表达式取值
let num = a>b?a : b
document.write(num) //20
</script>
数字补0案例
需求:用户输入1个数,如果数字小于10,则前面进行补0, 比如 09 03 等
分析:
①:为后期页面显示时间做铺垫
②:利用三元运算符 补 0 计算
<script>
//1.用户输入
let num = +prompt("请输入一个数字")
//判断输出,字符串(在前面)和数字相连会隐式转换
num > 10? alert(num) : alert("0" + `${num}`)
</script>
2.2.2.3.switch 语句
注意事项
- switch case语句一般用于等值判断,不适合于区间判断
?2. switch case一般需要配合break关键字使用 没有break会造成case穿透,不会跳出,直到完成结束
案例 简单计算器
需求:用户输入2个数字,然后输入 + - * / 任何一个,可以计算结果
分析:
①:用户输入数字
②:用户输入不同算术运算符,可以去执行不同的运算 (switch
<script>
let num1 = +prompt("输入第一个数:")
let num2 = +prompt("输入第二个数:")
let select = prompt("输入你要对这两个数进行什么样的运算")
switch (select) {
case "+":
alert(num1 + num2)
break
case "-":
alert(num1 - num2)
break
case "*":
alert(num1 * num2)
break
case "/":
alert(num1 / num2)
break
default:
alert("您的输入有误")
break
}
</script>
2.2.3循环语句
2.2.3.1 断点调试
作用:学习时可以帮助更好的理解代码运行,工作时可以更快找到bug
浏览器打开调试界面
- 按F12打开开发者工具
- 点到sources一栏
- 选择代码文件
断点:在某句代码上加的标记就叫断点,当程序执行到这句有标记的代码时会暂停下来
2.2.3.2 while 循环
循环:重复执行一些操作, while : 在…. 期间, 所以 while循环 就是在满足条件期间,重复执行某些代码。
比如我们运行相同的代码输出5次(输出5句 “我学的很棒”)
- while 循环基本语法:
释义:
跟if语句很像,都要满足小括号里的条件为true才会进入 循环体 执行代码
while大括号里代码执行完毕后不会跳出,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到小括号判断条件,直到括号内条件不满足,即跳出
- while 循环三要素:
循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。
所以,while循环需要具备三要素:
总结:
- while循环的作用是什么?
在满足条件期间,重复执行某些代码- while循环三要素是什么?
变量起始值
终止条件(没有终止条件,循环会一直执行,造成死循环)
变量变化量(用自增或者自减)
案例 在页面中打印输出10句“月薪过万”
需求:使用while循环,页面中打印,可以添加换行效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let i = 1
while(i<=10){
document.write(`${i}:月薪过万<br>`)
i++
}
</script>
</body>
</html>
While 练习
需求:使用while循环,页面中打印,可以添加换行效果
- 页面输出1-100
核心思路: 利用 i ,因为正好和 数字对应
let i = 1
while(i<=100){
document.write(`${i}<br>`)
i++
}
- 计算从1加到100的总和并输出
核心思路:
声明累加和的变量 sum
每次把 i 加到 sum 里面
let i = 1
let sum = 0
while(i<=100){
sum = sum + i
i++
}
document.write(sum)
- 计算1-100之间的所有偶数和
核心思路:
声明累加和的变量 sum
首先利用if语句把 i 里面是偶数筛选出来
把 筛选的 i 加到 sum 里
let i = 1
let sum = 0
while(i<=100){
if(i%2 === 0){
sum = sum + i
}
i++
}
document.write(sum)
<script>
// let age = 18
// age = age + 1
// age += 1
// 1. 页面输出1~100
// let i = 1
// while (i <= 100) {
// document.write(`这是第${i}个数<br>`)
// i++
// }
// 2. 页面输出1~100 累加和
// let i = 1 // 变量的起始值
// let sum = 0 // 累加和变量
// while (i <= 100) {
// // 把i 累加到 sum 里面
// // sum = sum + i
// sum += i
// i++
// }
// console.log(sum) // 5050
// 3. 页面输出1~100 偶数和
let i = 1
let sum = 0
while (i <= 100) {
// 筛选偶数 只有偶数才累加
if (i % 2 === 0) {
sum = sum + i
}
// 每次循环都要自加
i++
}
console.log(sum)
</script>
2.2.3.3 循环退出
循环结束:
break:退出循环
continue:结束本次循环,继续下次循环
区别:
continue 退出本次循环,一般用于排除或者跳过某一个选项的时候, 可以使用continue
break 退出整个循环,一般用于结果已经得到, 后续的循环不需要的时候可以使用
<script>
// let i = 1
// while (i <= 5) {
// console.log(i)
// if (i === 3) { //不输出3以及3以后的
// break // 退出循环
// }
// i++
// }
let i = 1
while (i <= 5) {
if (i === 3) {
i++
continue //不输出3
}
console.log(i)
i++
}
</script>
案例 页面弹框
需求:页面弹出对话框,‘你爱我吗’,如果输入‘爱’,则结束,否则一直弹出对话框
分析:
①:循环条件永远为真,一直弹出对话框
②:循环的时候,重新让用户输入
③:如果用户输入的是: 爱,则退出循环 (break)
<script>
while (true) {
let str = prompt('你爱我吗')
// 退出条件 爱
if (str === '爱') {
break
}
}
</script>
2.3综合案例
案例 简易ATM取款机案例
需求:用户可以选择存钱、取钱、查看余额和退出功能
分析:
①:循环的时候,需要反复提示输入框,所以提示框写到循环里面
②:退出的条件是用户输入了 4,如果是4,则结束循环,不在弹窗
③:提前准备一个金额预先存储一个数额
④:取钱则是减法操作, 存钱则是加法操作,查看余额则是直接显示金额
⑤:输入不同的值,可以使用switch来执行不同的操作
<script>
let cunkuan = 4000
while (true) {
let select = prompt(`
请选择您的操作
1.取款
2.存款
3.查看余额
4.退出`)
if (select === "4"){
break
}
switch(select){
case "1":
//取款
let money = +prompt("请输入要取的金额")
cunkuan = cunkuan - money
break
case "2":
//存款
let num = +prompt("请输入要存的金额")
cunkuan = cunkuan + num
break
case "3":
//查看余额
alert(`您的银行卡余额是${cunkuan}`)
break
default:
//输入有误
break
}
}
</script>
三、JavaScript 基础第三天
3.1循环-for
3.1.1for循环-基本使用
1. for循环语法
作用:重复执行代码
好处:把声明起始值、循环条件、变化值写到一起,让人一目了然,它是最常使用的循环形式
循环练习:
- 利用for循环输出1~100岁
- 求1-100之间所有的偶数和
- 页面中打印5个小星星
- for循环的最大价值: 循环数组需求: 请将 数组 [‘马超’,‘赵云’, ‘张飞’, ‘关羽‘,’黄忠’] 依次打印出
<script>
//1. 利用for循环输出1~100岁
for(let i = 1;i <=100; i++){
document.write(`${i}岁<br>`)
}
// 2. 求1-100之间所有的偶数和
let sum = 0
for(let a = 1;a <=100; a++){
if(a%2 === 0){
sum = sum + i
}
}
//3. 页面中打印5个小星星
for(let b = 1;b <=5; b++){
document.write(`*<br>`)
}
</script>
<script>
let arr = ['马超','赵云','张飞','关羽','黄忠']
for(let i = 0;i<arr.length;i++){
document.write(`${arr[i]} <br>`)
}
</script>
2. 退出循环
continue 退出本次循环,一般用于排除或者跳过某一个选项的时候, 可以使用continue
break 退出整个for循环,一般用于结果已经得到, 后续的循环不需要的时候可以使用
<script>
for(let i = 1;i<=5;i++){
if(i === 3){
//continue
continue
}
console.log(i)
}
console.log(`=====================`)
for(let i = 1;i<=5;i++){
if(i === 3){
//break
break
}
console.log(i)
}
</script>
了解:
while(true) 来构造“无限”循环,需要使用break退出循环。
for(;😉 也可以来构造“无限”循环,同样需要使用break退出循环。
总结:
- for循环和while循环有什么区别呢:
当如果明确了循环的次数的时候推荐使用for循环
当不明确循环的次数的时候推荐使用while循环
3.1.2for循环嵌套
for 循环嵌套
练习 • 打印5行5列的星星
需求: 页面中打印出5行5列的星星
分析:
①:利用双重for循环来做
②:外层循环控制打印行,内层循环控制每行打印几个(列)
升级版本:
用户输入行数和列数,打印对应的星星!
<script>
let row = prompt(`请输入行`)
let col = prompt(`请输入列`)
for(let i =0 ;i < row ;i++){
for(let j = 0 ;j < col ;j++){
document.write('☆')
}
document.write(`<br>`)
}
</script>
练习• 打印倒三角形星星
需求:如图所示
分析:
①:利用双重for循环来做
②:外层循环控制打印行,内层循环控制每行打印几个(列)
③:内层循环的个数跟第几行是一一对应的
<script>
let row = prompt(`请输入行`)
for(let i =1 ;i <= row ;i++){
for(let j = 0 ;j < i ;j++){
document.write('☆')
}
document.write(`<br>`)
}
</script>
练习 • 九九乘法表
需求:如图所示
分析:
①:只需要把刚才倒三角形星星做改动
②: ★ 换成 1 x 1 = 2 格式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
span {
display: inline-block;
width: 90px;
padding: 5px 0;
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>
for (let i = 1; i <= 9; i++) {
for (let j = 1; j <= i; j++) {
document.write(`<span>${j} × ${i} = ${i*j}</span>`)
}
document.write(`<br>`)
}
</script>
</body>
</html>
3.2数组
3.2.1数组是什么
数组:(Array)是一种可以按顺序保存数据的数据类型
为什么要数组?
思考:如果我想保存一个班里所有同学的姓名怎么办?
场景:如果有多个数据可以用数组保存起来,然后放到一个变量中,管理非常方便
3.2.2数组的基本使用
1. 声明语法:
1.数组是按顺序保存,所以每个数据都有自己的编号
2.计算机中的编号从0开始,所以小明的编号为0,小刚编号为1,以此类推
3.在数组中,数据的编号也叫索引或下标
4.数组可以存储任意类型的数据
2. 取值语法
通过下标取数据
取出来是什么类型的,就根据这种类型特点来访问
3. 一些术语:
元素:数组中保存的每个数据都叫数组元素
下标:数组中数据的编号
长度:数组中数据的个数,通过数组的length属性获得
4. 遍历数组(重点)
目标:能够遍历输出数组里面的元素
用循环把数组中每个元素都访问到,一般会用for循环遍历
语法
练习 • 数组求和
需求:求数组 [2,6,1,7, 4] 里面所有元素的和以及平均值
分析:
①:声明一个求和变量 sum。
②:遍历这个数组,把里面每个数组元素加到 sum 里面。
③:用求和变量 sum 除以数组的长度就可以得到数组的平均值。
<script>
//需求:求数组 [2,6,1,7, 4] 里面所有元素的和以及平均值
let sum = 0
let ave
let arr = [2,6,1,7, 4]
for(let i = 0;i<arr.length;i++){
sum = sum + arr[i]
}
ave= sum / arr.length
console.log(sum)
console.log(ave)
</script>
练习 • 数组求最大值和最小值
需求:求数组 [2,6,1,77,52,25,7] 中的最大值
分析:
①:声明一个保存最大元素的变量 max。
②:默认最大值可以取数组中的第一个元素。
③:遍历这个数组,把里面每个数组元素和 max 相比较。
④:如果这个数组元素大于max 就把这个数组元素存到 max 里面,否则继续下一轮比较。
⑤:最后输出这个 max
拓展:
自己求一下最小值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 需求:求数组 [2,6,1,77,52,25,7] 中的最大值
let arr = [2,6,1,77,52,25,7]
// 假设第一个值是最大的
let max = arr[0]
// 假设第一个值是最小的
let min = arr[0]
for(let i = 1 ; i < arr.length;i++){
max > arr[i]? max : max = arr[i]
min > arr[i]? min = arr[i] : min
}
document.write(`最大值为${max}`)
document.write(`最小值为${min}`)
</script>
</body>
</html>
3.2.3操作数组
数组本质是数据集合, 操作数据无非就是 增 删 改 查 语法
3.2.3.1操作数组-新增
数组.push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度 (重点)
arr.unshift(新增的内容) 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度
总结:
- 想要数组末尾增加数据元素利用那个方法?
arr.push()
可以添加一个或者多个数组元素
返回的是数组长度- 想要数组开头增加数据元素利用那个方法?
arr.unshift()
可以添加一个或者多个数组元素
返回的是数组长度- 重点记住那个?
arr.push()
案例 数组筛选
需求:将数组 [2, 0, 6, 1, 77, 0, 52, 0, 25, 7] 中大于等于 10 的元素选出来,放入新数组
分析:
①:声明一个新的数组用于存放新数据newArr
②:遍历原来的旧数组, 找出大于等于 10 的元素
③:依次追加给新数组 newArr
<script>
//数组去0案例
let arr = [2,0,6,1,77,0,52,0,25,7]
let newArr = []
for(let i = 0;i<arr.length;i++){
if(arr[i] >= 10)
newArr.push(arr[i])
}
console.log(newArr)
</script>
数组去0案例
需求:将数组 [2, 0, 6, 1, 77, 0, 52, 0, 25, 7] 中的 0 去掉后,形成一个不包含 0 的新数组
分析:
①:声明一个新的数组用于存放新数据newArr
②:遍历原来的旧数组, 找出不等于0的元素
③:依次追加给新数组 newArr
<script>
//数组去0案例
let arr = [2,0,6,1,77,0,52,0,25,7]
let newArr = []
for(let i = 0;i<arr.length;i++){
if(arr[i] !== 0)
newArr.push(arr[i])
}
console.log(newArr)
</script>
3.2.3.2操作数组-删除
数组. pop() 方法从数组中删除最后一个元素,并返回该元素的值
数组. shift() 方法从数组中删除第一个元素,并返回该元素的值
数组. splice() 方法 删除指定元素
解释:
1.start 起始位置:
指定修改的开始位置(从0计数)
2.deleteCount:
表示要移除的数组元素的个数
可选的。 如果省略则默认从指定的起始位置删除到最后
<script>
let arr = ['red', 'green', 'blue']
// console.log(arr.pop()) // blue
// 1.pop() 删除最后一个元素
// arr.pop()
// arr.pop()
// console.log(arr)
// 2. shift() 删除第一个元素
// arr.shift()
// console.log(arr)
// 3. splice 删除指定元素 splice(起始位置-索引号, 删除几个)
arr.splice(1, 1) // 是从索引号1的位置开始删, 只删除1个
// arr.splice(1) // 从green 删除到最后
console.log(arr)
</script>
总结:
- 想要数组末尾删除1个数据元素利用那个方法?带参数吗?
arr.pop()
不带参数
返回值是删除的元素- 想要数组开头删除1个数据元素利用那个方法?带参数吗?
arr.shift()
不带参数
返回值是删除的元素- 想要指定删除数组元素用那个?开发常用吗?有那些使用场景?
arr.splice(起始位置, 删除的个数)
开发很常用,比如随机抽奖,比如删除指定商品等等
3.3综合案例
案例 根据数据生成柱形图
需求: 用户输入四个季度的数据,可以生成柱形图
分析:
①:需要输入4次,所以可以把4个数据放到一个数组里面
利用循环,弹出4次框,同时存到数组里面
②:遍历改数组,根据数据生成4个柱形图,渲染打印到页面中
柱形图就是div盒子,设置宽度固定,高度是用户输入的数据
div里面包含显示的数字和 第n季度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
display: flex;
width: 700px;
height: 300px;
border-left: 1px solid pink;
border-bottom: 1px solid pink;
margin: 50px auto;
justify-content: space-around;
align-items: flex-end;
text-align: center;
}
.box>div {
display: flex;
width: 50px;
background-color: pink;
flex-direction: column;
justify-content: space-between;
}
.box div span {
margin-top: -20px;
}
.box div h4 {
margin-bottom: -35px;
width: 70px;
margin-left: -10px;
}
</style>
</head>
<body>
<script>
//声明一个数组来接受输入的数字
let arr = []
//四次弹框效果
for (let i = 1; i < 5; i++) {
let number = prompt(`请输入第${i}个季度的数据`)
arr.push(number)
}
//盒子开头
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}季度</h4>
</div>
`)
}
//盒子结尾
document.write(`</div>`)
</script>
</body>
</html>
四、JavaScript 基础第四天
4.1函数
为什么需要函数
函数的使用
函数传参
函数返回值
作用域
有名函数/匿名函数
把相同部分抽取出来封装
4.1.1为什么需要函数
函数:
function,是被设计为执行特定任务的代码块
说明:
函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。
比如我们前面使用的 alert() 、 prompt() 和 console.log() 都是一些 js 函数,只不过已经封装好了,我们直接使用的
总结:
- 为什么需要函数?
可以实现代码复用,提高开发效率- 函数是什么?
function执行特定任务的代码块
4.1.2函数使用
函数的声明语法:
例:
函数名命名规范:
- 和变量命名基本一致
- 尽量小驼峰式命名法
- 前缀应该为动词
- 命名建议:常用动词约定
函数的调用语法:
注意:声明(定义)的函数必须调用才会真正被执行,使用 () 调用函
** alert() , parseInt() 这种名字后面跟小括号的本质都是函数的调用**
函数体:
函数体是函数的构成部分,它负责将相同或相似代码“包裹”起来,直到函数调用时函数体内的代码才会被执行。函数的功能代码都要写在函数体当中。
总结:
- 函数是用那个关键字声明的?
function- 函数不调用会执行吗?如何调用函数?
函数不调用自己不执行
调用方式: 函数名()- 函数的复用代码和循环重复代码有什么不同?
循环代码写完即执行,不能很方便控制执行位置
随时调用,随时执行,可重复调用
练习 • 函数课堂练习
需求:
- 写一个打招呼的函数 hi~
<script>
//1.函数的声明
function sayHi(){
console.log('hi~~~')
}
//2.函数调用
sayHi()
</script>
- 把99乘法表封装到函数里面,重复调用3次
<script>
//声明函数
function sheet99() {
//把重复代码封装
//1.外层循环控制行数
for (let i = 1; i <= 9; i++) {
//2.里层循环控制列数
for (let j = 1; j <= i; j++) {
document.write(`<span>${j} × ${i} = ${i * j}</span>`)
}
//换行
document.write(`<br>`)
}
}
</script>
案例 函数案例
需求:
- 封装一个函数,计算两个数的和
<script>
function getsum(sum1,sum2){
sum = sum1 + sum2
alert(`和为${sum}`)
}
let sum1 = + prompt(`请输入第一个数`)
let sum2 = + prompt(`请输入第二个数`)
getsum(sum1,sum2)
</script>
- 封装一个函数,计算1-100之间所有数的和
<script>
function getNumberSum(){
let sum = 0
for(let i =1;i<=100;i++){
sum = sum + i
}
alert(sum)
}
getNumberSum()
</script>
4.1.3函数传参
解决办法:把要计算的数字传到函数内
结论:
- 若函数完成功能需要调用者传入数据,那么就需要用有参数的函数 这样可以极大提高函数的灵活性
声明语法:
例:
调用语法:
形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值
开发中尽量保持形参和实参个数一致
alert(‘打印’), parseInt(‘11’), Number(‘11’) 本质上都是函数调用的传参
总结:
- 函数传递参数的好处是?
可以极大的提高了函数的灵活性- 函数参数可以分为那两类?怎么判断他们是那种参数?
1.函数可以分为形参和实参
2.函数声明时,小括号里面的是形参,形式上的参数
3.函数调用时,小括号里面的是实参,实际的参数
4.尽量保持形参和实参的个数一致- 参数中间用什么符号隔开?
逗号
练习 • 函数封装求和
需求:采取函数封装的形式:输入2个数,计算两者的和,打印到页面中
<script>
function getsum(sum1,sum2){
sum = sum1 + sum2
alert(`和为${sum}`)
}
let sum1 = + prompt(`请输入第一个数`)
let sum2 = + prompt(`请输入第二个数`)
getsum(sum1,sum2)
</script>
函数传参-参数默认值:
形参: 可以看做变量,但是如果一个变量不给值,默认是什么?
undefined
但是如果做用户不输入实参,刚才的案例,则出现 undefined + undefined 结果是什么?
NaN
我们可以改进下,用户不输入实参,可以给 形参默认值,可以默认为 0, 这样程序更严谨,可以如下操作:
说明:这个默认值只会在缺少实参参数传递时才会被执行,所以有参数会优先执行传递过来的实参, 否则默认为undefined
案例 函数封装-求学生总分
需求:学生的分数是一个数组,计算每个学生的总分
分析:
①: 封装一个求和函数
②: 传递过去的参数是一个数组
③: 函数内部遍历数组求和
<script>
//1.封装函数
//arr = [],参数默认值,如果没有实参传过来,则默认调用函数的结果为0
function getArrSum(arr = []){
//3.编写函数体
let sum = 0
for(let i=0;i<arr.length;i++){
sum = sum + arr[i]
}
console.log(sum)
}
//2.调用函数
getArrSum([1,2,3,4,5,6]) //21
getArrSum([12,45,67]) //124
getArrSum() //0
</script>
4.1.4函数返回值
提问:什么是函数?
函数是被设计为执行特定任务的代码块
提问:执行完特定任务之后,然后呢?
把任务的结果给我们
其实我们前面已经接触了很多的函数具备返回值:
只是这些函数是JS底层内置的.我们直接就可以使用
当然有些函数,则没有返回值:
所以要根据需求,来设定需不需要返回值
总结:
- 函数很多情况下需要返回值,这个时候5919不能直接打印,而是需要得到一个返回值为5919然后放到盒子里
return关键字:
当函数需要返回数据出去时,用return关键字
怎么使用呢?
<script>
//函数返回值
function fn(){
return 20
}
fn() //没有值,相当于执行fn() = 20
//console.log(fn()) //20
let re = fn()
console.log(re) //20
</script>
运用返回值求和:
<script>
//求和函数写法
//定义函数
function getSum(sum1=0,sum2=0){
return sum1 + sum2
}
let sum1 = +prompt(`请输入第一个数`) //45
let sum2 = +prompt(`请输入第二个数`) //67
let re = getSum(sum1,sum2)
//不打印的情况下
//需要用到的时候只需要用“re”就行了,而不需要再去调用
console.log(re) //112
</script>
有返回值的函数:
细节:
- 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
- return 后面代码不会再被执行,会立即结束当前函数,所以 return 后面的数据不要换行写
- return函数可以没有 return,这种情况函数默认返回值为 undefine
<script>
function fn(){
}
console.log(fn()) //undefined
</script>
总结:
- 为什么要让函数有返回值
函数执行后得到结果,结果是调用者想要拿到的(一句话,函数内部不需要输出结果,而是返回结果!!!!!)
对执行结果的扩展性更高,可以让其他的程序使用这个结果- 函数有返回值用那个关键字? 有什么注意事项呢?
语法:return 数据
return后面不接数据或者函数内不写return,函数的返回值是undefined
return能立即结束当前函数, 所以 return 后面的数据不要换
练习 • 函数返回值练:
- 求任意2个数中的最大值, 并返回
<script>
//求任意2个数中的最大值
function getMaxNumber(num1 ,num2){
return num1 > num2? num1 : num2
}
let num1 = +prompt(`输入第一个数`)
let num2 = +prompt(`输入第二个数`)
alert(getMaxNumber(num1,num2))
</script>
- 求任意数组中的最大值并返回这个最大值
<script>
// 求任意数组中的最大值并返回这个最大值
function getArrMaxNumber(arr = []){
let max = arr[0]
for(let i=1;i<arr.length;i++){
max = max>arr[i]? max : arr[i]
}
return max
}
alert(getArrMaxNumber([1,5,3,7,9,20,45,2,3,79]))
</script>
- 求任意数组中的最小值并返回这个最小值
- 断点调试:进入函数内部看执行过程 F1
- 求任意数组中的最大值,最小值并返回这个最大值,最小值((函数如何返回多个值))
<script>
//返回最大和最小值(函数如何返回多个值))
function getArrMaxAndMinNumber(arr = []){
let max = arr[0]
let min = arr[0]
for(let i=1;i<arr.length;i++){
max = max>arr[i]? max : arr[i]
}
for(let i=1;i<arr.length;i++){
min = min<arr[i]? min : arr[i]
}
//返回两个数,用数组接收
return [max,min]
}
//返回值是一个数组
let newArr = getArrMaxAndMinNumber([1,5,3,7,9,20,45,2,3,79])
//这里还可以循环输出返回的数组
alert(`最大值:${newArr[0]},最小值:${newArr[1]}`)
</script>
函数细节补充:
- 两个相同的函数后面的会覆盖前面的函数
- 在Javascript中 实参的个数和形参的个数可以不一致
如果形参过多 会自动填上undefined (了解即可)
如果实参过多 那么多余的实参会被忽略 (函数内部有一个arguments,里面装着所有的实参)
- 函数一旦碰到return就不会在往下执行了 函数的结束用return
4.1.5作用域
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
变量有一个坑, 特殊情况:
如果函数内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐
但是有一种情况,函数内部的形参可以看做是局部变量
<script>
// let num = 20
// function fn() {
// num = 10 // 全局变量来看 强烈不允许!!!!
// }
// fn()
// console.log(num) //10
// function fun(x, y) {
// // 形参可以看做是函数的局部变量
// console.log(x)
// }
// fun(1, 2)
// console.log(x) // 错误的,x是局部变量,只在fun(x, y)函数内有效
// let num = 10
function fn() {
// let num = 20
function fun() {
// let num = 30
console.log(num)
}
fun()
}
fn()
</script>
总结:
- JS 中作用域分为哪2种?
全局作用域。函数外部或者整个script 有效
局部作用域。也称为函数作用域,函数内部有效- 根据作用域不同,变量分为哪2种?
全局变量
局部变量- 有一种特殊情况是全局变量是那种?我们提倡吗?
局部变量或者块级变量 没有let 声明直接赋值的当全局变量看
我们强烈不提倡
还有一种特殊情况,函数内部的形参可以当做局部变量看
4.1.6变量的访问原则
思考:
- 在不同作用域下,可能存在变量命名冲突的情况,到底改执行谁呢?
变量的访问原则:
只要是代码,就至少有一个作用域
写在函数内部的局部作用域
如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
访问原则:在能够访问到的情况下 先局部, 局部没有在找全局
案例 1: 结果是几?
function f1() {
let num = 123
function f2() {
console.log( num )
}
f2()
}
let num = 456
f1()
//结果是123
案例 2: 结果是几?
function f1() {
let num = 123
function f2() {
let num = 0
console.log(num)
}
f2()
}
let num = 456
f1()
//结果是0
案例 3: 结果是几?
let a = 1
function fn1() {
let a = 2
let b = '22'
fn2()
function fn2() {
let a = 3
fn3()
function fn3() {
let a = 4
console.log(a) //a的值 ?
console.log(b) //b的值 ?
}
}
}
fn1()
//结果是4,22
总结:
- 变量访问原则是什么?
采取就近原则的方式来查找变量最终的值
4.1.7匿名函数
- 具名函数的调用可以写到任何位置
- 函数表达式,必须先声明函数表达式,后调用
先调用会报错
匿名函数
没有名字的函数, 无法直接使用。
使用方式:
- 函数表达式
- 立即执行函数
1. 函数表达式
将匿名函数赋值给一个变量,并且通过变量名称进行调用,我们将这个称为函数表达式
其中函数的形参和实参使用跟具名函数一致
使用场景:
2. 立即执行函数
场景介绍: 避免全局变量之间的污染
注意: 多个立即执行函数要用 ; 隔开,要不然会
写法:(function(){…})()
先写两个小括号()()
在第一个括号里面写匿名函数(functiong(){……})()
<script>
//let number = 10
//let number = 20
//两个同名变量互相影响,此时可以使用立即执行函数,对页面中各个区域的盒子分离。
//使得即使变量名相同但是不在同一个函数内也不会冲突
//立即执行函数
(function(){
console.log(11)
})()
(function(){
let num = 10
})();
(function(){
let num = 20
})()
</script>
总结:
- 立即执行函数有什么作用?
防止变量污染不用担心和其他函数的变量名重叠- 立即执行函数需要调用吗? 有什么注意事项呢?
无需调用,立即执行,其实本质已经调用了
(function(){…})()
(**function()**是形参{…})()
(function(){…})是一个整体 () 是实参
多个立即执行函数之间用分号隔开
4.2综合案例
4.2.1案例 转换时间案例
需求: 用户输入秒数,可以自动转换为时分秒
分析:
①:用户输入总秒数 (注意默认值)
②:计算时分秒(封装函数) 里面包含数字补0
③:打印输出
计算公式:计算时分秒
小时: h = parseInt(总秒数 / 60 / 60 % 24)
分钟: m = parseInt(总秒数 / 60 % 60 )
秒数: s = parseInt(总秒数 % 60
<script>
//定义函数
function translateTime(time){
//天
day = parseInt(time/60/60/24)
//小时,parseInt()取整100
hour = parseInt(time/60/60%24)
//分钟
min = parseInt(time/60%60)
//秒
second = parseInt(time%60)
//补0!!,注意:要记得用一个值来接收右边的结果
hour = hour < 10? '0' + hour : hour
min = min < 10? '0' + min : min
second = second < 10? '0' + second : second
return [day,hour,min,second]
}
let time = +prompt('请输入秒数')
//调用函数
let arr = translateTime(time)
document.write(`${arr[0]}天${arr[1]}小时${arr[2]}分钟${arr[3]}秒`)
</script>
4.2.2逻辑中断(重要)
开发中,还会见到以下的写法:
其实类似参数的默认值写法
4.2.3转换为Boolean型
显示转换:
1.Boolean(内容)
记忆: ‘’ 、0、undefined、null、false、NaN 转换为布尔值后都是false, 其余则为 true
<script>
console.log(Boolean('pink')) //true
console.log(Boolean('')) //false
console.log(Boolean(0)) //false
console.log(Boolean(90)) //true
console.log(Boolean(-1)) //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)
}
</script>
隐式转换:
- 有字符串的加法 “” + 1 ,结果是 “1”
- 减法 - (像大多数数学运算一样)只能用于数字,它会使空字符串 “” 转换为 0,使数字字符串 “1234” 转换为 1234
- null 经过数字转换之后会变为 0
- **undefined 经过数字转换之后会变为 NaN,undefined做任何操作都是NaN **
null == undefined(true)值相等,数据类型不相等
null === undefined(false)
五、JavaScript 基础第五天
5.1对象
思考:
- 保存网站用户信息,比如姓名,年龄,电话号码… 用以前学的数据类型方便吗?
不方便,很难区分- 我们是不是需要学习一种新的数据类型,可以详细的描述某个事物?
姓名
年龄
电话
……
5.1.1什么是对象
对象(object):JavaScript里的一种数据类型
可以理解为是一种无序的数据集合, 注意数组是有序的数据集合
用来描述某个事物,例如描述一个人
人有姓名、年龄、性别等信息、还有吃饭睡觉打代码等功能
如果用多个变量保存则比较散,用对象比较统一
比如描述 班主任 信息:
静态特征 (姓名, 年龄, 身高, 性别, 爱好) => 可以使用数字, 字符串, 数组, 布尔类型等表示
动态行为 (点名, 唱, 跳, rap) => 使用函数表示
总结:
- 对象是什么?
对象是一种数据类型
无序的数据的集合- 对象有什么特点?
无序的数据的集合
可以详细的描述描述某个事物
5.1.2对象使用
5.1.2.1 对象声明语法
5.1.2.2 对象由属性和方法组成
属性:信息或叫特征(名词)。 比如 手机尺寸、颜色、重量等…
方法:功能或叫行为(动词)。 比如 手机打电话、发短信、玩游戏…
5.1.2.3属性
数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的。
- 属性都是成对出现的,包括属性名和值,它们之间使用英文 : 分隔
- 多个属性之间使用英文 , 分隔
- 属性就是依附在对象上的变量(外面是变量,对象内是属性)
- 属性名可以使用 “” 或 ‘’,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
总结:
- 对象属性有顺序吗?
没有- 属性和值用什么符号隔开?多个属性用什么隔开?
属性和值用 ; 隔开
多个属性用,逗号隔开
练习 • 请声明一个产品对象,里面包如下信息:
要求:
商品对象名字: goods
商品名称命名为: name
商品编号: num
商品毛重: weight
商品产地: addres
<script>
//请声明一个产品对象,里面包如下信息:
// 要求:
// 商品对象名字: goods
// 商品名称命名为: name
// 商品编号: num
// 商品毛重: weight
// 商品产地: address
let goods = {
name : '小米10',
num : 100012816024,
weight : '0.55kg',
address : '中国大陆'
}
console.log(goods) //{name: '小米10', num: 100012816024, weight: '0.55kg', address: '中国大陆'}
</script>
5.1.2.4属性–查
声明对象,并添加了若干属性后,可以使用 ’ . '获得对象中属性对应的值,我称之为属性访问。
语法:对象名.属性
简单理解就是获得对象里面的属性值。
5.1.2.5属性–改
语法:对象名.属性 = 新
5.1.2.6属性–增
语法:对象名.新属性 = 新值
5.1.2.7属性–删
语法:delete 对象名.属性
<script>
let person = {
uname:"张老师",
age:18,
gender:"女"
}
// 属性查 对象.属性
console.log(person.uname) //张老师
console.log(person.age) //18
console.log(person.gender) //女
//属性改 相当于重新赋值
person.age = 19
console.log(person.age) //19
console.log(person) //{uname: '张老师', age: 19, gender: '女'}
//属性增加
person.address = "DGUT"
console.log(person) //{uname: '张老师', age: 19, gender: '女', address: 'DGUT'}
//属性删除
delete person.gender
console.log(person) //{uname: '张老师', age: 19, address: 'DGUT'}
</script>
总结:
- 对象查语法如何写?
对象名.属性- 对象改语法如何写:
对象名.属性 = 新值- 对象增语法如何写:
对象名.新属性名 = 新值
改和增语法一样,判断标准就是对象有没有这个属性,没有就是新增,有就是改
练习 • 请对产品对象,做如下操作:
要求:- 请将商品名称里面的值修改为: 小米10 PLUS
- 新增一个属性颜色 color 为 ‘粉色’
- 请依次页面打印输出所有的属性
<script>
let goods = {
name : '小米10',
num : 100012816024,
weight : '0.55kg',
address : '中国大陆'
}
//请将商品名称里面的值修改为: 小米10 PLUS
goods.name = "小米10 PLUS"
//新增一个属性颜色 color 为 "粉色"
goods.color = "粉色"
//请依次页面打印输出所有的属性值
console.log(goods.name)
console.log(goods.num)
console.log(goods.weight)
console.log(goods.address)
console.log(goods.color)
</script>
5.1.2.8属性-查的另外一种写法(对象循环遍历的时候用)
对于多词属性或着 - 等属性,点操作就不能用了。
我们可以采取: 对象[‘属性’] 方式, 单引号和双引号都阔以
对象[‘属性’] 方式, 单引号和双引号都阔以
也可以用于其他正常属性
[ ]语法里面的值如果不添加引号 默认会当成变量解析
总结:
- 没有必要的时候直接使用点语法, 在需要解析变量的时候使用 [ ] 语法
- 对象访问属性有哪两种方式?
点形式 对象.属性
[ ] 形式 对象[‘属性’]- 两种方式有什么区别?
点后面的属性名一定不要加引号
[ ] 里面的属性名一定加引号
后期不同使用场景会用到不同的写法
5.1.2.9对象中的方法
数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数。
- 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
- 多个属性之间使用英文 , 分隔
- 方法是依附在对象中的函数
- 方法名可以使用 “” 或 ‘’,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
声明对象,并添加了若干方法后,可以使用 . 调用对象中函数,我称之为方法调用。
也可以添加形参和实参
<script>
let obj = {
uname : "张老师",
// function(形参)
sayHi: function(){
console.log("早上好")
},
sum:function(x,y){
console.log(x+y)
}
}
// console.log(obj)
//方法调用,不需要打印
//obj是对象,sayHi(实参)是方法
obj.sayHi() //早上好
obj.sum(1,2) //3
</script>
总结:
- 对象访问方法是如何实现的?
对象.方法()
person.sayHi()- 对象方法可以传递参数吗?
可以,跟函数使用方法基本一致
5.1.3遍历对象
for 遍历对象的问题:
对象没有像数组一样的length属性,所以无法确定长度
对象里面是无序的键值对, 没有规律,没有序号,没有索引号. 不像数组里面有规律的下标
- 一般不用这种方式遍历数组、主要是用来遍历对象
- for in语法中的 k 是一个变量, 在循环的过程中依次代表对象的属性名
- 由于 k 是变量, 所以必须使用 [ ] 语法解析
- 一定记住: k 是获得对象的属性名, 对象名[k] 是获得 属性值
- k是字符串 ‘uname’,不是属性名,如果直接写obj.k 相当于 obj.‘uname’
总结:
- 遍历对象用那个语句?
for in- 遍历对象中, for k in obj,获得对象属性是那个,获得值是那个?
获得对象属性是 k
获得对象值是 obj[k]
<script>
let person = {
uname:"张老师",
age:18,
gender:"女"
}
// for in语法中的 k 是一个变量, 在循环的过程中依次代表对象的属性名
//由于 k 是变量, 所以必须使用 [ ] 语法解析
//一定记住: k 是获得对象的属性名, 对象名[k] 是获得 属性值
//k是字符串 'uname',不是属性名
for(let k in person){
console.log(k)
//如果直接写person.k 相当于 person.'uname'
console.log(person[k])
}
</script>
案例 遍历数组对象
需求:请把下面数据中的对象打印出来:
<script>
//请把下面数据中的对象打印出来
// 定义一个存储了若干学生信息的数组
let students = [
{ name: '小明', age: 18, gender: '男', hometown: '河北省' },
{ name: '小红', age: 19, gender: '女', hometown: '河南省' },
{ name: '小刚', age: 17, gender: '男', hometown: '山西省' },
{ name: '小丽', age: 18, gender: '女', hometown: '山东省' }
]
//students是一个数组
for(let i=0;i<students.length;i++){
console.log(students[i]) //打印出每一个对象
//获取对象的属性值 对象名.属性
console.log(students[i].name)
console.log(students[i].age)
console.log(students[i].gender)
console.log(students[i].hometown)
}
</script>
案例 遍历数组对象
需求:根据以上数据渲染生成表格
<!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>
table {
width: 600px;
text-align: center;
}
table,
th,
td {
border: 1px solid #ccc;
border-collapse: collapse;
}
caption {
font-size: 18px;
margin-bottom: 10px;
font-weight: 700;
}
tr {
height: 40px;
cursor: pointer;
}
table tr:nth-child(1) {
background-color: #ddd;
}
table tr:not(:first-child):hover {
background-color: #eee;
}
</style>
</head>
<body>
<h2>学生信息</h2>
<p>将数据渲染到页面中...</p>
<table>
<caption>学生列表</caption>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>家乡</th>
</tr>
<!-- 前面的都是写死的,所以在这里开始用script渲染 -->
<script>
// 定义一个存储了若干学生信息的数组
let students = [
{ name: '小明', age: 18, gender: '男', hometown: '河北省' },
{ name: '小红', age: 19, gender: '女', hometown: '河南省' },
{ name: '小刚', age: 17, gender: '男', hometown: '山西省' },
{ name: '小丽', age: 18, gender: '女', hometown: '山东省' }
]
//2.渲染页面
//注意:数组下标是从0开始的
for (let i = 0; i < students.length; i++) {
document.write(`
<tr>
<td>${i+1}</td>
<td>${students[i].name}</td>
<td>${students[i].age}</td>
<td>${students[i].gender}</td>
<td>${students[i].hometown}</td>
</tr>
`)
}
</script>
</table>
</body>
</html>
5.1.4内置对象
5.1.4.1内置对象是什么
- JavaScript内部提供的对象,包含各种属性和方法给开发者调用
- 思考:我们之前用过内置对象吗?
document.write()
console.log()
5.1.4.2内置对象Math
介绍:Math对象是JavaScript提供的一个“数学”对象
作用:提供了一系列做数学运算的方法
Math对象包含的方法有:
random:生成0-1之间的随机数(包含0不包括1)
ceil:向上取整
floor:向下取整
max:找最大数
min:找最小数
pow:幂运算
abs:绝对值
Math对象在线文档
<script>
//内置对象Math中的属性
console.log(Math.PI) //3.141592653589793
//内置对象Math中的方法
//Math.ceil()向上取整
console.log(Math.ceil(3.1415)) //4
//向下取整
console.log(Math.floor(3.56)) //3
//四舍五入
console.log(Math.round(3.56))//4
console.log(Math.round(4.46)) //4
console.log(Math.round(-1.5)) //-1
console.log(Math.round(-1.1)) //-1
console.log(Math.round(-1.51)) //-2
//负数的四舍五入以-0.5为界限,小于-0.5减一,大于或者等于-0.5舍去
//正数的四舍五入以0.5为界限,大于等于0.5加一,小于0.5舍去
//最大最小值
console.log(Math.max(1,3,5,8,2,4,6,9)) //9
console.log(Math.min(-1,1,3,5,8,-2,4,6,9)) //-2
//幂运算
console.log(Math.pow(2,3)) //8
//绝对值
console.log(Math.abs(-10)) //10
console.log(Math.abs(100)) //100
</script>
null是一个空对象,当对象还没确定时,可以用null先替代
let obj = null
5.1.4.3生成任意范围随机数
Math.random() 随机数函数, 返回一个0 - 1之间,并且包括0不包括1的随机小数 [0, 1)
- 如何生成0-10的随机数呢?
Math.floor(Math.random()*(10+1))
- 如何生成5-10的随机数?
Math.floor(Math.random()*6 + 5)
- 如何生成N-M之间的随机数
Math.floor(Math.random()*(M-N+1) + N)
<script>
//如何生成0-10的随机数呢?
//Math.random()生成[0,1)的数,
//Math.random()*(10+1)取[0,11)的数
//Math.floor()向下取整,只能取到[0,10]
console.log(Math.floor(Math.random()*(10+1)));
//颜色随机变换
let arr = ['red','green','blue']
console.log(arr[Math.floor(Math.random()*arr.length)])
//如何生成5-10的随机数?
console.log(Math.floor(Math.random()*6 + 5));
//如何生成N-M的随机数?
//Math.floor(Math.random()*(M-N+1) + N)
//封装一个随机数函数,以后直接调用
function random(N,M){
return Math.floor(Math.random()*(M-N+1) + N)
}
console.log(random(5,8));
</script>
案例1 随机点名案例
需求:请把 [‘赵云’, ‘黄忠’, ‘关羽’, ‘张飞’, ‘马超’, ‘刘备’, ‘曹操’] 随机显示一个名字到页面中
分析:
①:利用随机函数随机生成一个数字作为索引号
②: 数组[随机数] 生成到页面
<script>
//需求:请把 [‘赵云’, ‘黄忠’, ‘关羽’, ‘张飞’, ‘马超’, ‘刘备’, ‘曹操’] 随机显示一个名字到页面中
// 分析:
// ①:利用随机函数随机生成一个数字作为索引号
// ②: 数组[随机数] 生成到页面
let arr = ['赵云','黄忠','关羽','张飞','马超','刘备']
let random = Math.floor(Math.random()*arr.length)
document.write(arr[random])
</script>
案例2 随机点名案例改
需求:请把 [‘赵云’, ‘黄忠’, ‘关羽’, ‘张飞’, ‘马超’, ‘刘备’, ‘曹操’] 随机显示一个名字到页面中,但是
不允许重复显示
分析:
①:利用随机函数随机生成一个数字作为索引号
②:数组[随机数] 生成到页面中
③:数组中删除刚才抽中的索引号
<script>
//需求:请把 [‘赵云’, ‘黄忠’, ‘关羽’, ‘张飞’, ‘马超’, ‘刘备’, ‘曹操’] 随机显示一个名字到页面中,但是不允许重复显示
// 分析:
// ①:利用随机函数随机生成一个数字作为索引号
// ②: 数组[随机数] 生成到页面
// ③:数组中删除刚才抽中的索引号
let arr = ['赵云','黄忠','关羽','张飞','马超','刘备','曹操']
let random = Math.floor(Math.random()*arr.length-i)
document.write(arr[random])
arr.splice(random, 1)
console.log(arr)
</script>
案例3 猜数字游戏
需求:程序随机生成 1~10 之间的一个数字,用户输入一个数字
①:如果大于该数字,就提示,数字猜大了,继续猜
②:如果小于该数字,就提示,数字猜小了,继续猜
③:如果猜对了,就提示猜对了,程序结束
需求:程序随机生成 1~10 之间的一个数字,用户输入一个数字
分析:
①:利用随机数生成一个数字
②:需要一直猜,所以需要不断的循环
③:因为条件是结果猜对了,就是判断条件退出,用while循环合适
④:内部判断可以用多分支语句
<script>
//需求:程序随机生成 1~10 之间的一个数字,用户输入一个数字
// ①:如果大于该数字,就提示,数字猜大了,继续猜
// ②:如果小于该数字,就提示,数字猜小了,继续猜
// ③:如果猜对了,就提示猜对了,程序结束
let random = Math.floor(Math.random() * 11)
while(true){
number = +prompt('请输入一个数')
if(number === random){
alert('数字猜对了')
break
}else if(number > random){
alert('数字猜大了,继续猜')
}else{
alert('数字猜小了,继续猜')
}
}
</script>
改进:设定可以猜的次数
<script>
// 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 {
alert('猜对了,真厉害')
//猜对了,把flag改为false,则不会执行下面的if(flag)
//因为flag默认是ture
flag = false
break
}
}
// 写到for的外面来
if (flag) {
alert('次数已经用完')
}
</script>
案例4 生成随机颜色
需求:该函数接收一个布尔类型参数,表示颜色的格式是十六进制还是rgb格式。
①:如果参数传递的是true或者无参数,则输出 一个随机十六进制的颜色
②:如果参数传递的是false,则输出 一个随机rgb的颜色
③:格式:
function getRandomColor(flag){
}
console.log(getRandomColor(true)) //#ffffff
console.log(getRandomColor(false)) //rgb(255,255,255)
分析:
提示: 16进制颜色格式为: ‘#ffffff’ 其中f可以是任意 0-f之间的字符
提示: rgb颜色格式为: ‘rgb(255,255,255) ’ 其中255可以是任意0-255之间的数
需求:该函数接收一个布尔类型参数,表示颜色的格式是十六进制还是rgb格式。
分析:
提示: 16进制颜色格式为: ‘#ffffff’ 其中f可以是任意 0-f之间的字符,需要用到数组,
let arr = [‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’]
提示: rgb颜色格式为: ‘rgb(255,255,255) ’ 其中255可以是任意0-255之间的数字
步骤:
①:如果参数为true或者无参数,则处理16进制颜色,核心思想是循环6次,生成随机的6个数字(取
值范围0~15),根据这个数字去找数组的值,然后和 # 拼接起来,并且返回值。
②:如果参数为false,随机生成一个0~255的数给三个变量,分别作为 r g b 三个颜色,之后拼接字
符串rgb(255,255,255)格式
<script>
//随机生成颜色
//需求:该函数接收一个布尔类型参数,表示颜色的格式是十六进制还是rgb格式。
// ①:如果参数传递的是true或者无参数,则输出 一个随机十六进制的颜色
// ②:如果参数传递的是false,则输出 一个随机rgb的颜色
//flag = true用户不输入时,默认输入true
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=0;i<6;i++){
let random = Math.floor(Math.random() * arr.length)
//字符串拼接
str = 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 `rbg(${r},${g},${b})`
}
}
console.log(getRandomColor(false))
console.log(getRandomColor(true))
console.log(getRandomColor())
</script>
5.2综合案例
案例 学成在线页面渲染案
需求:根据数据渲染列表页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>学车在线首页</title>
<link rel="stylesheet" href="./css/style.css">
<style>
</style>
</head>
<body>
<!-- 4. box核心内容区域开始 -->
<div class="box w">
<div class="box-hd">
<h3>精品推荐</h3>
<a href="#">查看全部</a>
</div>
<div class="box-bd">
<ul class="clearfix">
<!-- <li>
<a href="#">
<img src="images/course01.png" alt="">
<h4>
Think PHP 5.0 博客系统实战项目演练
</h4>
<div class="info">
<span>高级</span> • <span>1125</span>人在学习
</div>
</a>
</li> -->
<script>
// 数据对象
// 里面的每一组对象就是每一个li
let data = [
{
src: 'images/course01.png',
title: 'Think PHP 5.0 博客系统实战项目演练',
num: 1125
},
{
src: 'images/course02.png',
title: 'Android 网络动态图片加载实战',
num: 357
},
{
src: 'images/course03.png',
title: 'Angular2 大前端商城实战项目演练',
num: 22250
},
{
src: 'images/course04.png',
title: 'Android APP 实战项目演练',
num: 389
},
{
src: 'images/course05.png',
title: 'UGUI 源码深度分析案例',
num: 124
},
{
src: 'images/course06.png',
title: 'Kami2首页界面切换效果实战演练',
num: 432
},
{
src: 'images/course07.png',
title: 'UNITY 从入门到精通实战案例',
num: 888
},
{
src: 'images/course08.png',
title: 'Cocos 深度学习你不会错过的实战',
num: 590
},
]
//循环渲染
//1.生成8个li
//2.换数据
for(let i=0;i<data.length;i++){
document.write(`
<li>
<a href="#">
<img src= ${data[i].src} alt="" title="${data[i].title}">
<h4>
${data[i].title}
</h4>
<div class="info">
<span>高级</span> • <span>${data[i].num}</span>人在学习
</div>
</a>
</li>
`)
}
</script>
</ul>
</div>
</div>
</body>
</html>
* {
margin: 0;
padding: 0;
}
.w {
width: 1200px;
margin: auto;
}
body {
background-color: #f3f5f7;
}
li {
list-style: none;
}
a {
text-decoration: none;
}
/* 清除浮动 */
.clearfix:before,.clearfix:after {
content:"";
display:table;
}
.clearfix:after {
clear:both;
}
.clearfix {
*zoom:1;
}
.box {
margin-top: 30px;
}
.box-hd {
height: 45px;
}
.box-hd h3 {
float: left;
font-size: 20px;
color: #494949;
}
.box-hd a {
float: right;
font-size: 12px;
color: #a5a5a5;
margin-top: 10px;
margin-right: 30px;
}
/* 把li 的父亲ul 修改的足够宽一行能装开5个盒子就不会换行了 */
.box-bd ul {
width: 1225px;
}
.box-bd ul li {
position: relative;
top: 0;
float: left;
width: 228px;
height: 270px;
background-color: #fff;
margin-right: 15px;
margin-bottom: 15px;
transition: all .3s;
}
.box-bd ul li a {
display: block;
}
.box-bd ul li:hover {
top: -8px;
box-shadow: 0 15px 30px rgb(0 0 0 / 10%);
}
.box-bd ul li img {
width: 100%;
}
.box-bd ul li h4 {
margin: 20px 20px 20px 25px;
font-size: 14px;
color: #050505;
font-weight: 400;
}
.box-bd .info {
margin: 0 20px 0 25px;
font-size: 12px;
color: #999;
}
.box-bd .info span {
color: #ff7c2d;
}
5.3拓展
5.3.1拓展-术语解释
5.3.2拓展- 基本数据类型和引用数据类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
- 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型
string ,number,boolean,undefined,null - 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型
通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的
栈;
简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
引用数据类型存放到堆里面
<script>
let num1 = 10
let num2 = num1
num2 = 20
console.log(num1) // 结果是? //10
let obj1 = {
age: 18
}
let obj2 = obj1
// 修改属性
obj2.age = 20
console.log(obj1.age) //20
</script>