Web前端必学的 JS 入门教程

1. JavaScript介绍

1.1 JavaScript 是什么

1. JavaScript (是什么?)

是一种运行在客户端(浏览器)的编程语言,实现人机交互效果

2. 作用(做什么?)

网页特效(监听用户的一些行为让网页作出对应的反馈)

表单验证(针对表单数据的合法性进行判断)

数据交互(获取后台的数据,渲染到前端)

服务端编程(node.js)

3. JavaScript的组成(有什么?)

 ECMAScript:

规定了js基础语法核心知识。

比如:变量、分支语句、循环语句、对象等等

Web APIs:

DOM 操作文档,比如对页面的元素进行移动、大小、添加删除等操作

BOM 操作浏览器,比如页面弹窗,检测窗口宽度、存储数据到浏览器等等

权威网站:MDN

1.2 JavaScript 书写位置

1. 内部 JavaScript

直接写在html文件里,用script标签包住

规范:script标签写在</body>上面

注意事项

我们将<script>放在HTML文件的底部附近的原因是浏览器会按照代码在文件中的顺序加载HTML

如果先加载的 JavaScript 期望修改其下方的 HTML,那么它可能由于 HTML 尚未被加载而失效

因此,将JavaScript 代码放在 HTML页面的底部附近通常是最好的策略

2. 外部 JavaScript

代码写在以 .js结尾的文件里

语法:通过script标签,引入到html页面中

注意事项

1. script标签中间无需写代码,否则会被忽略!

2. 外部JavaScript会使代码更加有序,更易于复用,且没有了脚本的混合,HTML也会更加易读,因此这是个好的习惯

3. 内联 JavaScript

代码写在标签内部

语法:

注意:此处作为了解即可,但是后面vue框架会用这种模式

1.3 JavaScript 的注释

1. 单行注释

  • 符号://
  • 快捷键:ctrl + /

2. 块注释

  • 符号:/* */
  • 快捷键:shift + alt + A

1.4 JavaScript的结束符

1. 结束符

  • 代表语句结束
  • 英文分号
  • 可写可不写
  • 换行符(回车)会被识别成结束符,所以一个完整的语句,不要手动换行
  • 因此在实际开发中有许多人主张书写 JavaScript 代码时省略结束符
  • 但为了风格统一,要写结束符就每句都写,要么每句都不写(按照团队要求)

1.5 输入和输出语法

1. 输出语法:

document.write('要输出的内容')
  • 向body内输出内容
  • 如果输出的内容写的是标签,也会被解析成网页元素
alert('要输出的内容')
  • 页面弹出警告对话框
console.log('控制台打印')
  • 控制台输出语法,程序员调试使用

2. 输入语法:

prompt('请输入您的姓名:')
  • 显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字

1.6 字面量

在计算机科学中,字面量(literal)是在计算机中描述 事 / 物

比如:[] 数组字面量  {} 对象字面量 等等

2. 变量

2.1 变量是什么

变量不是数据本身,变量是计算机存储数据的容器。可以理解为是一个个用来装东西的纸箱子。

2.2 变量基本使用

1. 声明变量:

要想使用变量,首先需要创建变量

语法:

let 变量名

  • 声明变量有两部分构成:声明关键字、变量名(标识)
  • let 即关键字(let:允许、许可、让、要),所谓关键字是系统提供的专门用来声明(定义)变量的词语

let age

age为变量名,也叫标识符

2. 变量赋值:

定义了一个变量后,你就能够初始化它(赋值)。在变量名之后跟上一个“=”,然后是数值。

注意:是通过变量名来获取变量里面的数据

3. 更新变量:

变量赋值后,还可以通过简单地给它一个不同的值来更新它

注意:let不允许多次声明一个变量

4. 声明多个变量

变量赋值后,还可以通过简单地给它一个不同的值来更新它

let age = 19, uname = 'ww'

/* 用户输入内容,浏览器输出程序

第一步:输入:用户输入框:prompt()
第二步:内部处理:保存数据
第三步:输出:页面打印document.write() */
<script>
    let name = prompt('请输入:')
    document.write(name)
</script>

 

/* 交换变量的值

步骤:
1.声明一个临时变量temp
2.把num1的值赋值给temp
3.把num2的值赋值给num1
4.把temp的值给num2 */
<script>
    let num1 = 10
    let num2 = 20
    let temp
    temp = num1
    num1 = num2
    num2 = temp
    console.log(num1, num2)
</script>

 

2.3 变量的本质

内存:计算机中存储数据的地方,相当于一个空间

变量:是程序在内存中申请的一块用来存放数据的小空间

2.4 变量命名规则与规范

规则:必须遵守,不遵守报错

规范:建议,不遵守不会报错,但不符合业内通识

1. 规则:

  • 不能用关键字
    • 关键字:有特殊含义的字符,JavaScript 内置的一些英语词汇。例如:let、var、if、for等
  • 只能用下划线、字母、数字、$组成,且数字不能开头
  • 字母严格区分大小写,如Age和age是不同的变量

2. 规范:

  • 起名要有意义
  • 遵守小驼峰命名法
    • 第一个单词首字母小写,后面每个单词首字母大写。

拓展-let和var的区别

let为了解决var的一些问题

var声明:

  • 可以先使用在声明(不合理)
  • var声明过的变量可以重复声明(不合理)
  • 比如变量提升、全局变量、没有块级作用域等等

变量拓展-数组

  • 数组(Array)是一种可以按顺序保存多个数据

1.1 数组的基本使用

1. 声明语法

let 数组名 = [数据1, 数据2, ..., 数据n]
  • 数组是按顺序保存,所以每个数据都有自己的编号
  • 在数组中,数据的编号也叫索引或下标

2. 一些术语:

  • 元素:数组中保存的每个数据都叫数组元素
  • 下标:数组中数据的编号
  • 长度:数组中数据的个数,通过数组的length属性获得

3. 数据类型

3.1 数据类型

计算机世界中的万事万物都是数据

计算机程序可以处理大量的数据,为什么要给数据分类

  • 更加充分和高效的利用内存
  • 也更加方便程序员使用数据

JS数据类型整体分为两大类

  • 基本数据类型
    • number 数字型
    • string 字符串型
    • boolean 布尔型
    • undefined 未定义型
    • null 空类型
  • 引用数据类型
    • object 对象
    • function 函数
    • array 数组

3.2 数据类型 - 数字类型(number)

即我们数学中学习到的数字,可以是整数、小数、正数、负数。

JavaScript中的正数、负数、小数等 统一称为 数字类型

注意事项

  • JS是弱数据类型,变量到底属于哪种类型,只有赋值之后,我们才能确认
  • Java是强数据类型 例如 int a = 3 必须是整数

3.2 数据类型 - 字符串类型(string)

通过单引号('')、双引号("")或反引号(`)包裹的数据都叫字符串,单引号和双引号没有本质上的区别,推荐使用单引号

注意事项:

  • 无论单引号或是双引号必须成对使用
  • 单引号/双引号可以互相嵌套,但是不以自己嵌套自己(口诀:外双内单,或者外单内双)
  • 必要时可以使用转义符 \,输出单引号或双引号

字符串拼接:+

模板字符串

1. 作用

  • 拼接字符串和变量
  • 在没有它之前,要拼接变量比较麻烦
document.write('大家好,我叫' + name + ',今年' + age + '岁')

2. 符号

  • ``
  • 在英文输入模式下按键盘的tab上方那个键(1左边那个键)
  • 内容拼接变量时,用${}包住变量
  • 用反引号包含的内容可以换行
document.write(`大家好,我叫${name},今年${age}岁`)

 

// 页面输出用户信息案例
<script>
    let uname = prompt('请输入您的姓名:')
    let age = prompt('请输入您的年龄:')
    document.write(`您是${uname},今年${age}岁啦`)
</script>

3.3 数据类型 - 布尔类型(boolean)

表示肯定或否定时在计算机中对应的是布尔类型数据

它有两个固定的值 true和false,表示肯定的数据用true(真),表示否定的数据用false(假)

3.4 数据类型 - 未定义类型(undefined)

未定义是比较特殊的类型,只有一个值 undefined

什么情况出现未定义类型?

只声明变量不赋值,变量的默认值为undefined,一般很少【直接】为某个变量赋值为undefined

情况说明结果
let age; console.log(age) 只声明 不赋值 undefined
console.log(age) 不声明 不赋值 直接使用 报错
age = 10; console.log(age) 不声明 只赋值 10(不提倡)

工作中的使用场景

我们开发中经常声明一个变量,等待传送过来的数据。

如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,就判断用户是否有数据传递过来

3.5 数据类型 - 空类型(null)

null表示值为空

let obj = null

null和undefined区别:

  • undefined表示没有赋值
  • null表示赋值了,但是内容为空

null开发中的使用场景:

官方解释:把null作为尚未创建的对象

大白话:将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null

 3.6 控制台输出语句和检测数据类型

1. 控制台输出语句

  • 控制台语句经常用于测试结果来使用
  • 可以看出数字型和布尔型颜色为蓝色,字符串和undefined颜色为灰色

2. 通过typeof关键字检测数据类型

let age = 18
let unage = '白羊'
let flag = false
let buy
console.log(typeof age) // number
console.log(typeof uname) // string
console.log(typeof flag) // boolean
console.log(typeof buy) // undefined

 

4. 类型转换

4.1 为什么要类型转换

JavaScript是弱数据类型:JavaScript也不知道变量到底属于哪种数据类型,只有赋值了才清楚

坑:使用表单、prompt获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算

此时需要转换变量的数据类型

通俗来说,把一种数据类型的变量转换成我们需要的数据类型

4.2 隐式转换

某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换为隐式转换

规则:

  • +号两边只要有一个是字符串,都会把另外一个转成字符串
  • 除了+以外的算术运算符 比如- * / 等都会把数据转成数字类型

缺点:

  • 转换类型不明确,靠经验才能总结

小技巧:

  • +号作为正号解析可以转换成Number

4.3 显式转换

编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换

概念:

自己写代码告诉系统该转成什么类型

转换为数字型

  • Number(数据)
    • 转成数字类型
    • 如果字符串内容里有非数字,转换失败时结果为NaN (Not a Number)即不是一个数字
    • NaN也是number类型的数据,代表非数字
  • parseInt(数据)
    • 只保留整数
  • parseFloat(数据)
    • 可以保留小数
  • parseInt和parseFloat常用作过滤单位:parseInt(100px)

转换为字符型:

  • String(数据)
  • 变量.toString(进制)
console.log(String(10))
let age = 10
console.log(age.toString())
// 将10转为二进制
console.log(age.toString(2))

 用户订单信息案例

<style>
    * {
        margin: 0;
        padding: 0;
    }
    
    table {
        margin: 0 auto;
        text-align: center;
        border-collapse: collapse;
    }
    
    table th,
    td {
        border: 1px solid #000;
        padding: 15px;
    }
    
    table caption {
        margin: 15px 0;
    }
</style>
<body>
    <script>
        // 需要输入3个数据,所以需要3个变量来存储 price num address
        let price = prompt('请输入商品价格:')
        let num = prompt('请输入商品数量:')
        let address = prompt('请输入收货地址:')
            // 需要计算总的价格total
            // *为隐式转换,把字符串转成数字类型
        let total = price * num
            // 页面打印生成表格,里面填充数据即可
            // 记得最好使用模板字符串
        document.write(`
            <table>
                <tbody>
                    <caption>用户订单信息案例</caption>
                    <tr>
                        <th>商品名称</th>
                        <th>商品价格</th>
                        <th>商品数量</th>
                        <th>总价</th>
                        <th>收货地址</th>
                    </tr>
                    <tr>
                        <td>小米手机青春PLUS</td>
                        <td>${price}元</td>
                        <td>${num}</td>
                        <td>${total}元</td>
                        <td>${address}</td>
                    </tr>
                </tbody>
            </table>
        `)
    </script>
</body>

5. 运算符

5.1 算术运算符

数学运算符也叫算术运算符,主要包括加、减、乘、除、取余(求模)

  • +:求和
  • -:求差
  • *:求积
  • /:求商
  • %:取模(取余数)
    • 开发中经常作为某个数字能否被整除

同时使用多个运算符编写程序时,会按着某种顺序先后执行,我们称为优先级。

JavaScript中 优先级越高越先被执行,优先级相同时从左向右执行

  • 乘、除、取余优先级相同
  • 加、减优先级相同
  • 乘、除、取余优先级大于加、减
  • 使用()可以提升优先级
  • 总结:先乘除后加减,有括号先算括号里面的~~~

计算圆的面积案例

<script>
    // 计算圆的面积方法一
    let r = prompt('请输入圆的半径:')
    let result = 3.14 * r * r
    document.write(`计算之后圆的面积是:${result}`)
        // 计算圆的面积方法二
    let r = prompt('请输入圆的半径:')
    document.write(`计算之后圆的面积是${3.14 * r * r}`)
</script>

5.2 赋值运算符

赋值运算符:对变量进行赋值的运算符

  • 已经学过的赋值运算符:= 将等号右边的值赋予给左边,要求左边必须是一个容器
  • 其他赋值运算符:
    • +=
      • <script>
            let num = 18
            num += 1 // 也就是 num = num + 1
            console.log(num);
        </script> 
    • -=
    • *=
    • /=
    • %=

5.3 一元运算符

众多的JavaScript的运算符可以根据所需表达式的个数,分为一元运算符、二元运算符、三元运算符

  • 二元运算符:
let num = 10 +20
  •  一元运算符:
    • 正负号

以前自加1

let num = 10
num = num + 1 // num+=1

更简便的写法

  • 自增:
    • 符号:++
    • 作用:让变量的值+1
  • 自减:
    • 符号:--
    • 作用:让变量的值-1
  • 使用场景:
    • 经常用于计数来使用。比如进行10次操作,用它来计算进行了多少次了

前置自增

  •  每执行1次,当前变量数值+1
  • 作用相当于num += 1

 前置自增和后置自增单独使用没有区别

 but:

  • 前置自增和后置自增独立使用时二者并没有差别!
  • 一般开发中我们都是独立使用
  • 后面i++后置自增会使用相对较多

面试题

5.4 比较运算符

1. 比较运算符的介绍

作用:比较两个数据大小,是否相等

2. 比较运算符的使用

>、<、>=、<=、==:左右两边是否相等、!=:不相等、===:左右两边是否类型和值都相等、!==:左右两边是否不全等

比较结果为boolean类型,即只会得到true或false

3. 比较运算符的细节

字符串比较,是比较的字符对应的ASCII码

  • 从左往右依次比较
  • 如果第一位一样再比较第二位,以此类推
  • 比较的少,了解即可

NaN不等于任何值,包括它本身

尽量不要比较小数,因为小数有精度问题

不同类型之间比较会发生隐式转换

5.5 逻辑运算符

1. 逻辑运算符的使用

逻辑运算符
符号 名称
&& 逻辑与
|| 逻辑或
! 逻辑非

 2.逻辑运算符里的短路

短路:只存在于&&和||中,当满足一定条件会让右边代码不执行

符号 短路条件
&& 左边为false就短路
|| 左边为true就短路

原因:通过左边能得到整个式子的结果,因此没必要再判断右边

运算结果:无论&&还||,运算结果都是最后被执行的表达式值,一般用在变量赋值

console.log(false && 20) // false
console.log(5 < 3 && 20) // false
console.log(undefined && 20) // undefined
console.log(null && 20) // null
console.log(0 && 20) // 0
console.log(10 && 20) // 20 不短路以 后面的为准
// 有5个值是当 false 来看的:fasle、 数字0、 ''、 undefined、 null、NaN
console.log(false || 20) // 20
console.log(5<3 || 20) // 20
console.log(undefined || 20) // 20
console.log(null || 20) // 20
console.log(0 || 20) // 20
console.log(10 || 20) // 10

 

// 判断一个数是4的倍数,且不是100的倍数
<script>
    let num = prompt('请输入:')
    console.log(num % 4 === 0 && num % 100 !== 0)
</script>

 

let num = prompt('请输入:')
num = num || 0 // 如果用户不输入,则返回0
console.log(num)

5.6 运算符优先级

优先级 运算符 顺序
1 小括号 ()
2 一元运算符 ++     --    !
3 算数运算符 先 * / % 后 + -
4 关系运算符 >   >=   <   <=
5 相等运算符 ==   !=   ===   !==
6 逻辑运算符 先 && 后 ||
7 赋值运算符 =
8 逗号运算符 ,
  • 一元运算符里面的逻辑非优先级很高
  • 逻辑与比逻辑或优先级高

6. 语句

6.1 表达式和语句

  • 表达式是一组代码的集合,JavaScript解释器会将其计算出一个结果
x = 7
3 + 4
num++

语句:

  • js 整句或命令,js 语句是以分号结束(可以省略)
  • 比如:if语句 for循环语句

区别:

  • 表达式计算出一个值,但语句用来自行以使某件事发生(做什么事)
  • 表达式 3+4
  • 语句 alert() 弹出对话框
  • 其实某些情况,也可以把表达式理解为语句,因为它是在计算结果,也是做事

6.2 分支语句

1. 程序三大流程控制语句

  • 以前我们写的代码,写几句就从上往下执行几句,这种叫顺序结构
  • 有的时候要根据条件选择执行代码,这种就叫分支结构
  • 某段代码被重复执行,就叫循环结构

分支语句可以让我们有选择性的执行想要的代码

分支语句包含:

  • lf分支语句
  • 三元运算符
  • switch语句

2. if 语句

if语句有三种使用:单分支、双分支、多分支

单分支使用语法:

if (条件) {
    满足条件要执行的代码
}
  • 括号内的条件为true时,进入大括号里执行代码
  • 小括号内的结果若不是布尔类型时,会发生隐式转换转为布尔类型

双分支if语法:

if (条件) {
    满足条件要执行的代码
} else {
    不满足条件执行的代码
}
// 用户输入,如果工龄大于等于3年,年底奖金+2000,否则年底没奖金
<script>
    let age = prompt('请输入工龄:')
    let money = 20000
    if (age >= 3){
        `您的工资为${money + 2000}`
    } else {
        `您的工资为${money}`
    }
</script>
让用户输入年份,判断这一年是闰年还是平年并输出
// 能被4整除但不能被100整除,或者被400整除的年份是闰年,否则都是平年
<script>
    // 因为prompt获取的是字符串,需要转为数字类型
    let year = +prompt('请输入年份:')
    if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) {
        alert(`${year}是闰年`)
    } else {
        alert(`${year}是平年`)
    }
</script>

多分支if语法:

if (条件1) {
    代码1
} else if (条件2) {
    代码2
} else if (条件3) {
    代码3
} else {
    代码n
}

 释义:

  • 先判断条件1,若满足条件1就执行代码1,其他不执行
  • 若不满足则向下判断条件2,满足条件2执行代码2,其他不执行
  • 若依然不满足继续往下判断,依次类推
  • 若以上条件都不满足,执行else里的代码n
  • 注:可以写N个条件,但这里演示只写2个

多分支if课堂案例:根据输入不同时间,输出不同的问候语注:

// 12点以前,输出上午好;18点以前,输出下午好;20点以前,输出晚上好
<script>
    let time = prompt('请输入现在的小时数:')
    if (time < 12) {
        prompt(`上午好,好好学习`)
    } else if (time < 18) {
        prompt(`下午好,好好学习`)
    } else if (time < 20) {
        prompt(`晚上好,好好学习`)
    } else {
        prompt(`夜深了,好好睡觉`)
    }
</script>

2. 三元运算符

  • 其实是比if 双分支更简单的写法,有时候也叫做三元表达式
  • 符号:?与∶配合使用

语法:

条件 ? 满足条件执行的代码 : 不满足条件执行的代码
  • 一般用来取值
<script>
    // 例:
    console.log(true ? 1 : 2)  // 1
    console.log(false ? 1 : 2)  // 2
</script>
// 判断两个数的大小
let num1 = +prompt('请输入第一个数:')
let num2 = +prompt('请输入第二个数:')
let result = num1 > num2 ? num1 : num2
document.write(`${result}大`)
<script>
    // 数字补0案例
    // 需要:用户输入1个数,如果数字小于10,则前面进行补0,比如09 03等
    // 分析:1.为后期页面显示时间做铺垫 2.利用三元运算符补0计算
    let num = prompt('请输入:')
    let time = num >= 10 ? num : 0 + num
        // let time = num < 10 ? num : 0 + num
    document.write(time)
</script>

 3. switch语句

switch (数据) {
    case 值1:
        代码1
        break
    case 值2:
        代码2
        break
    default:
        代码n
        break
}

释义:

找到跟小括号里数据全等的case值,并执行里面对应的代码

数据和值若没有全等 === 的则执行default里的代码

1. switch case语句一般用于等值判断,不适合于区间判断

2. switch case一般需要配合break关键字使用,没有break会造成case穿透

switch (1) {
    case 1:
        alert(1)
        break
    case 2:
        alert(2)
        break
    case 3:
        alert(3)
        break
    default:
        alert('没有数据')
}

 简单计算器

/* 简单计算器
需求: 用户输入2个数字, 然后输入 + - * / 任何一个,可以计算结果
分析:
1. 用户输入数字
2. 用户输入不同算术运算符, 可以去执行不同的运算(switch) */
let num1 = +prompt('请输入第一个数:')
let num2 = +prompt('请输入第二个数:')
let fuhao = prompt('请输入运算符号:')
switch (fuhao) {
    case '+':
        alert(`${num1} + ${num2} = ${num1 + num2}`)
        break
    case '-':
        alert(`${num1} - ${num2} = ${num1 - num2}`)
        break
    case '*':
        alert(`${num1} * ${num2} = ${num1 * num2}`)
        break
    case '/':
        alert(`${num1} / ${num2} = ${num1 / num2}`)
        break
    default:
        alert('请输入+ - * /这些运算符号!')
}

6.3 循环语句

1. 断点调试

  • 作用:学习时可以帮助更好的理解代码运行,工作时可以更快找到bug
  • 浏览器打开调试界面
    • 1. 按F12打开开发者工具
    • 2. 点到sources一栏
    • 3. 选择代码文件
    • 4. 想在哪一行打断点,点击它的行号即可
    • 5. 刷新

2. while循环

1. 循环:重复执行某段代码,而while:在...期间

while (循环条件) {
    要重复执行的代码(循环体)
}

 

释义:

  • 跟if语句很像,都要满足小括号里的条件为true才会进入执行代码
  • while大括号里代码执行完毕后不会跳出,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到小括号判断条件,直到括号内条件不满足,即跳出

2. while循环注意事项:

循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。所以,循环需要具备三要素:

  • 1. 变量起始值
  • 2. 终止条件(没有终止条件,循环会一直执行,造成死循环)
  • 3. 变量变化量(用自增或者自减)
// 循环三要素
// 1. 变量起始值
let i = 1
    // 2. 终止条件
while (i <= 10) {
    document.write(`月薪过万 <br>`)
        // 变量变化
    i++
}

 

// 页面输出1~10
// 起始值
let i = 1
    // 终止条件
while (i <= 10) {
    document.write(`${i} <br>`)
        // 变量变化
    i++
}

 

// 输出1~100的累加和
// 起始值
let i = 1
let sum = 0
    // 终止条件
while (i <= 100) {
    sum = sum + i
        // 变量变化
    i++
}
document.write(`1~100的累加和是${sum}`)
// 计算1~100之间的所有偶数和
let i = 1
    // 声明累加和的变量 sum
let sum = 0
while (i <= 100) {
    // 首先利用if语句把i里面的是偶数筛选出来
    if (i % 2 === 0) {
        // 把筛选的i加到sum里面
        sum = sum + i
    }
    i++
}
document.write(`1~100之间所有偶数和:${sum}`)

 

// 页面弹框案例
let love = ''
    // 当条件为true时,才会向下执行
while (love !== '爱') {
    love = prompt('Do you love me?')
}

 简易取款机

// 循环的时候,需要反复提示输入框,所以提示框写到循环里面
let str = ''
    // 提前准备一个金额预先存储一个数额
let money = 100
    // 退出的条件是用户输入4(用户只要不输4就不退出)
while (str !== '4') {
    str = prompt(`
    请选择您的操作:
    1. 取款
    2. 存款
    3. 查看余额
    4. 退出
    `)
        // 输入不同的值,可以使用switch来执行不同的操作
    switch (str) {
        case '1':
            let qu = +prompt('请输入取款金额:')
            money = money - qu
            break
        case '2':
            let cun = +prompt('请输入存款金额:')
            money = money + cun
            break
        case '3':
            alert(`您还有${money}元`)
            break
    }
}

 

分别输入四季度的数据得到柱形图

<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>
<body>
    <script>
        let arr = []
        for (let i = 1; i <= 4; i++) {
            arr.push(+prompt(`请输入第${i}季度的数据`))
        }
        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>`)
    </script>
</body>

 7 循环 - for

7.1 for循环基本使用

1. for循环语法

也是重复执行代码

好处:把声明起始值、循环条件、变化值写到一起,让人一目了然

for (声明记录循环次数的变量(相当于起始条件); 循环条件; 变化值(相当于变化量)) {
    循环体
}
// 页面输出十句“月薪过万”
for (let i = 1; i <= 10; i++) {
    document.write(`月薪过万 <br>`)
}
// 利用for循环输出1~100岁
for (let i = 1; i <= 100; i++) {
    document.write(`我今年${i}岁了 <br>`)
}
// 求1~100之间所有的偶数和
let sum = 0
for (let i = 1; i <= 100; i++) {
    if (i % 2 === 0) {
        sum = sum + i
    }
}
document.write(`1~100之间所有的偶数和:${sum}`)
// 页面中打印5个心形
for (let i = 1; i <= 5; i++) {
    document.write('❤️‍🔥')
}

2. 遍历数组

// 页面中打印['马超', '赵云', '张飞', '关羽', '黄忠']
let arr = ['马超', '赵云', '张飞', '关羽', '黄忠']
    /*
    document.write(arr[0])
    document.write(arr[1])
    document.write(arr[2])
    document.write(arr[3])
    document.write(arr[4])
    */
for (let i = 0; i < arr.length; i++){
// for (let i = 0; i <= 4; i++) {
    document.write(`${arr[i]} <br>`)
}

7.2 退出循环

1. for循环和while循环有什么区别

  • 当明确了循环的次数的时候推荐使用for循环
  • 当不明确循环的次数的时候推荐使用while循环

2. 循环结束

  • continue:结束本次循环,断续下次循环
  • break:跳出所在的循环
for (let i = 1; i < 6; i++) {
    if (i === 4) {
        // continue   // 1235
        break   // 123
    }
    document.write(i)
}

7.3 循环嵌套

for 循环嵌套

for (外部声明记录循环次数的变量; 循环条件; 变化值) {
    for (内部声明记录循环次数的变量; 循环条件; 变化值) {
        循环体
    }
}

一个循环里再套一个循环,一般用在for循环里

for (let i = 1; i < 6; i++) {
    for (let j = 1; j < 6; j++) {
        document.write('❤️‍🔥')  // 在一行中输出25个心心
    }
}

 记忆单词案例

for (let i = 1; i < 4; i++) {
    document.write(`第${i}天 <br>`)
    for (let j = 1; j < 6; j++) {
        document.write(`第${j}个单词 <br>`)
    }
}
// 运行结果如下

 

// 打印五行五列💖
// 外层循环控制打印行
for (let i = 1; i < 6; i++) {
    // 里层循环控制每行打印几个(列)
    for (let j = 1; j < 6; j++) {
        document.write('💖')
    }
    // 五个心打印完了换行
    document.write('<br>')
}
// 用户输入需要,打印对应的💖
let row1 = prompt('请输入行数:')
let row2 = prompt('请输入列数')
for (let i = 1; i <= row1; i++) {
    // 里层循环控制每行打印几个(列)
    for (let j = 1; j <= row2; j++) {
        document.write('💖')
    }
    // 五个心打印完了换行
    document.write('<br>')
}

 

// 打印直角三角形💖
    /*
        1. 利用双重for循环
        2. 外层循环控制打印行,内层循环控制每行打印几个(列)
        3. 内层循环的个数跟第几行是一一对应的
    */
for (let i = 1; i < 6; i++) {
    for (let j = 1; j <= i; j++) {
        document.write('💖')
    }
    document.write('<br>')
}

 

<style>
    div {
        display: inline-block;
        line-height: 25px;
        margin: 5px;
        background-color: pink;
        padding: 0 10px;
        border: 1px solid hotpink;
        color: deeppink;
        border-radius: 5px;
        box-shadow: 2px 2px 2px rgba(0, 0, 0, .2);
        text-align: center;
    }
</style>
<script>
    // 打印九九乘法表
    for (let i = 1; i < 10; i++) {
        for (let j = 1; j <= i; j++) {
            document.write(`
            <div>${j} X ${i} = ${i * j}</div>
            `)
        }
        document.write('<br>')
    }
</script>

8. 数组

8.1 数组是什么

  • 数组(Array)是一种可以按顺序保存数据的数据类型
  • 为什么要数组?
    • 思考:如果我想保存一个班里5个人的姓名怎么办?
    • 如果有多个数据可以用数组保存起来

8.2 数组的基本使用

1. 声明语法

let 数组名 = [数据1, 数据2, ..., 数据n]
  • 数组是按顺序保存,所以每个数据都有自己的编号
  • 计算机中的编号从0开始
  • 在数组中,数据的编号也叫索引或下标
  • 数组可以存储任意类型的数据

2. 取值语法

数组名[下标]

通过下标取数据

3. 一些术语

  • 元素:数组中保存的每个数据都叫数组元素
  • 下标:数组中数据的编号
  • 长度:数组中数据的个数,通过数组的length属性获得
let names = ['小明', '小刚', '小红', '小丽', '小米']
console.log(names[0]) // 小明
console.log(names[1]) // 小刚
console.log(names.length) // 5

 

4. 遍历数组

  • 用循环把数组中每个元素都访问到,一般会用for循环遍历
for (let i = 0; i < 数组名.length; i++) {
    数组名[i]
}

 

let nums = [10, 20, 30, 40, 50]
for (let i = 0; i < nums.length; i++) {
    document.write(nums[i])
}

 

// 求数组[2, 6, 1, 7, 4]里面所有元素的和以及平均值
let arr = [2, 6, 1, 7, 4]
    // 声明求和变量sum
let sum = 0
    // 声明平均值
let average = 0
    // 遍历数组,把里面每个数组元素加到sum里面
    // 因 数组下标从0开始,所以i = 0
for (let i = 0; i < arr.length; i++) {
    sum = sum + arr[i]
}
// 用求和变量sum除以数组的长度就可以得到数组的平均值
average = sum / arr.length
document.write(`这个同学的总分是:${sum},平均分是:${average}`)
// 求数组[2, 6, 1, 77, 52, 25, 7]中的最大值
let arr = [2, 6, 1, 77, 52, 25, 7]
    // 声明一个保存最大元素的变量max
let max = 0
    // 默认最大值可以取数组中的第一个元素
max = arr[0]
    // 遍历这个数组,把里面每个数组元素和max相比较
for (let i = 1; i < arr.length; i++) {
    // 如果这个数组元素大于max,就把这个数组存到max里面,否则继续下一轮比较
    if (max < arr[i]) {
        max = arr[i]
    }
}
// 最后输出max
document.write(`这个数组中的最大值是:${max}`)

 

5. 操作数组

数组本质是数据集合,操作数据无非就是 增 删 改 查 语法:

 

 

1. 数组增加新的数据

数组.push()方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度(重点)

语法:

arr.push(元素1, ..., 元素n)
// 例:
let arr = ['hot', 'green']
document.write(arr.push('blue', 'yellow')) // 4
document.write(arr)  // hot,green,blue,yellow

arr.unshift(新增的内容)方法将一个或多个元素添加到数组的开头,并返回该数组的新长度,用法同push

语法:

arr.unshift(元素1, ..., 元素n)

 数组筛选:将[2, 0, 6, 1, 77, 0, 52, 0, 25, 7]中大于等于10的元素选出来,放入新数组

        /*
            1. 声明一个新的数组用于存放新数据newArr
            2. 遍历原来的旧数组,找出大于等于10的元素
            3. 依次追加给新数组newArr
        */
        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])
            }
        }
        document.write(newArr)

 

// 数组筛选:将[2, 0, 6, 1, 77, 0, 52, 0, 25, 7]中不等于0的元素选出来,放入新数组
        /*
            1. 声明一个新的数组用于存放新数据newArr
            2. 遍历原来的旧数组,找出不等于0的元素
            3. 依次追加给新数组newArr
        */
        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])
            }
        }
        document.write(newArr)

 

2.  数组删除元素

数组.pop()方法从数组中删除最后一个元素,并返回该元素的值

语法:

arr.pop()

数组.shift()方法从数组中删除第一个元素,并返回该元素的值

语法:

arr.shift()

 数组.splice()方法 删除指定元素

语法:

arr.splice(start, deleteCount)
// arr.splice(起始位置, 删除几个元素)
  • start 起始位置
    • 指定修改的开始位置(从0计数)
  • deleteCount:
    • 表示要移除的数组元素的个数
    • 可选的。如果省略则默认从指定的起始位置删除到最后

删除元素的使用场景:

  • 随机抽奖,中奖的用户就需要从数组里面删除,不允许重复抽奖
  • 点击删除按钮,相关的数据会从商品数据中删除

9. 冒泡排序

冒泡排序是一种简单的排序算法。

它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

比如数组[2,3,1,4,5]经过排序成为了[1,2,3,4,5]或者[5,4,3,2,1]

// 冒泡排序
let arr = [2, 6, 4, 3, 5, 1]
    // 外层循环控制趟数,循环4次,arr.length - 1
for (let i = 0; i < arr.length - 1; i++) {
    // 里层循环控制一趟交换几次,arr.length - i - 1
    for (let j = 0; j < arr.length - i - 1; j++) {
        // 交换两个变量
        if (arr[j] > arr[j + 1]) {
            let temp = arr[j]
            arr[j] = arr[j + 1]
            arr[j + 1] = temp
        }
    }
}
document.write(arr)

// 根据用户输入的数据生成柱形图

// 第一步 构建基本结构
<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>
<body>
    <div class="box">
        <div style="height: 123px;">
            <span>123</span>
            <h4>第一季度</h4>
        </div>
        <div style="height: 156px;">
            <span>156</span>
            <h4>第二季度</h4>
        </div>
        <div style="height: 120px;">
            <span>120</span>
            <h4>第三季度</h4>
        </div>
        <div style="height: 210px;">
            <span>210</span>
            <h4>第四季度</h4>
        </div>
    </div>
</body>
// 第二步 添加js内容
<script>
    // 需要循环4次,所以可以把4个数据放到一个数组里面
    let arr = []
    for (let i = 0; i < arr.length; i++) {
        // 利用循环,弹出4次框,同时存到数组里面
        arr.push(prompt(`请输入第${i}季度的数据:`))
    }
    console.log(arr)
</script>
 1 // 第三步
 2 // 1. 注释body里面的内容,包括js内容
 3 // 2. 加js内容,用js为页面添加盒子
 4 document.write(`<div class="box">`)
 5 document.write(`</div>`)
 6 
 7 // 3. 有四季度,可以使用for循环,在上面第4行和第5行中间添加
 8 for (let i = 1; i <= 4; i++){}
 9 
10 // 4. 在里面任意添加一季度的内容
11 <div style="height: 123px;">
12     <span>123</span>
13     <h4>第一季度</h4>
14 </div>
15 
16 // 5. 取消前面注释的js内容
17 
18 // 最终展示效果如下:
19 <script>
20     // 需要循环4次,所以可以把4个数据放到一个数组里面
21     let arr = []
22     for (let i = 0; i < arr.length; i++) {
23         // 利用循环,弹出4次框,同时存到数组里面
24         arr.push(prompt(`请输入第${i}季度的数据:`))
25     }
26     // console.log(arr)
27     document.write(`<div class="box">`)
28     for (let i = 0; i < arr.length; i++) {
29         document.write(`
30             <div style="height: 123px;">
31                 <span>123</span>
32                 <h4>第一季度</h4>
33             </div>
34         `)
35     }
36     document.write(`</div>`)
37 </script>
// 第四步 更改内容(第三步中的第30、31、32行)
<div style="height: ${arr[i]}px;">
    <span>${arr[i]}</span>
    <h4>第${i + 1}季度</h4>
</div>

// 根据用户输入的数据生成柱形图
// 总体效果如下:
// CSS部分效果不变
<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>
<script>
    // 需要循环4次,所以可以把4个数据放到一个数组里面
    let arr = []
    for (let i = 1; i <= 4; i++) {
        // 利用循环,弹出4次框,同时存到数组里面
        arr.push(prompt(`请输入第${i}季度的数据:`))
    }
    // console.log(arr)
    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>`)
</script>

 10. 函数

10.1 为什么需要函数

function,是被设计为执行特定任务的代码块

说明:

函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用

10.2 函数使用

函数的声明语法

function 函数名() {
    函数体
}
  • 函数名命名规范
    • 和变量命名基本一致
    • 尽量小驼峰式命名法
    • 前缀应该为动词
    • 命名建议:常用动词约定
动词 含义
can

判断是否可执行某个动作

has

判断是否含义某个值

is

判断是否为某个值

get

获取某个值

set

设置某个值

load

加载某些数据

函数的调用语法

// 函数调用,这些函数体内的代码逻辑会被执行
函数名()
  • 注意:声明(定义)的函数必须调用才会真正被执行,使用()调用函数
  • 我们曾经使用的 alert(),parseInt()这种名字后面跟小括号的本质都是函数的调用

函数体

  • 函数体是函数的构成部分,它负责将相同或相似代码“包裹”起来,直到函数调用时函数体内的代码才会被执行。函数的功能代码都要写在函数体当中。
// 打招呼
function sayHi() {
    console.log('嗨~')
}
sayHi()
// 封装一个函数,计算两个数的和
function getSum() {
    let num1 = 10
    let num2 = 20
    document.write(`${num1 + num2}<br>`)
}
getSum()

// 封装一个函数,计算1-100之间所有数的和
function getSum100() {
    let sum = 0
    for (let i = 1; i <= 100; i++) {
        sum += i
    }
    document.write(`1~100之间所有数的和为:${sum}`)
}
getSum100()

 

1. 为什么要有参数的函数

思考:这样的函数只能求 10 + 20,这个函数功能局限非常大

解决办法:把要计算的数字传到函数内

结论:

  • 若函数完成功能需要调用者传入数据,那么就需要用有参数的函数
  • 这样可以极大提高函数的灵活性

2. 有参数的函数声明和调用

声明语法

function 函数名(参数列表){
    函数体
}

参数列表

  • 传入数据列表 
  • 声明这个函数需要传入几个数据
  • 多个数据用逗号隔开

调用语法

函数名(传递的参数列表)
  • 调用函数时,需要传入几个数据就写几个,用逗号隔开

3. 形参和实参

  • 形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
  • 实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
  • 形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值
  • 开发中尽量保持形参和实参个数一致
  • 我们曾经使用过的 alert('打印'), parseInt('11'), Number('11') 本质上都是函数调用的传参
function getSum(num1, num2) {
    document.write(`${num1 + num2}`)
}

 

function getSum100(start, end) {
    let sum = 0
    for (let i = start; i <= end; i++) {
        sum += i
    }
    document.write(`${start},${end}之间所有数的和为:${sum}`)
}
getSum100(1, 100)

 

function getSum100(start, end) {
    let sum = 0
        // 如果调用的时候,我们没有传递实参,默认为0
    start = start || 0
    end = end || 0
    for (let i = start; i <= end; i++) {
        sum += i
    }
    document.write(`${start},${end}之间所有数的和为:${sum}`)
}
getSum100()

 

// 函数封装 - 求学生总分
// 传递过去的参数是一个数组
function getScore(arr) {
    // 封装一个求和函数
    let sum = 0
    // 函数内部遍历数组求和
    for (let i = 0; i < arr.length; i++) {
        sum = sum + arr[i]
    }
    document.write(sum)
}
getScore([100, 100, 100, 100, 100])

10.3 函数返回值

1. 为什么要让函数有返回值

  • 什么是函数
    • 函数是被设计为执行特定任务的代码块
  • 执行完特定任务之后,然后呢?
    • 把任务的结果给我们
  • 缺点:把计算后的结果处理方式写死了,内部处理了
  • 解决:把处理结果返回给调用者
  • 有返回值函数的概念:
    • 当调用某个函数,这个函数会返回一个结果出来
    • 这就是有返回值的函数

2. 用return返回数据

当函数需要返回数据出去时,用return关键字

语法

return 数据

使用方法

function getSum(x, y) {
    return x + y
}
let num = getSum(10, 30)
document.write(num)
function fn() {
    return 20 // 相当于执行了 fn() = 20
}
fn() // 没有返回值,如果需要返回值:document.write(fn())

// 有时函数名字比较长
function getMyResult() {
    return 20
}
document.write(getMyResult()) // 20

// 当我们想要调用时,可以:
let re = getMyResult()
document.write(re)
// 求和函数有返回值,这个函数就只是求和,把结果返回给我们就行了,这个函数不需要打印输出
function getSum(x, y) {
    x = x || 0
    y = y || 0
    return x + y
}
let sum = getSum(1, 2)
    // 什么时候需要它时,就打印输出
document.write(sum)

 

3. 用 return 返回数据

细节:

  • 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
  • 函数内部只能出现 1 次 return,并且 return 后面代码不会再被执行,所以 return 后面的数据不要换行写
  • return 会立即结束当前函数
  • 函数可以没有 return,这种情况函数默认返回值为 undefined
// 求数组中的最大值
function getArrMax(arr) {
    // 声明一个max变量,把数组第一个值给max
    let max = arr[0]
        // 开始遍历数组并比较
    for (let i = 1; i < arr.length; i++) {
        if (max < arr[i]) {
            max = arr[i]
        }
    }
    // 返回这个最大值
    return max
}
let re = getArrMax([2, 5, 3, 9, 7, 8])
document.write(re)

 

// 使用 return 返回多个值
function getReturn(x, y) {
    let plus = x + y
    let minus = x - y
        // return plus minus结果只返回一个值,因为return只能返回一个值
    return [plus, minus]
}
let re = getReturn(10, 50)
document.write(`相加之后的结果:${re[0]}<br> 相减之后的结果:${re[1]}`)

 求数组中的最大值和最小值

function getArrValue(arr) {
    // 声明一个最大值和最小值变量,并把数组中的第一个值赋给它
    let max = min = arr[0]
        // 遍历数组,得到最大值和最小值
    for (let i = 1; i < arr.length; i++) {
        if (max < arr[i]) {
            max = arr[i]
        }
        if (min > arr[i]) {
            min = arr[i]
        }
        /* 第二种:
            max < arr[i] ? max = arr[i]:max
            min > arr[i] ? min = arr[i]:min
        */
        /* 第三种:
            max = max < arr[i] ? arr[i]:max
            min = min > arr[i] ? arr[i]:min
        */
    }
    // 返回最大值和最小值
    return [max, min]
}
let value = getArrValue([20, 50, 30, 90, 40, 10])
document.write(`数组中的最大值:${value[0]},数组中的最小值:${value[1]}`)

 

// 求两个数中的最大值
let num1 = +prompt('请输入第一个数:')
let num2 = +prompt('请输入第二个数:')
    // 比较函数,得出最大值
    // return可以写多个,但是条件只能执行一个
function getMaxValue(num1, num2) {
    /* if (num1 > num2) {
        return num1
    } else {
        return num2
    } */
    return num1 > num2 ? num1 : num2
}
// 实参也可以放变量
let value = getMaxValue(num1, num2)
document.write(value)

10.4 作用域

1. 作用域概述

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

  • 全局作用域
    • 全局有效,作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件
  • 局部作用域
    • 局部有效,作用于函数内的代码环境,就是局部作用域。因为跟函数有关系,所以也称为函数作用域
  • 块级作用域
    • {}内有效,块作用域由 {} 包裹,if 语句和 for 语句里面的 {} 等

2. 变量的作用域

  • 全局变量
    • 函数外部 let 的变量
    • 全局变量在任何区域都可以访问和修改
  • 局部变量
    • 函数内部 let 的变量
    • 局部变量只能在当前函数内部访问和修改
  • 块级变量
    • {} 内部的 let 变量
    • let 定义的变量,只能在块作用域里访问,不能跨块作用域里访问,不能跨块访问,也不能跨函数访问

3. 变量的作用域

变量有一个坑,特殊情况:

如果函数内部或者块级作用域内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐

但是有一种情况,函数内部的形参可以看做是局部变量。

4. 变量访问原则 - 作用域链

  • 只要是代码,就至少有一个作用域
  • 写在函数内部的局部作用域
  • 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
  • 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链

10.5 匿名函数

1. 匿名函数

  • 具名函数
    • 声明:function fn() {}
    • 调用:fn()
  • 匿名函数
    • function() {}

将匿名函数赋值给一个变量,并且通过变量名称进行调用,我们将这个称为函数表达式

语法:

let fn = function() {
    // 函数体
}

调用:

fn() // 函数名

2. 立即执行函数

场景介绍:避免全局变量之间的污染

语法:

// 方式1
(function () {console.log(11)})();
// 方式2
(function () {console.log(11)}());
// 不需要调用,立即执行
  • 注意:多个立即执行函数要用;隔开,要不然会报错

转换时间案例  {用户输入秒数,可以自动转换为时分秒}

// 1. 用户输入总秒数
let seconds = +prompt('请输入秒数:')
    // 2. 计算时分秒(封装函数)里面包含数字补0
function getTimes(t) {
    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
    return `计算之后的时间是${h}小时${m}分${s}秒`
}
// 3. 打印输出
let str = getTimes(seconds)
document.write(str)

 计算公式:计算时分秒

小时:h = parseInt(总秒数 / 60 / 60 % 24)

分钟:m = parseInt(总秒数 / 60 % 24)

秒数:h = parseInt(总秒数 % 60)

// 当不知道有多少实参传过来时
function fn() {
    // arguments 函数内有效,表现形式为伪数组
    // 伪数组比真数组少了一些pop() push()等方法
    console.log(arguments)
    let sum = 0
    for (let i = 0; i < arguments.length; i++) {
        sum += arguments[i]
    }
    console.log(sum)
}
fn(1, 2, 3)
/* // 初:在用户没有传值的时候,会返回0
    function fn(x, y) {
        x = x || 0
        y = y || 0
        document.write(x + y)
    }
    fn() */
// 高:
// x 和 y 可以看做是 函数内部的局部变量
// 调用的时候会有个内部判断是否有参数传递过来
// 没有参数 则执行 x = 0
// 有参数,则执行实参赋值
function fn(x = 0, y = 0) {
    document.write(x + y)
}
fn() // 0
fn(6, 5) // 11

11. 对象

11.1 什么是对象

对象(object):JavaScript里的一种数据类型

可以理解为是一种无序的数据集合

用来 描述某个事物,例如描述一个人

  • 人有姓名、年龄、性别等信息、还有吃饭睡觉打代码等功能
  • 如果用多个变量保存则比较散,用对象比较统一

比如描述班主任信息:

  • 静态特征(姓名、年龄、身高、性别、爱好) => 可以使用数字,字符串,数组,布尔类型等表示
  • 动态行为(点名,唱,跳,rap)=> 使用函数表示

11.2 对象使用

1. 对象声明语法

let 对象名 = {}

例如:

// 声明了一个person的对象
let person = {}

 

2. 对象由属性和方法组成

  • 属性:信息或叫特征(名词)。比如 手机尺寸、颜色、重量等......
  • 方法:功能或叫行为(动词)。比如 手机打电话、发短信、玩游戏......
let 对象名 = {
    属性名:属性值,
    方法名:函数
}

 

3. 属性

数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的。

let person = {
    uname: 'andy',
    age: 18,
    sex: '男'
}
  • 属性都是成对出现的,包括属性名和值,它们之间使用英文 : 分隔
  • 多个属性之间使用英文 , 分隔
  • 属性就是依附在对象上的变量(外面是变量,对象内是属性)
  • 属性名可以使用"" 或 '' ,一般情况下省略,除非名称遇到特殊符号如空格、中横线等

4. 属性访问

声明对象,并添加了若干属性后,可以使用 . 或 [] 获得对象中属性对应的值,我们称之为属性访问。

简单理解就是获得对象里面的属性值

let person = {
    name: 'andy',
    age: 18,
    sex: '男'
}
console.log(person.name)
console.log(person.age)
let person = {
    name: 'andy',
    age: 18,
    sex: '男'
}
console.log(person['name'])
console.log(person['age'])

 5. 对象中的方法

数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数

let person = {
    name: 'andy',
    sayHi: function() {
        document.write('hi~~~')
    }
}
  • 1. 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
  • 2. 多个属性之间使用英文 , 分隔
  • 3. 方法是依附在对象中的函数
  • 4. 方法名可以使用 "" 或 '',一般情况下省略,除非名称遇到特殊符号如空格、中横线等

6. 对象中的方法访问

声明对象,并添加了若干方法后,可以使用 . 调用对象中函数,我们称之为方法调用

let person = {
        name: 'andy',
        sayHi: function() {
            document.write('hi~~~')
        }
    }
    // 对象名.方法名()
person.sayHi()

注意:千万别忘了给方法名后面加小括号

let person = {
        name: 'andy',
        sayHi: function() {
            document.write('hi~~~')
        }
    }
    // 对象名.方法名()
person.sayHi()

11.3 操作对象

对象本质是无序的数据集合,操作数据无非就是 增 删 改 查 语法:

  • 查询对象
    • 对象.属性 或 对象['属性']
    • 对象.方法()
  • 重新赋值
    • 对象.属性 = 值
    • 对象.方法 = function() {}
  • 对象添加新的数据
    • 对象名.新属性名 = 新值
  • 删除对象中属性
    • delete 对象名.属性名
let obj = {
    uname: '小明',
    age: 18
}
console.log(obj.age)
    // 修改:对象.属性 = 新值
obj.age = 81
console.log(obj)
    // 新增一个属性,js可以非常方便的动态新增属性或方法
obj.sex = '男'
    // 先去对象里面找是否有sex这个属性,如果有则更新值修改,没有则新增这个属性
obj.sing = function() {
    console.log('hi~~~')
}
console.log(obj)
// 删除
delete obj.uname
console.log(obj)

11.4 遍历对象

  •  对象没有像数组一样的length属性,所以无法确定长度
  • 对象里面是无序的键值对,没有规律。不像数组里面有规律的下标

可以利用for in遍历对象

let obj = {
    uname: '小明',
    age: 18,
    sex: '男'
}
for (let k in obj) {
    console.log(k) // 打印属性名
    console.log(obj[k]) // 打印属性值
}

 

<script>
    let students = [{
            name: '小明',
            age: 18,
            genter: '男',
            hometown: '河北省'
        }, {
            name: '小红',
            age: 19,
            genter: '女',
            hometown: '河南省'
        }, {
            name: '小刚',
            age: 20,
            genter: '男',
            hometown: '山西省'
        }, {
            name: '小蓝',
            age: 21,
            genter: '女',
            hometown: '山东省'
        }]
        // 得到小明的名字
        // console.log(students[0]) // {name: "小明", age: 18, genter: "男", hometown: "河北省"}
        // console.log(students[0].name); // 小明
    for (let i = 0; i < students.length; i++) {
        console.log(students[i].name)
        console.log(students[i].hometown)
    }
</script>

下面代码运行:

<style>
    table {
        width: 600px;
        text-align: center;
    }
    
    table,
    th,
    td {
        border: 1px solid #ccc;
        border-collapse: collapse;
    }
    
    caption {
        font-style: 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>

<script>
    // 第一步:打印头部和尾部
    let students = [{
        name: '小明',
        age: 18,
        gender: '男',
        hometown: '河北省'
    }, {
        name: '小红',
        age: 19,
        gender: '女',
        hometown: '河南省'
    }, {
        name: '小丽',
        age: 20,
        gender: '男',
        hometown: '山西省'
    }, {
        name: '小刚',
        age: 21,
        gender: '女',
        hometown: '山东省'
    }]
    document.write(`
<table>
    <tbody>
        <caption>学生列表</caption>
            <tr>
                <th>序号</th>
                <th>姓名</th>
                <th>年龄</th>
                <th>性别</th>
                <th>家乡</th>
            </tr>
`)
    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>
    `)
    }
    document.write(`
</tbody>
</table>
`)
</script>

11.5 内置对象

1. 内置对象是什么

  • JavaScript内部提供的对象,包含各种属性和方法给开发者调用
  • 思考:我们之间用过内置对象吗?
    • document.write()
    • console.log()

2. 内置对象Math

  • Math对象是JavaScript提供的一个“数学高手”对象
  • 提供了一系列做数学运算的方法
  • 可以通过MDN查询

3. 生成任意范围随机数

  • 生成N - M之间的随机数(生成的随机数包含N与M)
    • Math.floor(Math.random() * (M - N + 1)) + N
// 封装一个函数,求💖到💖的随机数
function getRandom() {
    Math.floor(Math.random() * (max - min + 1)) + min
}
let random = getRandom(1, 10)
console.log(random)
// 随机点名
// 随机数
function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
}
// 声明一个数组
let arr = ['赵云', '黄忠', '关羽', '张飞', '刘备', '曹操']
let random = getRandom(0, arr.length - 1)
document.write(arr[random])
// 随机点名
// 随机数
function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
}
// 声明一个数组
let arr = ['赵云', '黄忠', '关羽', '张飞', '刘备', '曹操']
let random = getRandom(0, arr.length - 1)
document.write(arr[random])

// 随机点名案例改进:随机显示一个名字到页面中,不能重复显示
// arr.splice(从哪里开始删,删几个)
arr.splice(random, 1)
console.log(arr)
// 猜数字游戏
/*
程序随机生成1~10之间的数字,用户输入一个数字
1. 如果大于该数字,就提示,数字猜大了,继续猜
2. 如果小于该数字,就提示,数字猜小了,继续猜
3. 如果猜对了,就提示猜对了,程序结束
*/
/* 分析:
1. 利用随机数生成一个数字
2. 需要一直猜,所以需要不断的循环
3. 用户输入,如果猜对了,就退出条件,用while循环合适
4. 内部判断可以用多分支语句
*/
function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
}
let random = getRandom(1, 10)
while (true) {
    let num = +prompt('请输入1~10之间的随机数')
    if (random < num) {
        alert('猜大了')
    } else if (random > num) {
        alert('猜小了')
    } else {
        alert('猜对了')
        break // break 退出循环  return退出函数
    }
}

拓展 - 术语解释

术语解释举例
关键字 在JavaScript中有特殊意义的词汇 let、var、function、if、else、switch、case、break
保留字 在目前的JavaScript中没意义,但未来可能会具有特殊意义的词汇 int、short、long、char
标识(标识符) 变量名、函数名的另一种叫法
表达式 能产生值的代码,一般配合运算符出现 10 + 3、age >= 18
语句 一句代码也称之为一条语句,一般按用途还会分类:输出语句、声明语句、分支语句

 拓展 - 基本数据类型和引用数据类型

简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型

  • 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型
    • string,number,boolean,undefined,null
  • 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型
    • 通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等

拓展 - 基本数据类型和引用数据类型

堆栈空间分配区别:

1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;

简单数据类型存放到栈里面

2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。

引用数据类型存放到堆里面

posted @ 2022-08-01 16:41  VTE01  阅读(148)  评论(0)    收藏  举报