# 变量 (<font style="color:red"> 重要 </font>)🗡

# 变量是什么❓

理解变量是计算机存储数据的 <font style="color:red">"容器"</font>。🔺

# 1. 变量🗜

  • 白话:变量就是一个装东西的盒子。📋
  • 通俗:变量是计算机中用来存储数据的 <font style="color:red">"容器"</font>, 它可以让计算机变得有记忆。
  • 注意:⚠️:<font style="color:red"> 变量不是数据本身,它们仅仅是一个用于存储数值的容器,可以理解为是一个个用来装东西的纸箱子 </font>。

# 变量基本使用⭐️

# 1. 声明变量🗽

要想使用变量,首先需要创建变量(也称为声明变量或者定义变量)

语法:🎲

let 变量名
  • 声明变量由两部分构成:声明关键字,变量名(标识)
  • let 即关键字(let : 允许,许可,让,要),所谓关键字是系统提供的专门用来声明(定义)变量的词语
  • <u>var 是我们的前任请把 var 忘掉 </u> --- [pink 老师]

举例:🌰

<script>
    let name;
</script>
  • 我们声明了一个 name 变量
  • name 即 <font style="color:red"> 变量的名称 </font>, 也叫标识符 🔺

# 2. 变量赋值🗿

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

声明变量的时候直接完成赋值操作,这种操作也成为,变量 <font style="color:red"> 初始化 </font>。

<script>
    // 声明一个变量名为 name, 并赋值
    let name = 'DouKx';
    // 弹出变量的值
    alert(name);
</script>

⚠️注意:是通过 <font style="color:red"> 变量名 </font > 来获得变量里面的数据。

image-20230420184038312

🌟目标:掌握变量的更新以及了解同时声明多个变量的写法。

# 声明多个变量⭐️

🎮语法:多个变量中间用逗号隔开

📋说明:看上去代码长度更短,但并 <font style="color:red"> 不推荐 </font> 这样,为了更好的可读性,请一行只声明一个变量

<script>
let name = '张三';
// 变量的更新
name = '李四';
alert(name);
// 将 name1 和 name2 都赋值为 刘桑
let name1 = name2 = '刘桑';
alert(name1);
alert(name2);
let a = b = 1;//1+1 = 2
alert(a+b);
// 同时声明多个变量并且它们赋值也是不同的
let name = '张三' , name1 = '刘桑';
alert(name);
alert(name1);
// 同时声明多个变量并且后续进行赋值
let a,b;
a = '张三';
b = '李四';
console.log(a,b);// 结果 张三 李四
</script>

# 3. 更新变量🗽

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

<script>
// 声明了一个 name 变量,同时里面存放了 ' 张三 ' 这个数据
let name = '张三';
// 这里不允许多次声明一个变量,没有理由重新声明变量
let name = '李四';
alert(name);
</script>

image-20230420212356880

⚠️<font style="color:red"> 注意 </font>:let 不允许多次声明同一个变量

# 变量的本质🌍

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

⛵️变量本质:是程序在内存中申请的一块用来存放数据的小空间,js 的变量是存储到内存中的

image-20230420221511897

  • 在内存中开辟一个空间
  • 通过变量名找到值

# 变量命名规则与规范💎

🌐规则:必须遵守,不遵守报错(法律层面)

🌐规范:建议,不遵守不会报错,但不符合业内通识(道德层面)

🌐规则 1:

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

🌐规则 2:

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

image-20230421082931446

# 变量扩展 - let 和 var 的区别🌓

let 和 var 区别:

在较旧的 JavaScript, 使用关键字 var 来声明变量,而不是 let

var 现在开发中一般不再使用它,只是我们可能再老版程序中看到它.

let 为了解决 var 的一些问题

var 声明:🎯

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

结论:

<font style="color:red">var 就是个 bug, 以后声明变量统一使用 let</font> .🎫

# 数组🗡

  • 数组 (Array) --- 一种将一组数据存储在单个变量名下的优雅方式

声明方式:

let arr = [];
     ↓    ↓
    变量  数组字面量
+----------------------------------+
// 赋值方式,每个数据之间用逗号隔开
let 数组名 = [数据1,数据2,...,数据n];
  • 数组是按顺序保存的,所以每个数据都有自己的编号
  • 计算机中的编号从 0 开始,所以数据 1 的编号为 0, 数据 2 的编号为 1, 以此类推
  • 在数组中,数据的编号也叫 <font style="color:red"> 索引下标 </font>.
  • <font style="color:red">JavaScript 中数组可以存储任意类型的数据 </font>.⚠️
  • 取出来是什么类型的,就根据这种类型特点来访问
  • 最大索引号 + 1 等于数组长度💫

取值语法:🎲

数组名[下标]

例如🌸

<script>
   let arr = ['张三','李四',20];
console.log('arr[2]数据类型:'+typeof arr[2]);
console.log('arr[1]数据类型:'+typeof arr[1]);
console.log('arr[0]下标值:'+arr[0]);
</script>

image-20230421092921594

一些术语:🏁

  • 元素:数组中保存的每个数据都叫数组元素
  • 下标 / 索引:数组中数据的编号
  • 长度:数组中数据的个数,通过数组的 length 属性获得 (最大索引号 + 1 等于数组长度)

# 常量🏑

📗 概念:使用 const 声明的变量为 "常量".

使用场景:当某个变量永远不会改变的时候,就可以使用 const 来声明,而不是 let

命名规范:变量名统一大写📗

// 声明一个常量
const NAME = '刘桑';
// 输出常量值
console.log(NAME);

注意:⚠️<font style="color:red"> 常量不允许重新赋值,声明的时候必须赋值 (初始化)</font>.

尝试改变常量值的后果 🔴

<script>
   const NAME = '刘桑';
   console.log(NAME);
   NAME = '张三';
   console.log(NAME);
</script>

image-20230421094855064

💠

  • let - 现在实际开发变量声明方式.
  • var - 以前的声明变量的方式,会有很多问题
  • const - 类似于 let, 但是变量的值无法被修改

# 数据类型⭐️

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

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

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

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

  • 基本数据类型🌟
  • 引用数据类型🌟

image-20230421191824939

# 数字类型 Number🔩

💠

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

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

<script>
   //number 数据类型
   let number = 1;
   let number1 = 1.1;
   console.log('number:'+number);
   console.log('number1:'+number1);
</script>

image-20230421192638721

<font style="color:red"> 注意事项 </font>:⚠️

<font style="color:red">JS 是弱数据类型,变量到底属于那种类型,只有赋值之后,我们才能确认 </font>.

<font style="color:red">Java 是强数据类型,例如: int a = 3 必须是整数类型 </font>.

数字可以有很多种操作,比如:乘法 * , 除法 / , 加法 + , 减法 - . 等等,所以经常和算术运算符一起.

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

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

🌟取模计算技巧:前面的数比后面的数大结果就是后面的数,比如:3 % 4 = 3

<script>
   console.log(1 + 1);//2
   console.log(1 - 1);//0
   console.log(1 * 1);//1
   console.log(1 / 1);//1
   console.log(4 % 2);//0
   console.log(2 % 4);//2
   console.log(1 % 4);//1
   console.log(3 % 4);//3
</script>

# 运算符执行的优先级🎄

💠

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

JavaScript 中,优先级越高越先被执行,<font style="color:red"> 优先级相同时以从左向右执行 </font>.

  • 乘,除,取余 优先级相同
  • 加,减优先级相同
  • 乘,除,取余优先级大于加,减
  • 使用()可以提升优先级
  • 📋总结:先乘除后加减,有括号先算括号里面的
  • 取余运算符开发中的使用场景是?
    • 用来判断某个数字是否能被整除🌟
<script>
   console.log(1 + 2 * 3);//7
   console.log((1 + 2) * 3);//9
   console.log(10 - 8 / 2);//6
   console.log((10 - 8) / 2);//1
   console.log(2 % 5 + 4 * 2);//10
   // 当优先级相同时会从左向右计算
   // 得出:2 % 9 * 2 = 4
   console.log(2 % (5 + 4) * 2);//4
</script>
  • ⚠️NaN 代表一个计算错误,它是一个不正确的或者一个未定义的数学操作所得到的结果
console.log('刘桑' - 2);//NaN
  • ⚠️NaN 是粘性的,任何对 NaN 的操作都会返回 NaN
console.log(NaN + 2);//NaN
  • ⚠️两个 NaN 进行比较,结果为 false
<script>
   console.log(NaN === NaN);//false
</script>

# 字符串类型 (string)🎄

💠

通过 <font style="color:red"> 单引号 (' ') , 双引号 ("") 或反引号 (``) 包裹的数据都叫字符串 </font>, 单引号和双引号没有本质上的区别,<font style="color:red"> 推荐使用单引号 </font>.

<script>
   // 三种不同的声明字符串类型的形式
   console.log('单引号-刘桑');
   console.log("双引号-刘桑");
   console.log(`反引号-刘桑`);
</script>

image-20230421210501160

⚠️如果不使用单引号,双引号,反引号形式来声明字符串的话会报错:Uncaught ReferenceError: 刘桑 is not defined.

<script>
   // 三种不同的声明字符串类型的形式
   //console.log (' 单引号 - 刘桑 ');
   //console.log ("双引号 - 刘桑");
   //console.log (`反引号 - 刘桑`);
   let name = 刘桑;
	console.log(name);//Uncaught ReferenceError: 刘桑 is not defined
</script>

image-20230421210833740

⚠️注意事项

  1. 无论单引号或是双引号必须成对使用

  2. 单引号 / 双引号可以互相嵌套,但是不以自己嵌套自己 (口诀:外双内单或者外单内双)

    🌰

    <script>
       console.log('外部'内部'');//Uncaught SyntaxError: missing ) after argument list
       console.log("外部"内部"");//Uncaught SyntaxError: missing ) after argument list
       console.log('外部"内部"');// 外部 "内部"
       console.log("外部'内部'");// 外部 ' 内部'
    </script>
  3. 必要时可以使用转义符 \ ,输出单引号或双引号

    🌰

    <script>
       console.log('外部\'内部\'');// 外部 ' 内部'
       console.log("外部\"内部\"");// 外部 "内部"
       console.log('外部"内部"');// 外部 "内部"
       console.log("外部'内部'");// 外部 ' 内部'
    </script>

    image-20230421212739008

# 字符串拼接⭐️

💠

场景+ 运算符,可以实现字符串的拼接

🎲口诀:数字相加,字符相连

📗绝世秘籍出自 Java 文章 :推荐使用 ""+变量 来将这个数据类型转换为字符串类型.

# 模板字符串⭐️

💠

  • 使用场景
    • 拼接字符串和变量
    • 在没有它之前,要拼接变量比较麻烦
document.write('大家好,我是'+name+',今年'+age+'岁');
  • 语法:🎲
    • `` (反引号)
    • 在英文输入模式下按键盘的 tab 键上方的那个键 (1 左边那个键)
    • 内容拼接变量时,用 <font style="color:red">${ }</font > 包住变量
<script>
    let name = '刘桑';
    let age = 18;
    document.write(`我叫${name},我今年${age}岁了`);
</script>

image-20230422161321755

字符串拼接比较麻烦,我们可以使用 <font style="color:red"> 模板字符串 </font>, 可以让我们拼接字符串更加简便

模板字符串使用注意事项:⚠️

  • 反引号来包含数据
  • 用 **${变量名}** 来使用变量

# 布尔类型 (<font style="color:red">boolean</font>)🎄

💠

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

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

<script>
    alert('JavaScript好玩不?');
    let flag = true;
    console.log(flag);
    if(flag)
        document.write('好玩');
    else
        document.write('不好玩');
</script>

# 未定义类型 (<font style="color:red">undefined</font>)🎄

💠

未定义是比较特殊的类型,只有一个值 undefined ,<font style="color:red"> 除字符串外 (数字类型,布尔值) 对 undefined 进行运算操作结果为 NaN</font>.

什么情况出现未定义类型

📋只声明变量,不赋值的情况下, 变量的默认值为 undefined , 一般很少 **[直接]** 为某个变量赋值为 undefined .

<script>
   // 声明一个变量未给值就是 undefined
   let name//undefined
	console.log(name)
	console.log(typeof name)//undefined
	console.log(name + 1)//NaN
	console.log(name + '1')//undefined1
	// 隐式类型转换 '1' = name - 1 = NaN
	console.log(name - '1')//NaN
	console.log(name + null)//undefined+null=NaN
	console.log(true + name)//NaN
</script>

image-20230422163720559

工作中的使用场景:📋

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

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

# 案例 - 查看是否载入 jQuery.js 文件🌳

💠

<script>
   if(typeof jQuery!='undefined')
		alert('jQuery已经加载完成');
	else
   	alert('jQuery未被加载');
</script>

📋如果没有引入 jQuery.js 文件则会执行 else 下语句,如果引入了就会执行 if 下语句

# <font style="color:red">null</font>(空类型)🎄

💠

📋在 Java 中 <font style="color:red">null</font > 只能是对象或者是字符串包装类类型,对象不能使用 + 进行拼接,包装类赋值为 null 会直接报错 <font style="color:red">NullpointerException</font>,字符串使用 + 就会拼接为 null1

String str = null;
System.out.println(str + 1);//null1

JavaScript 中的 null 仅仅是一个代表 "无" , "空" 或 "值未知" 的特殊值,<font style="color:red">null 是一个 object 对象 </font>.

null 任何数字等于其数字值,true 为 1,fasle 为 0,加字符串则会拼接

<script>
   let name = null
   console.log(`name = ${name}`)//null
   console.log(`name 的type = ${typeof name}`)//object
   console.log(`name + 1 的type = ${typeof name + 1} , 值为 ${name + 1}`)// 类型 object1 值 1
   console.log(`name + null 的type = ${typeof name + null} , 值为 ${name + null}`)// 类型 objectnull 值 0
   console.log(`name - 1 的type = ${typeof name - 1} , 值为 ${name - 1}`)// 类型 NaN 值 - 1
   console.log(`name - '1' 的type = ${typeof name - '1'} , 值为 ${name - '1'}`)// 类型 NaN 值 - 1
   console.log(`name + '1' 的type = ${typeof name + '1'} , 值为 ${name + '1'}`)// 类型 object1 值 null1
   console.log(`name + 1 的type = ${typeof name + 1} , 值为 ${name + 1}`)//object1
</script>

image-20230422164915348

# null undefined 区别:🗡
  • undefined : 表示声明变量没有赋值,如果检测变量是 undefined 就说明没有值传递过来,undefined 对任何数据操作运算结果都为 NaN
  • null : 表示赋值了,但是内容为空,null 任何数字等于其数字值,true 为 1,fasle 为 0,加字符串则会拼接

查看 null 和 undefined 计算区别 .

# null 开发中的使用场景:🗡

💠

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

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

# undefined 与 null 的计算区别🗡

<script>
    let num = null
    console.log(num + 2)//2
    console.log(num + null)//0
    console.log(num - 1)//-1
    //null+'1' 字符串相加
    console.log(num + '1')//null1
    //null-'1' 隐式转换为 NaN
    console.log(num - '1')//-1
    //object1,num 是一个对象为 null 加 1 为 object1
    console.log(typeof num + 1)
    console.log('-------------------')
	 //true: 1 , fasle: 0
    console.log(num + true)//1
    console.log(num + false)//0
    console.log('-------------------')
    let person
    // 出字符串外 (数字类型,布尔值) 对 undefined 进行运算操作结果为 NaN
    console.log(person + 1)//NaN
    //undefined 加上字符串为 undefined1, 字符串相加
    console.log(person + '1')//undefined1
    //'1' 隐式转换为数字类型减去 undefined 结果为 NaN "-" 号会隐式转换字符串为数字
    console.log(person - '1')//NaN
    console.log(person + num)//undefined+null=NaN
    console.log(typeof person)//undefined
    console.log(true + person)//NaN
</script>

image-20230425091036124

# 检测数据类型⭐️

💠

<font style="color:red"> 通过 typeof 关键字 </font> 检测数字类型

typeof 运算符可以返回被检测的数据类型,它支持两种语法形式:

  1. 作为运算符: <font style="color:red">typeof x</font>(常用的写法)
  2. 函数形式: typeof (x)

换言之,有括号和没有括号,得到的结果都是一样的,所以我们直接使用 <font style="color:red"> 运算符 </font > 的写法.

# 数据类型转换🎄

💠

<script>
   let input = prompt('请输入您要输入的值:');
	console.log('您输入的数据类型为:'+typeof input);
</script>

在 JavaScript 中 prompt, 表单 单选框 复选框 多选框,这些表单默认取过来的值就是 <font style="color:red">string</font > 类型

image-20230422172333098

image-20230422172350041

# 为什么需要类型转换🌳

💠

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

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

console.log('1000'+'2000');// 输出结果: 10002000

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

通俗来说,就是 <font style="color:red"> 把一种数据类型的变量转换成我们需要的数据类型 </font>.

# 隐式转换🌳

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

规则:

  • + 号两边只要有一个是字符串,都会把另外一个转换成字符串
  • ⚠️<font style="color:red"> 除了 + 以外的算术运算符 </font>,比如 - , * , / , 都会把数据转成数字类型

缺点:

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

小技巧:🗡

  • <font style="color:red"> + 号作为正号解析可以转换成数字型 </font>.
  • <font style="color:red"> 任何数据和字符串相加,结果都是字符串 </font>.

与 Java 的区别:⚠️

  • 在 Java 中只能使用 + 号来将其它类型转换为字符串进行拼接,而不能使用 - , * , / , % 来进行对字符串的运算否则将会报错:<font style="color:red">Operator '%' cannot be applied to 'int', 'java.lang.String'</font>.

image-20230423105637508

⚠️<font style="color:red"> 注意 </font>:JavaScript 中 += 也会将其它数据类型隐式转换为字符串类型或者 -= 转换为数字类型,但在 Java 中这么写就会报错

<script>
   // 隐式转换
   // 从左到右检测到有字符串类型则将后面的也转换成字符串
   console.log('p' + 1);//p1
   console.log(typeof 'p' + 1);//string
   // 减号检测到有数字类型则将字符串转换为数字类型
   // 减,乘,除都类似只有加号不同
   console.log('2' - 2);//0
   console.log(typeof '2' - 2);//NaN
   console.log(2 * '2');//4
   console.log(typeof 2 * '2');//NaN
   console.log(2 / '2');//1
   console.log(typeof 2 / '2');//NaN
   console.log(2 % '2');//0
   console.log(typeof 2 % '2');//NaN
   // 前面加上 + 为正数
   console.log(+12);//12
   console.log(typeof +12);//number
   // 将字符串转换为数字型
   console.log(+'12');//12
   console.log(typeof +'12');//number
</script>

# 显式转换🌳

💠

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

概念:🎲

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

# 转换为数字型🌲

  • Number (数据)

    • 转成数字类型
    • 如果字符串内容里有非数字,转换失败时结果为 NaN (Not a Number) 既不是一个数字
    • NaN 也是 Number 类型的数据,代表非数字
  • 转换为数字型有四种方式:

    • 第一个为:隐式类型转换使用: +
    • 第二个为:显式类型转换使用:Number (数据)
    • 第三个为:显式类型转换使用: parseInt (数据)
      • 只保留整数
    • 第四个为:显式类型转换使用: parseFloat (数据)
      • 可以保留小数
<script>
   let age = '18.1';
   console.log('age的数据类型:'+typeof age);//string
   console.log('强制类型转换为Number:'+Number(age));//18.1
   console.log('强制类型转换为Number后的数据类型:'+typeof Number(age));//number
   console.log('将abc强制转换为数字型:'+Number('abc'));//NaN
   let n = prompt('请输入您的年薪:');
   console.log(typeof n);//string
   let num = Number(prompt('请输入您的年薪:'));
   console.log(typeof num);//number
   let num1 = +prompt('请输入您的年薪:');
   console.log(typeof num1);//number
   let parseAge = parseInt(age);
   console.log(typeof parseAge);//number, 只能保留整数
   let parseFloatAge = parseFloat(age);
   console.log(typeof parseFloatAge);//number, 可以保留小数,也可以保留整数
</script>
<script>
   let num = 18.1;
   let num1 = parseInt(num);
   console.log(num1);//18, 只能保留整数
   let num2 = parseFloat(num);
   console.log(num2);//18.1, 可以保留小数
   num = 18;
   let num3 = parseFloat(num);
   console.log(num3);//18, 也可以保留整数
	console.log(parseFloat('abc12.1'))//NaN
   console.log(parseInt('abc12'))//NaN
</script>
  • 🔴parseInt 和 parseFloat 可以检测参数中是否有数字,从左边开始检测到有非数字为止,如果并没有或者说一开始就是非数字的字符那么结果就是 NaN
<script>
   // 检测前面是否有数字类型,直到没有数字类型为止
   // 检测没有数字类型结束前面没有检测到数字类型则为 NaN
   console.log(parseInt('12px'));//12
   console.log(parseFloat('150px'));//150
   console.log(parseInt('px12'));//NaN
   console.log(parseInt('1a2r'));//1
</script>

总结: 📗

转换为数字类型有三种显式类型转换和一种隐式类型转换

显式转换: Number (数据),parseInt (数据),parseFloat (数据)

隐式转换: +

  • 案例:使用 prompt 将两个数相加 alert 返回结果
<script>
   // 第一种写法
   let num = +prompt('输入数字:');
   let num1 = +prompt('输入数字:');
   alert('相加的结果为:'+(num + num1));// 如果不加括号将会又被转换为字符串类型
   // 第二种写法
   let num2 = prompt('输入数字:');
   let num3 = prompt('输入数字:');
   alert(`相加的结果为:${(+num2) + (+num3)}`);// 同样使用上面的写法写 prompt 上转换这里不会被转换为字符串类型,例如下面代码
	let num2 = +prompt('输入数字:');
   let num3 = +prompt('输入数字:');
   alert(`相加的结果为:${num2 + num3}`);
</script>

结合以上知识的综合案例:确认订单案例

<!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>
    h1{
        text-align:center;
    }
    #table,tr,td{
        border: red 1px solid;
        background:rebeccapurple;
        margin:auto;
        text-align:center;
    }
</style>
</head>
<body>
    <h1>确认订单</h1>
    <script>
        let name = prompt('请输入商品名称:');
        let num = +prompt('请输入商品价格:');
        let num1 = +prompt('请输入商品数量:');
        let address = prompt('请输入收货地址:');
        let total = num * num1;
        document.write(`
            <table id="table">
                <tr>
                    <th>商品名称</th>
                    <th>商品价格</th>
                    <th>商品数量</th>
                    <th>总价</th>
                    <th>收货地址</th>
                </tr>
                <tr>
                    <td>${name}</td>
                    <td>${num} 元</td>
                    <td>${num1}</td>
                    <td>${total} 元</td>
                    <td>${address}</td>
                </tr>
            </table>
        `);
    </script>
</body>
</html>

test

# 常见的报错信息🎄

image-20230423130251705

翻译: const 声明中缺少初始化式

const age;
console.log(age);//const, 声明变量后必须赋值

image-20230423130448726

翻译:年龄没有定义

分析:📋

  • 提示 age 变量没有定义过
  • 很可能 age 变量没有声明和赋值
  • 或者我们输出变量名和声明的变量不一致引起的(简单说写错变量名了)

image-20230423130709427

翻译:标识符‘年龄’已经声明

let age = 18;
let age = 22;
console.log(age);// 错误,let 不允许重复声明

分析:

  • 提示 "age" 已经声明
  • 很大概率是因为重复声明了一个变量
  • 注意 let 或者 const 不允许多次声明同一个变量

image-20230423130939493

翻译: . 分配给常量变量。

const age = 18;
age = 22;
console.log(age);// 错误,常量不能被重新赋值
  • 常量被重新赋值了
  • 常量不能被重新赋值

# 运算符🎄

练习 JavaScript 运算符游戏网站 - 主要练习: == 运算符

# 算术运算符🌳

💠

📋 + , - , * , / , % 都属于算术运算符

取模 % : 被取模数为 0 就会 NaN, 而在 Java 中会报错算术异常 /by zero

JavaScript: console.log(10 % 0)//NaN
Java: ArithmeticException: / by zero

取模数 取模 被取模数 被取模数大于 取模数则 取 取模数比如:

<script>
    console.log(13 % 10)//3
    console.log(4 % 5)// 只要后面比前面的大取模都是前面的 4
</script>

# 赋值运算符🌳

💠

对变量进行赋值的运算符就是赋值运算符

  • 💫已经学过的运算符: = <font style="color:red"> 将等号右边的值赋予给左边,要求左边必须是一个容器 </font>.
  • 🌠其它赋值运算符:
    • +=
    • -=
    • *=
    • /=
    • %=
  • += 出现是为了简化代码,比如让 let num = 10,num 加 5 怎么写呢?
    • num += 5
<script>
   let num = 1;
   //num+1=2 但是这个 2 并没有赋值给任何人所以 num 还是 1
   num + 1;
   console.log('num+1 = '+num);//1
   let num1 = 1;
   num1 = num1 + 1;
   console.log('num1 = num1 + 1 = '+num1);//2
   let num2 = 1;
   num2 += 2;
   console.log('num2 += 2 = '+num2);//3
</script>

# 一元运算符🌳

💠

众多的 JavaScript 的运算符可以根据所需表达式的个数,分为 <font style="color:red"> 一元运算符,二元运算符,三元运算符 </font>.

比如:一元运算符

  • 例如:正号,负号
let num = +10;
let num1 = -10;

比如:二元运算符

  • 例如:变量 + 变量
  • 例如:变量 > 变量 或者 <或者 = 或者>= 或者 <= 或者 ==
let num = 10 + 10;
  • 用到了两个操作数,表达式的个数为 2,所以 + 为二元运算符

比如:三元运算符

  • 例如:变量 > 值?true:false;
<script>
   let num = 10;
   // 判断 num 的值是否大于 11, 大于为 true, 否则为 false
   //true:YES , false:NO
   let str = num > 11 ? 'YES':'NO';
   console.log(str);//NO
</script>
  • 用到了三个操作数,表达式的个数为 3

自增

  • 符号:+ +
  • 作用:让变量的值 + 1

自减

  • 符号:- -
  • 作用:让变量的值 - 1

使用场景:经常用于 <font style="color:red"> 计数 </font > 来使用。比如进行 10 次操作,用它来计算进行了多少次了

  • 自增运算符的使用

# 前置自增🌲

let num = 1;
++num;
console.log(num);//1

每次执行 1 次,当前变量数值加 1

其作用相当于 num += 1

# 后置自增🌲

let num = 1;
num++;
console.log(num);//1

每执行 1 次,当前变量数值加 1

其作用相当于 num += 1

# 前置自增和后置自增的区别🌲

前置自增和后置自增如果参与运算就有区别:(难点,但是了解即可)

前置自增:

  • 前置自增:先自增再使用(记忆口诀:++ 在前 <font style="color:red"> 先加 </font>)
  • 先计算后输出结果
<script>
   let num = 1;
   console.log(++num + 1);//3
   // 参与运算时 num+1 的值只在运算范围内有效
   // 执行到此处 num 的值为 2 ++2 + 1 = 4
   console.log(++num + 1);//4
</script>

后置自增:

  • 后置自增:先使用再自增(记忆口诀:++ 在后 <font style="color:red"> 后加 </font>)
  • 先输出结果在进行自增
<script> 
	let num1 = 1;
    console.log(num1++ + 1);//2
    console.log(num1++ + 1);//3
</script>

📗前置自增和后置自增在独立使用时二者并没有差别!

# 面试题🗡

这个计算的结果和 Java 相同的💫

⭐️提示:看下面的计算公式要想到优先级

<script>
    let num = 1;
    //num++ :1
    //+
    //++num :2
    // 计算后原本为 3num++ 自增 1
    // = 4
    //num :3
    //3 + 4 = 7
    console.log(num++ + ++num + num);//7
</script>
  • 自我理解的公式为: (1+2+1)+3=7
  • (num++ + ++num) + num = 7
<script>
    let num = 1;
    console.log(num + ++num + num++);//5
</script>
  • (1+2+2) = 5
  • num + (num + num) = 5
<script>
    let num = 1;
    console.log(++num + num + num++);//6
</script>
  • 2+2+2=6
  • num + num + num = 6

# 比较运算符🌳

💠

比较运算符的介绍

  • 使用场景:比较两个数据大小,是否相等
  • 比较运算符
    • > : 左边是否大于右边
    • < : 左边是否小于右边
    • >= : 左边是否大于或等于右边
    • <= : 左边是否小于或等于右边
    • == : <font style="color:red"> 左右两边值是否相等 </font>.
    • === : <font style="color:red"> 左右两边是否类型和值都相等 </font>.
    • !== : 左右两边是否不全等
    • != : 左右两边值是否不相等
  • 比较结果为 boolean 类型,即只会得到 true 或 false
  • <font style="color:red"> 开发中判断是否相等,强烈推荐使用 === .</font>.
<script>
   //1=='1' 会将 '1' 转换为数字类型,比较为 true
   console.log(1 == '1');//true
   console.log(1 === '1');//false
   console.log(undefined == null);//true
   console.log(undefined === null);//false
   //NaN 不等于任何人包括它自己
   console.log(NaN == NaN);//false
   console.log(NaN === NaN);//false
   // 判断类型和值
   console.log(1 !== '1');//true
   // 不判断类型
   console.log(1 != '1');//false
</script>

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

比较规则是一一对应比较大小

image-20230423183209921

  • 从左往右依次比较
  • 如果第一位一样在比较第二位,以此类推
  • 尽量不要比较小数,因为小数有精度问题

查看 ASCII 码表

  • 💫<font style="color:red"> 不同类型之间比较会发生隐式转换 </font>.
    • 最终把数据隐式转换成 number 类型再比较
    • 开发中,如果进行准确比较推荐使用 === , 或者 !== .

# 逻辑运算符🌳

💠

使用场景:逻辑运算符用来解决多重条件判断

语法:🎲

num > 5 && num < 10
符号名称日常读法特点口诀
&&逻辑与并且符号两边都为 true 结果才为 true一假则假
||逻辑或或者符号两边有一个 true 就为 true一真则真
逻辑非取反true 变 false<br>false 变 true真变假,假变真

👹

  • && , || 它们都是具有短路性的

    • && : 前面为 false 则不会执行后面的
    <script>
       let num = 1;
       let flag = ++num > 3 && ++num == 1;
       console.log(flag);
    	console.log(num);//2
    </script>
    • || : 前面为 true 则不会执行后面的
    <script>
       let num = 1;
       let flag = ++num < 3 || ++num == 1;
       console.log(flag);
       console.log(num);//2
    </script>

🌠这只是执行流程的区别,与返回的布尔值不耽搁

# 逻辑中断🌴

💠

💫在 Java 中布尔值要么是 true,要么是 false,不能被其它的数据定义,逻辑判断必须返回的是一个布尔类型的值不能 false||0 这种操作.

开发中,还会见到一下写法:

解释:简单说就是初始化参数避免 undefined 的。

0 在 JavaScript 中 为 false 如果传入的参数为 0 或者没有传入参数那么,就会短路或判断,如果为 false 则赋值为 0 作为初始值,如果不为 0 则赋值为传入的值其它值都是 true 不会指向 || 后面的操作。

在 JavaScript 中,记住一句话: 非 0 即为真! <strong style="color:red"> 这句话在 Java 中不存在因为 Java 中数字不能代表布尔值 </strong>。

function getSum(x = 0,y = 0){
   x = x || 0
   y = y || 0
   console.log(x + y)
}
getSum(1,2)

其实类似参数的默认值写法

  • 短路:只存在于 && 和 || 中,当满足一定条件会让右边代码不执行
符号短路条件
&&左边为 false 就短路
||左边为 true 就短路
  • 原因:通过左边能得到整个式子的结果,因此没必要再判断右边
  • 非 0 即为真!!!📗
    • Java 语言的布尔类型变量,其赋值只能是 true 和 false,所以非 0 即 true 并不存在于 java 中。
<script>
    // 非 0 即为真
    console.log(11 && 22)//22
    console.log(11 || 22)//11
    console.log(false || 0)//0
    console.log(true || 0)//true
    console.log(0 || false)//false
    console.log(2 || 1)//2
</script>
  • 🌠结论:短路 || 前为真则返回前值,前为假则判断后,后为真或者假都返回后值

# 运算符优先级🌳

💠

  • 一元运算符中 <font style="color:red"> 逻辑非 (!) 的优先级很高 </font>.
  • <font style="color:red"> 逻辑与 比 逻辑或优先级高 </font>.(口诀:先与后或)
优先级运算符顺序
1小括号()
2一元运算符++ -- !
3算术运算符先 * / % 后 + -
4关系运算符> >= < <=
5相等运算符== != === !==
6逻辑运算符先 && 后 ||
7赋值运算符=
8逗号运算符,

# (问)- 一个变量满足三个条件🎄

💍

问题:如果让一个变量满足 if 条件为 a == 1 && a == 2 && a == 3 的条件

<script>
   let a = {
      value: 1,// 初始值 1
      valueOf: function(){// 重写 valueOf
         return this.value ++;// 返回 vlaue 值,并自增 1
      }
   };
   if(a == 1 && a == 2 && a == 3)
      alert('符合条件');
   else
      alert('不符合条件');
</script>

结果:

image-20230423142229703

# 语句🎉

# 表达式和语句🎺

💠

什么是表达式:❓

表达式是可以被求值的代码,JavaScript 引擎会将其计算出一个结果

例如:

x = 7
3 + 4
num++
  • 这些都是式子,都可以被求出值

💠

什么是语句:❓

语句是一段可以执行的代码。

比如:prompt ( ) 可以弹出一个输入框,还有 if 语句 for 循环语句等等

表达式和语句的区别:🚧

表达式:<font style="color:red"> 因为表达式可被求值,所以它可以写在赋值 语句的右侧 </font>.

  • 表达式 num = 3 + 4

语句:<font style="color:red"> 而语句不一定有值,所以比如 alert ( ) for 和 break 等语句就不能被用于赋值 </font>.

  • 语句 alert () 弹出对话框 console.log () 控制台打印输出

# 分支语句🏆

# 顺序结构〽️
graph TD;
代码1-->代码2-->代码3;
# 分支结构〽️
graph TD;
代码1--满足条件-->代码2-->代码3;
代码1--不满足-->代码3;
# 循环结构〽️
graph TD;
代码1--重复执行-->重复代码-->代码3;

分支语句可以让我们有 <font style="color:red"> 选择性 </font > 的执行想要的代码

# if 语句🍃

💠

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

单分支使用语法

if(条件){
   满足条件要执行的代码
}
  • 括号内的条件为 true 时,进入大括号里执行代码
  • 小括号内的结果若不是布尔类型时,会发生隐式转换为布尔类型
  • 如果大括号只有一个语句,大括号可以省略,但是,不提倡这么做

多分支使用:

💠

使用场景:适合于有多个结果的时候,比如学习成绩可以分为:优 良 中 差

释义

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

判断学生成绩:

<script>
   let str = +prompt('请输入成绩:');
      if(str >= 90 && str <= 100){
         alert('优');
      }else if(str >= 80 && str <= 89){
         alert('优良');
      }else if(str >= 70 && str <= 79){
         alert('及格');
      }else if(str >= 60 && str <= 69){
         alert('差');
      }
</script>

test

# 案例 - 输入一个年份判断是闰年还是平年🌠

💠

分析:🎮

  1. 能被 4 整除但不能被 100 整除,或者能被 400 整除的年份是闰年,否则都是平年
  2. 需要逻辑运算符
<script>
   	let year = +prompt('请输入年份:');
   if(year % 4 === 0 && year % 100 !== 0 || year % 400 === 0)
      alert('闰年');
   else
   alert('平年');
</script>

# 三元运算符🌴

💠

使用场景:其实是比 if 双分支更简单的写法,可以使用三元表达式

  • 符号:?与:配合使用

语法:🎯

条件 ? 满足条件执行的代码 : 不满足条件执行的代码
  • 一般用来取值

# 输出两个数的最大值🌠

<script>
   let num = +prompt('请输入数字:');
   let num1 = +prompt('请输入数字:');
   let unum = num < num1 ? num1 : num;
   alert(`最大值:${unum}`);
</script>

# switch 语句🌴

💠

释义:

  • 🌠找到跟小括号里数据全等的 case 值,并执行里面对应的代码
  • 💫若没有全等 <font style="color:red">===</font > 的则执行 default 里的代码
  • 📋例:数据若跟值 2 全等,则执行代码 2

⚠️

<font style="color:red">1.switch case 语句一般用于等值判断,不适合于区间判断 </font>.

<font style="color:red">2.switch case 一般需要配合 break 关键字使用,没有 break 会造成 case 穿透 </font>.

语法格式: 🎲

switch (数据) {// 选择判断表达式
   case1://目标值
      代码1
      break// 跳出当前循环结构,执行后面的代码
   case2://目标值
      代码2
      break// 跳出当前循环结构,执行后面的代码
   default://没有对应的目标值则执行default
      代码n
      break// 跳出当前循环结构,执行后面的代码,以最后一条语句可以写 break 也可以不写
}

# 案例 — 实现简单计算器

需求:用户输入 2 个数字,然后输入 + - * / 任何一个,可以计算结果

分析:

  1. 用户输入数字
  2. 用户输入不同算术运算符,可以去执行不同的运算 (switch)
<script>
    let num = +prompt('请输入数字:');
    let n = prompt('请输入操作符(+ - * / %):');
    let num1 = +prompt('请输入数字:');
    let number;
    switch(n){
        case '+':
           number = num + num1;
            alert(`计算两个数相加结果为:${number}`);
           break
        case '-':
            number = num - num1;
            alert(`计算两个数相减结果为:${number}`);
            break
        case '*':
            number = num * num1;
            alert(`计算两个数相乘结果为:${number}`);
            break
        case '/':
            number = num / num1;
            alert(`计算两个数相除结果为:${number}`);
            break
        case '%':
            number = num % num1;
            alert(`计算两个数相取模结果为:${number}`);
          	break
        default:
            alert('请输入正确的计算符号');
    }
</script>

# 循环语句🌮

💠

补充知识点:<font style="color:red"> 断点调试 </font>.(重要)🔴

  • 作用:学习时可以帮助更好的理解代码运行,工作时可以更快找到 bug

  • 浏览器打开调试界面

    1. 按 F12 打开开发者工具
    2. 点到 sources 一栏
    3. 选择代码文件

<img src="./images/image-20230424143407847.png" alt="image-20230424143407847" style="zoom:50%;" />

# while 循环🌳

💠

循环:重复执行一些操作,while: 在... 期间,所以 <font style="color:red">while 循环 </font>, 就是在 < font style="color:red"> 满足条件 </font> 期间,重复执行某些代码

while 循环基本语法:🎲

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

释义:📋

  • 跟 if 语句很像,都满足小括号里的条件为 true 才会进入 <font style="color:red"> 循环体 </font > 执行代码
  • while 大括号里代码执行完毕后不会跳出,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到小括号判断条件,直到括号内条件不满足,即跳出

while 循环三要素:🌠

循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。
所以,<font style="color:red">while 循环需要具备三要素 </font>:⚠️

  1. 变量起始值
  2. 终止条件 (没有终止条件,循环会一直执行,造成死循环)
  3. 变量变化量 (用自增或自减)
<script>
    // 变量的起始值
    let num = 1;
    // 循环条件
    while(num <= 3){
        // 我们要执行的代码语句
        document.write('我会循环三次<br>');
        // 自增,用于不满足循环条件结束循环
        num++;
    }
</script>
<script>
    let or = false
    while(or){
        alert('你猜我为啥不执行')
    }
</script>

# do while 循环🌳

💠

执行流程:先无条件的执行一次循环后判断循环条件是否成立

<script>
    let num = 1;
    do{
        document.write(`你好,js${num}<br>`)
        if(num == 3){
            break
        }
        num++;
    }while(num <= 5)
</script>
<script>
    // 条件为 false
    let or = false;
    do{
        let str = prompt(`
        1.继续
        2.不玩了
        `)
        switch(str){
            case '1':
                or = true
                break
            case '2':
                or = false
                break
            default:
                alert('请输入存在的选项')
        }
        alert('do!')
    }while(or)// 初始条件为 false, 但是先让你玩一局
</script>

while 和 do while 的区别:🗡

while: 执行时先判断循环条件是否成立

do while: 先无条件执行一次,再判断循环条件是否成立

# for 循环🌳

💠

作用:重复执行代码

好处:把声明起始值,循环条件,变化值写到一起,让人一目了然,它是最常使用的循环形式

语法格式:🎲

for(变量起始值;终止条件;变量变化量){
   // 循环体
}
<script>
    // 变量起始值;终止条件;变量变化量
    for(let i = 0;i < 3;i ++){
        // 循环体
        document.write(`你好,js<br>`)
    }
</script>

for 循环的最大价值:<font style="color:red"> 循环遍历数组 </font>.

📋需求:将数组 [' 马超 ',' 赵云 ',' 张飞 ',' 关羽 ',' 黄忠 '] 依次打印出来

<script>
    let arr = ['马超','赵云','关羽','黄忠']
    // 循环遍历数组中的元素
    for(let i = 0,end = arr.length;i < end;i ++){
        // 判断如果 i 小于数组长度说明后面还有元素,i+1 略过最后一个的打印
        if(arr.length > i + 1){
            // 写出的元素后面跟着,
            document.write(arr[i]+',')
        }else{
            // 写出最后一个元素后面什么没有
            document.write(arr[i])
        }
    }
</script>

效果:

image-20230424164126948

# for 循环和 while 循环的区别🌳

💠

for: 在已知循环次数的情况下使用 for 循环

while:在不确定循环次数的情况下使用 while 循环,它是判断执行的

# for 循环嵌套🌳

💠

for(外部声明记录循环次数的变量;循环条件;变化值){
   for(内部声明记录循环次数的变量;循环条件;变化值){
      循环体
   }
}
  • 一个循环里再嵌套一个循环,一般用在 for 循环里,当然其它循环也可以嵌套,但是没有不知道循环次数的情况下还要嵌套循环的情况的!建议循环嵌套使用 for !

📋计算:每天记住 5 个单词,3 天后一共能记住多少单词?

<script>
    for(let i = 0;i < 3;i ++){
        document.write(`${i+1}天<br>`)
       for(let j = 0;j < 5;j ++){
           document.write(`记住了${j+1}个单词<br>`)
       }
    }
</script>

效果:

image-20230424171529564

# 循环跳转🌳

# break🌴

💠

跳出当前循环结构,执行后面的代码

# continue🌴

💠

结束本次循环,继续下次循环

区别:🗡

  • continue 退出本次循环,执行下一次循环,一般用于排除或者跳过某一个选项的时候,可以使用 continue
  • break 退出整个循环,并不是结束程序,还会执行循环后面的代码,一般用于结果已经得到,后续的循环不需要的时候可以使用

# 案例 - 模拟银行存取款🎄

<script>
    let money = 0
    while(true){
        let n = prompt(`
    1.存钱💲
    2.取钱💲
    3.查看余额💲
    4.退出💫
    `);
        let n_num
        switch(n){
            case '1':
                let num = +prompt('请输入您存的数😁:')
                if(num === num){
                    if(num === 0){
                        alert('这么穷🥱?')
                    }else if(num < 0){
                        alert('你Tm认真的吗🤬?')
                    }
                    money += num
                }else{
                    alert('您输入的是数字吗?🤔')
                }
                break
            case '2':
                let num1 = +prompt('请输入您要取的数🙄:')
                if(money === 0){
                    alert('你一个穷光蛋🥚取什么钱,没钱滚蛋😡')
                    break
                }
                n_num = money
                money -= num1
                if(money < 0){
                    money = n_num
                    alert('你TM别那么多钱就别取👿')
                    break
                }
                break
            case '3':
                if(money <= 10){
                    alert(`您存储的余额为🤨:${money} 💲 穷B`)
                    break
                }
                alert(`您存储的余额为🥰:${money} 💲`)
                break
            case '4':
                alert('确认,程序退出 ? -_-!')
                break
            default:
                continue
        }
        if(n === '4'){
            break
        }
    }
</script>