JavsScript基础语法01
目录
- 1. JavaScript的书写位置
- 2. JavaScript注释
- 3. JavaScript输入输出语句
- 4. 变量
- 4.1 let 和 const命令
- 5. 数据类型
- 5.1 简单数据类型
- 5.2 获取变量数据类型
- 5.3 数据类型转换
- 5.4 模板字符串
- 6. 运算符
- 6.1 算术运算符
- 6.2 递增和递减运算符
- 6.3 比较运算符
- 6.4 逻辑运算符
- 6.5 赋值运算符
- 6.6 运算符优先级
- 6.7 5种方法交换两个变量的值
- 6.8 变量的解构赋值
- 6.9 对象的解构赋值
- 6.10 字符串的解构赋值
- 7. 流程控制
- 7.1 顺序流程控制
- 7.2 分支流程控制
- 8. 循环
- 8.1 while循环
- 8.2 do...while循环
- 8.3 for循环
- 8.4 循环语句的嵌套
- 8.5 continue和break
1. JavaScript的书写位置
JS
有3种书写位置,分别为行内、内嵌和外部。行内式写法如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JS的书写位置</title>
</head>
<body>
<!--第一种: 行内式-->
<input type="button" value="点我试试" onclick="alert('Hello World')">
</body>
</html>
- 可以将单行或少量
JS
代码写在HTML
标签的事件属性中(以on
开头的属性) 如:onclick - 可读性差,在
html
中编写JS
大量代码时,不方便阅读 - 引号易错,引号多层嵌套匹配时,非常容易弄混
- 特殊情况下使用
内嵌式写法如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JS的书写位置</title>
</head>
<body>
</body>
</html>
<script>alert("Hello World");
</script>
- 可以将多行
JS
代码写到script
标签中 - 内嵌
JS
是学习时常用的方式
外部JS文件写法如下,先新建一个外部的 JS
文件,并在其中编写 JS
代码,然后在 HTML
中进行引入:
引入的 HTML
代码如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JS的书写位置</title>
</head>
<body>
</body>
</html>
<!--第三种: 外部js文件 -->
<script src="test.js"></script>
- 利于
HTML
页面代码结构化,把大段JS
代码独立到HTML
页面之外,既美观,也方便文件级别的复用 - 引用外部
JS
文件的script
标签中间不可以写代码 - 适合于
JS
代码量比较大的情况
2. JavaScript注释
为了提高代码的可读性,JS
与 HTML/CSS
一样,也提供了注释功能。JS中的注释主要有两种,分别是 单行注释
和 多行注释
。示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JS中的注释</title>
</head>
<body></body>
</html>
<script>// 单行注释的注释方式如下:// 我是Amo 不想被js引擎执行 注释起来 //用来注释单行文字// 一般单行注释的快捷键为: ctrl/command + /console.log(1111); //控制台输出打印// 多行注释的注释方式如下:// 一般多行注释的快捷键为: ctrl/command + shift + / 不同的编辑器快捷键不同/* 1.发送请求获取响应2.判断请求是否成功 如果成功 解析数据* */
</script>
上述代码运行结果如下:
3. JavaScript输入输出语句
为了方便信息的输入输出,JS
中提供了一些输入输出语句,其常用的语句如下:
方法 | 说明 | 归属 |
---|---|---|
alert(msg) | 浏览器弹出警示框 | 浏览器 |
console.log(msg) | 浏览器控制台打印输出信息 | 浏览器 |
prompt(info) | 浏览器弹出输入框,用户可以输入 | 浏览器 |
示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JS中的输入输出语句</title>
</head>
<body></body>
</html>
<script>alert("Hello World");console.log("Hello World");// 可以使用一个变量来存储用户录入的值idCard = prompt("请输入您的身份证号码:");console.log(idCard);
</script>
4. 变量
变量就是一个装东西的盒子。变量是用于存放数据的容器。 我们通过 变量名
获取数据,甚至数据可以修改。
本质:变量是程序在内存中申请的一块用来存放数据的空间。类似我们酒店的房间,一个房间就可以看做是一个变量。为了节省空间,笔者后续给出的示例代码都将省略 HTML/CSS
的代码,变量的使用如下:
<script>//var是一个JS关键字,用来声明变量。使用该关键字声明变量后,计算机会自动为变量分配内存空间//第一种方式: 先声明 后赋值var age; //age 定义的变量名 要符合一定的规则 ==> 教室的门牌号age = 10; //赋值 ==>教室中的同学 通过age找到同学age = 20; //更新变量 即age被重新赋值//第二种: 变量的初始化 即声明变量的同时给它赋值var name = "Amo";//第三种: 同时声明多个变量var school = "重庆大学", address = "重庆市沙坪坝区";
</script>
变量命名规范:
- 由字母
(A-Za-z)
、数字(0-9)
、下划线(_)
、美元符号( $ )
组成,如:usrAge, num01, _name - 严格区分大小写。var app; 和 var App; 是两个变量
- 不能以数字开头。
18age
是错误的 - 不能是关键字、保留字。例如:var、for、while
- 变量名必须有意义。 MMD BBD nl → age
- 遵守驼峰命名法。首字母小写,后面单词的首字母需要大写。如:myFirstName
4.1 let 和 const命令
ES6
新增了 let
命令,用于声明变量。其用法类似于 var
,但是所声明的变量只在 let
命令所在的代码块内有效。示例代码如下:
<script>//{}表示代码块{var a = 1;let b = 2;}console.log(a);console.log(b);
</script>
上述代码执行结果如下:
for
循环的计数器就非常适合 let
命令,示例代码如下:
<script>var arr1 = [];for (var i = 0; i < 10; i++) {arr1[i] = function () {return i;}}/*上述代码中 变量i是var声明的 即全局范围内有效,每一次循环i的值都会发生改变而循环内 被赋值给数组a的函数内部的i指向全局的i 所有数组a的成员中的i指向的都是同一个i 导致运行时输出的是最后一轮的i值也就是10。*/console.log(arr1[2]());//10var arr2 = [];for (let i = 0; i < 10; i++) {arr2[i] = function () {return i;}}/*上面的代码中,变量i是let声明的,当前的i只在本轮循环有效。所以每一次循环的i其实都是一个新的变量,于是最后输出的是6。 JavaScript引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。*/console.log(arr2[2]());//2
</script>
上述代码执行结果如下:
另外,for
循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。示例代码如下:
<script>for (let i = 0; i < 3; i++) {let i = "abc";console.log(i)}
</script>
上述代码执行结果如下:
正确运行以上代码将输出 3次abc
。这表明函数内部的变量 i
与循环变量 i
不在同一个作用域,而是有各自单独的作用域。let
声明变量不存在变量提升,示例代码如下:
<script>console.log(foo); //输出undefinedvar foo = 2;//let的情况console.log(bar);let bar = 2;
</script>
上述代码执行结果如下:
只要块级作用域内存在 let
命令,它所声明的变量就 绑定(binding)
这个区域,不再受外部的影响。示例代码如下:
<script>var temp = 123;if(true){temp = "abc";let temp;}
</script>
上述代码运行结果如下:
上面的代码中存在全局变量 temp
,但是块级作用域内 let
又声明了一个全局变量 temp
,导致后者绑定这个块级作用域,所以在 let
声明变量前,对 temp
赋值会报错。ES6
明确规定,如果区块中存在 let
和 const
命令,则这个区块对这些命令声明的变量从一开始就形成封闭作用域。只要在声明之前就使用这些变量,就会报错。总之,在代码块中,使用 let
命令声明变量之前,该变量都是不可用的。这在语法上称为 暂时性死区(temporal dead zone)
,简称 TDZ
。在看看下面这个例子:
<script>console.log(typeof y); //undefinedconsole.log(typeof x);let x;
</script>
上述代码执行结果如下:
上面的代码中,变量 x
使用 let
命令声明,所以在声明之前都属于 x
的 死区
,只要用到该变量就会报错。因此 typeof
运行时就会抛出一个 ReferenceError
。作为比较,如果一个变量根本没有被声明,使用 typeof
反而不会报错。这样的设计是为了让大家养成良好的编程习惯,变量一定要在声明之后使用,否则就会报错。有些 死区
比较隐蔽,不太容易发现。示例代码如下:
<script>function bar(x = y, y = 2) {return [x, y];}bar();//报错
</script>
上述代码执行结果如下:
上面的代码中,调用 bar
函数之所以报错(某些实现可能不报错),是因为参数 x
的默认值等于另一个参数 y
,而此时 y
还没有声明,属于 死区
。如果 y
的默认值是 x
,就不会报错,因为此时 x
已经声明。另外下面的代码也会报错,与 var
的行为不同。
<script>var x = x;console.log(x)let y = y;console.log(y);
</script>
上述代码执行结果如下:
以上代码出错也是因为暂时性死区,使用 let
声明变量时,只要变量在还没有声明前使用,就会报错。let
不允许在相同作用域内重复声明同一个变量。示例代码如下:
<script>var a = 10;var a = 20; // 可以重复声明不报错let x = 1;let x = 2; //报错
</script>
上述代码执行结果如下:
const
声明一个只读的常量。一旦声明,常量的值就不能改变。注意 const
具备上面 let
所述的所有特性,如下图所示:
const
实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值) 而言,值就保存在变量指向的内存地址中。因此等同于常量。但对于复合类型的数据(主要是对象和数组)而言,变量指向的内存地址保存的只是一个指针(引用),const
只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,这完全不能控制。示例代码如下:
<script>const person = {};// 为foo添加一个属性person.name = "Amo";console.log(person.name);// 将person指向另一个对象 就会报错person = {};
</script>
上述代码执行结果如下:
补充一点,let
声明变量不会污染全局变量,示例代码如下:
<script>// console.log(window.a)//let RegExp = 2;//console.log(RegExp) // 2//console.log(window.RegExp) // ƒ RegExp() { [native code] }var RegExp = 3;console.log(RegExp) // 3console.log(window.RegExp) // 3
</script>
上面补充的关于一些 ES6
的新特性,参考阮一峰 ES6标准入门
一书,一些解释性文字就直接拿过来了,当作学习使用,如有侵权,请联系笔者删除。如果是刚学习 JS
的读者可以先跳过这部分的学习。
5. 数据类型
在计算机中,不同的数据所需占用的存储空间是不同的,为了便于把数据分成所需内存大小不同的数据,充分利用存储空间,于是定义了不同的数据类型。简单来说,数据类型就是数据的类别型号。比如姓名 张三
,年龄 18
,这些数据的类型是不一样的。JS
把数据类型分为两类:
5.1 简单数据类型
示例代码如下:
<script>//JS弱类型语言(动态语言) 自动根据=右边变量值的数据类型来判断var age = 21; //整数 默认为十进制var height = 18;//小数console.log(Number.MAX_VALUE) //JS中数值的最大值console.log(Number.MIN_VALUE) //JS中数值的最小值//数字型三个特殊值console.log(1 / 0); //Infinity: 代表无穷大,大于任何数值console.log(-1 / 0); // -Infinity: 代表无穷小,小于任何数值// isNaN: 非数字返回true 数字返回falseconsole.log(isNaN(age)); // false //字符串 用双引号或者单引号即可var name = "Amo"; // 'Amo'console.log(name.length); // 输出字符串长度 3var address = "重庆市'沙坪坝区'" // 注意:JS外双内单 外单内双 否则会报错var sex = '我是"男"的'//字符串拼接 常用到var personInfo = "Amo" + "--" + "好帅~"console.log(personInfo); //Amo--好帅~ +用来连接var num1 = 10;console.log("10" + 100); //10100//布尔值 要么是true 要么是false 即非真就假console.log(true);console.log(true + 1);//1 true在参与运算的时候会转换为1 false转换为0//一个声明后没有被赋值的变量会有一个默认值undefinedvar company;console.log(company); //undefinedconsole.log(company + 11);//NaN//一个声明变量给null值,里面存的值为空 后续深入讲解console.log(11 + null) //null参与运算时转换为0
</script>
5.2 获取变量数据类型
typeof
可用来获取检测变量的数据类型,示例代码如下:
<script>var age = 18;console.log(typeof age); //number
</script>
不同类型的返回值如下图所示:
5.3 数据类型转换
使用表单、prompt
获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算,而需要转换变量的数据类型。通俗来说,就是把一种数据类型的变量转换成另一种数据类型,通常会实现 3
种方式的转换:
转换为字符串类型
转换为数字型
转换为布尔型
转换为字符串,如下图所示:
隐式转换是我们在进行算数运算的时候,JS
自动转换了数据类型。转换为数字型(重点),如下图所示:
转换为布尔型,如下图所示:
代表空、否定的值会被转换为false
,如 0/NaN/null/undefined
其余值都会被转换为 true
。
5.4 模板字符串
模板字符串(template string)
是增强版的字符串,用反引号( `)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>模板字符串</title>
</head>
<body>
<div id="box"></div>
</body>
</html>
<script>// 需求: 现在我想要将ul>li 标签写入id为box的盒子中const oBox = document.querySelector("#box")let id = "desc";let desc = "Amo so cool~";// 传统的方法字符串拼接 一旦拼接字符串太长多 容易乱//oBox.innerHTML = "<ul><li id='" + id + "'>" + desc + "</li></ul>"// 使用模板字符串拼接oBox.innerHTML = `<ul><li id="${id}">${desc}</li></ul>`;let x = 1;let y = 2//大括号内可以放入任意的JS表达式 可以进行计算以及引用对象属性。console.log(`${x} + ${y * 2} = ${x + y * 2}`);
</script>
上述代码执行结果如下:
关于 模板字符串
还有一些更复杂的操作,可以参考阮一峰的ES6 标准入门
一书。
6. 运算符
运算符(operator)
也被称为操作符,是用于实现赋值、比较和执行算数运算等功能的符号。JavaScript
中常用的运算符有:
- 算术运算符
- 递增和递减运算符
- 比较运算符
- 逻辑运算符
- 赋值运算符
6.1 算术运算符
算术运算使用的符号,用于执行两个变量或值的算术运算。
要注意的一个点是 浮点数的精度问题
,浮点数值的最高精度是 17
位小数,但在进行算术计算时其精确度远远不如整数。示例代码如下:
<script>let result = 0.1 + 0.2;console.log(result);console.log(0.07 * 100);
</script>
上述代码执行结果如下:
所以:不要直接判断两个浮点数是否相等 !
6.2 递增和递减运算符
如果需要反复给数字变量 添加或减去1
,可以使用 递增(++)
和 递减(--)
运算符来完成。在 JavaScript
中,递增(++)
和 递减(--)
既可以放在变量前面,也可以放在变量后面。放在变量前面时,我们可以称为 前置递增(递减)
运算符,放在变量后面时,我们可以称为 后置递增(递减)
运算符。注意:递增和递减运算符必须和变量配合使用。 示例代码如下:
<script>// 1.前置递增运算符和后置递增运算符单独参与运算的时候无差别let num1 = 1;num1++;console.log(num1);//2let num2 = 1;++num2;console.log(num2);//2//2.参与复合运算的时候let num3 = 10;//先自+1 在求和 ==> num3=10+1 ==> num3+10 ==>21console.log(++num3 + 10);//21let num4 = 10;//先返回原值求和 后自加 ==> num4+10 ==> 20 最后结果// 后自增: num4=10+1=11 但是这个值已经不参与运算了console.log(num4++ + 10); //20
</script>
6.3 比较运算符
比较运算符(关系运算符) 是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值 true/false
作为比较运算的结果。
等号的比较要特别注意,如下图所示:
示例代码如下:
<script>console.log(18 == "18"); //trueconsole.log(18 === "18"); // false
</script>
6.4 逻辑运算符
逻辑运算符是用来进行布尔值运算的运算符,其返回值也是布尔值。后面开发中经常用于多个条件的判断。
逻辑与 &&
,两边都是true才返回true,否则返回false。
逻辑或 ||
,两边都是false才返回false,否则返回true。
逻辑非 (!)
也叫作取反符,用来取一个布尔值相反的值,如true 的相反值是 false。示例代码如下:
<script>let isOk = true;console.log(!isOk);//false
</script>
短路运算(逻辑中断)
:当有多个表达式(值)时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值。示例代码如下:
<script>// 1.逻辑与 表达式1&&表达式2&&表达式3...// 有0则返回0 否则返回最后一个非0数字console.log(123 && 456); // 456console.log(0 && 456); // 0console.log(123 && 456 && 789); // 789// 2.逻辑或 表达式1||表达式2||表达式3...// 返回第一个非0数字console.log(123 || 456); // 123console.log(0 || 456); // 456console.log(123 || 456 || 789); // 123
</script>
6.5 赋值运算符
用来把数据赋值给变量的运算符。
6.6 运算符优先级
6.7 5种方法交换两个变量的值
<script>// 第一种写法: 使用第三方变量let a = 10;let b = 20;console.log(`交换变量值之前a为:${a} b为:${b}`);let temp = a;a = b;b = a;console.log(`交换变量值之后a为:${a} b为:${b}`);console.log("******************************");// 第二种写法: 算术运算符的方式let x = 10;let y = 20;console.log(`交换变量值之前x为:${x} y为:${y}`);let sum = x + y;x = sum - x;y = sum - x;console.log(`交换变量值之后x为:${x} y为:${y}`);console.log("******************************");// 第三种写法: 位运算的方式let m = 10;let n = 20;console.log(`交换变量值之前m为:${m} n为:${n}`);m = m ^ n;n = m ^ n;m = m ^ n;console.log(`交换变量值之后m为:${m} n为:${n}`);console.log("******************************");// 第四种写法: 解构赋值let i = 10;let j = 20;console.log(`交换变量值之前i为:${i} j为:${j}`);[i, j] = [j, i];console.log(`交换变量值之后i为:${i} j为:${j}`);console.log("******************************");// 第五种写法: 一句话搞定let c = 10;let d = 20;console.log(`交换变量值之前c为:${c} d为:${d}`);c = (c + d) - (d = c);console.log(`交换变量值之后c为:${c} d为:${d}`);
</script>
上述代码执行结果如下所示:
6.8 变量的解构赋值
在上述交换两个变量的时候,我们提到了 解构赋值
的概念。ES6
允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,这被称为 解构(Destructuring).
示例代码如下:
<script>// 以前为变量赋值只能直接指定值let a = 1, b = 2, c = 3;console.log(a, b, c);// ES6允许这样写let [l, m, n] = [1, 2, 3];//可以从数组中提取值 按照对应位置对变量赋值console.log(l, m, n);
</script>
本质上这种写法属于 模式匹配
,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。
<script>let [foo, [[bar], baz]] = [1, [[2], 3]];console.log(foo, bar, baz) // 1 2 3let [, , third] = ["amo", "jerry", "paul"];console.log(third); //paullet [x, , y] = [1, 2, 3];console.log(x, y); // 1 3let [head, ...tail] = [1, 2, 3, 4];console.log(head, tail);// 1 [2,3,4]let [a, b, ...c] = ["amo"];//如果解构不成功 变量的值就等于undefinedconsole.log(a, b, c); // amo undefined []let [m] = [];let [i, j] = [1]; //这两种解构都属于不成功console.log(m, i, j); //undefined 1 undefined
</script>
上述代码执行结果为:
另一种情况是 不完全解构
,即等号左边的模式只匹配一部分的等号右边的数组,这种情况下,解构依然可以成功。示例代码如下:
<script>let [x, y] = [1, 2, 3];console.log(x, y); // 1 2let [a, [b], c] = [1, [2, 3], 4];console.log(a, b, c) // 1 2 4//上面两个例子都属于不完全解构,但是可以成功。let [m, n] = 1;console.log(m, n);
</script>
上述代码执行结果如下:
对于 Set
结构,也可以使用数组的解构赋值。示例代码如下:
<script>let [x, y, z] = new Set(["Amo", "Jerry", "Paul"]);console.log(x, y, z); // Amo Jerry Paul
</script>
事实上,只要某种数据结构具有 Iterator
接口,都可以采用数组形式的解构赋值。解构赋值
还允许指定默认值,示例代码如下:
<script>let [a = true] = [];console.log(a);let [x, y = "b"] = ["a"];console.log(x, y); // a b//ES6内部使用严格相等运算符(===)判断一个位置是否有值,所以,如果//一个数组成员不严格等于undefined,默认值是不会改变的let [m, n = "b"] = ["a", undefined];console.log(m, n); // a blet [b = 1] = [undefined]; //这里是undefined理解为没值 则默认值为1console.log(b); // 1let [l = 1] = [null];console.log(l); // null
</script>
如果默认值是一个表达式,那么这个表达式是 惰性
求值的,即只有在用到时才会求值。示例代码如下:
<script>function f() {console.log("aaa");}let [x = f()] = [1];console.log(x); // 因为x能取到值,所以函数f根本不会执行//默认值可以引用解构赋值的其它变量,但该变量必须已经声明let [a = 1, b = a] = [];console.log(a, b);let [m = 1, n = m] = [2];console.log(m, n);let [j = 1, k = j] = [1, 2];console.log(j, k);let [o = p, p = 1] = [];console.log(o, p);
</script>
上述代码执行结果如下:
6.9 对象的解构赋值
解构不仅可以用于数组,还可以用于对象。示例代码如下:
<script>let {name, age} = {name: "Amo", age: 18}console.log(name, age) // Amo 18
</script>
上述代码执行结果如下:
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定。而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。示例代码如下:
<script>let {name, age} = {age: 18, name: "Amo"};console.log(name, age); // Amo 18let {address} = {sex: "男", hobby: "唱歌"};console.log(address) // undefined
</script>
如果变量名与属性名不一致,示例代码如下:
<script>let {foo: baz} = {foo: "aaa", bar: "bbb"};console.log(baz) // aaalet obj = {first: "hello", last: "world"};let {first: f, last: l} = obj;console.log(f, l); // hello world//实际上,对象的解构赋值是下面形式的简写let {a: a, b: b} = {a: "aaa", b: "bbb"};console.log(a, b); // aaa bbb//也就是说,对象的解构赋值的内部机制是先查找到同名属性,然后在赋值给对应的变量。//真正被赋值的是后者,而不是前者let {name: age} = {name: "amo", address: "重庆市沙坪坝区"}console.log(age); // amo
</script>
与数组一样,解构也可以用于嵌套结构的对象。示例代码如下:
<script>let obj = {p: ["hello",{y: "world"}]}let {p: [x, {y}]} = obj;console.log(x, y); // hello world
</script>
注意,这时 p
是模式,不是变量,因此不会被赋值。如果 p
也要作为变量赋值,可以写成下面这样。
<script>let obj = {p: ["Hello",{y: "World"}]};let {p, p: [x, {y}]} = obj;console.log(x, y, p);
</script>
上述代码执行结果如下:
下面是另一个例子。
<script>let node = {loc: {start: {line: 1,column: 5}}}let {loc, loc: {start}, loc: {start: {line}}} = node;console.log(line);console.log(start);console.log(loc);
</script>
上述代码执行结果如下:
下面是嵌套赋值的例子:
<script>let obj = {};let arr = [];({foo: obj.prop, bar: arr[0]} = {foo: 123, bar: true});console.log(obj);console.log(arr);//对象指定默认值let {x = 3} = {};console.log(x);let {a, b = 5} = {a: 1};console.log(a); //1console.log(b); //5let {m: n = 3} = {};console.log(n); //3let {i: j = 3} = {i: 5};console.log(j); //5 默认值生效的条件是,对象的属性值严格等于undefined//对象的解构赋值可以很方便地将现有对象的方法赋值到某个变量let {log, sin, cos} = Math;//由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构let arr2 = [1, 2, 3];let {0: first, [arr2.length - 1]: last} = arr2;console.log(first, last); // 1 3
</script>
上述代码执行结果如下:
6.10 字符串的解构赋值
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。示例代码如下:
<script>const [a, b, c, d, e] = "hello";console.log(a, b, c, d, e);//类似数组的对象都有一个length属性,因此还可以对这个属性进行解构赋值let {length: len} = "hello";console.log(len);//5
</script>
上述代码执行结果如下:
7. 流程控制
在一个程序执行的过程中,各条代码的执行顺序对程序的结果是有直接影响的。很多时候我们要通过控制代码的执行顺序来实现我们要完成的功能。简单理解:流程控制就是来控制代码按照一定结构顺序来执行。 流程控制主要有三种结构,分别是顺序结构、分支结构 和 循环结构,代表三种代码执行的顺序。
7.1 顺序流程控制
顺序结构是程序中最简单、最基本的流程控制,它没有特定的语法结构,程序会按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。
7.2 分支流程控制
由上到下执行代码的过程中,根据不同的条件,执行不同的路径代码(执行代码多选一的过程),从而得到不同的结果。
JS
语言提供了两种分支结构语句:if
语句、switch
语句。if
语句语法结构如下:
// 条件成立执行代码,否则什么也不做
if (条件表达式) {// 条件成立执行的代码语句
}
示例代码如下:
<script>let age = 20;if (age > 18) {console.log("成年了,可以上网打撸了!");}
</script>
上述代码执行结果为:
if else
语句(双分支语句),语法结构如下:
// 条件成立 执行if里面代码,否则执行else里面的代码
if (条件表达式) {// [如果] 条件成立执行的代码
} else {// [否则] 执行的代码
}
如果某一年是闰年,那么这一年的2月份就有29天,否则这一年的2月份就有28天。应用 if…else
语句判断2020年2月份的天数。代码如下:
<script>let year = 2020;let month = 0;//判断指定年是否是闰年if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) {month = 29;} else {month = 28;}console.log(`2020年2月份的天数为${month}`);
</script>
上述代码执行结果为:
if else if
语句(多分支语句) 语法结构如下:
// 适合于检查多重条件。
if (条件表达式1) {语句1;
} else if (条件表达式2) {语句2;
} else if (条件表达式3) {语句3;....
} else {// 上述条件都不成立执行此处代码
}
将某学校的学生成绩转化为不同等级,划分标准如下:
① 优秀大于等于90分
② 良好大于等于75分
③ 及格大于等于60分
④ 不及格小于60分
假设Amo的考试成绩是85分,输出该成绩对应的等级。其关键代码如下:
<script>let score = 85;if (score < 60) {console.log("不及格");} else if (score < 74) {console.log("及格");} else if (score < 90) {console.log("良好");} else {console.log("优秀");}
</script>
上述代码执行结果为:
if
语句不但可以单独使用,而且可以嵌套应用,即在 if
语句的从句部分嵌套另外一个完整的 if
语句。基本语法格式如下:
if (表达式1){if(表达式2){语句1}else{语句2}
}else{if(表达式3){语句3}else{语句4}
}
例如,Amo的高考总分是620,英语成绩是120。假设重点本科的录取分数线是600,而英语分数必须在 130
以上才可以报考外国语大学,应用 if语句
的嵌套判断该考生能否报考外国语大学,代码如下:
<script>const totalScore = 620;const englishScore = 120;if (totalScore > 600) {if (englishScore > 130) {console.log("能报考外国语大学!");} else {console.log("该考生可以报考重点本科,但不能报考外国语大学!");}} else {if (totalScore > 500) {console.log("该考生可以报考普通本科");} else {console.log("该考生只能报考专科");}}
</script>
上述代码执行结果为:
三元表达式,语法结构如下:
表达式1 ? 表达式2: 表达式3;
- 如果表达式
1
为 true ,则返回表达式2
的值,如果表达式1为 false,则返回表达式3的值 - 简单理解: 就类似于
if else(双分支)
的简写 示例代码如下:<script>let x = 4 > 5 ? 1 : 2;console.log(x); // 2 </script>
switch
分支流程控制,switch
语句也是多分支语句,它用于基于不同的条件来执行不同的代码。当要针对变量设置一系列的特定值的选项时,就可以使用 switch
。语法格式如下:
switch (表达式){case 常量表达式1:语句1;break;case 常量表达式2:语句2;break;…case 常量表达式n:语句n;break;default:语句n+1;break;
}
参数说明:
- 表达式:任意的表达式或变量。
- 常量表达式:任意的常量或常量表达式。当表达式的值与某个常量表达式的值相等时,就执行此
case
后相应的语句。如果表达式的值与所有的常量表达式的值都不相等,则执行default
后面相应的语句。 - break:用于结束
switch
语句,从而使JavaScript
只执行匹配的分支。如果没有了break
语句,则该匹配分支之后的所有分支都将被执行,switch
语句也就失去了使用的意义。
switch
语句的执行流程如下图所示:
default
语句可以省略。在表达式的值不能与任何一个 case
语句中的值相匹配的情况下,JavaScript
会直接结束 switch
语句,不进行任何操作。case
后面常量表达式的数据类型必须与表达式的数据类型相同,否则匹配会全部失败,而去执行 default
语句中的内容。某公司年会举行抽奖活动,中奖号码及其对应的奖品设置如下:
① 1
代表 一等奖
,奖品是 华为手机
② 2
代表 二等奖
,奖品是 光波炉
③ 3
代表 三等奖
,奖品是 电饭煲
④ 其他号码代表 安慰奖
,奖品是 16G-U盘
假设Amo抽中的奖号为3,输出该员工抽中的奖项级别以及所获得的奖品。代码如下:
<script>let grade = ""; //定义表示奖项级别的变量let prize = ""; //定义表示奖品的变量let code = 3; //定义表示中奖号码的变量值为3switch (code) {case 1:grade = "一等奖";prize = "华为手机";break;case 2:grade = "二等奖";prize = "光波炉";break;case 3:grade = "三等奖";prize = "电饭煲";break;default:grade = "安慰奖";prize = "16G-U盘";break;}document.write(`该员工获得了${grade}<br/>奖品是${prize}`)
</script>
上述代码执行结果为:
在程序开发的过程中,使用 if
语句还是使用 switch
语句可以根据实际情况而定,尽量做到物尽其用,不要因为 switch
语句的效率高就一味地使用,也不要因为 if
语句常用就不应用 switch
语句。要根据实际的情况,具体问题具体分析,使用最适合的条件语句。一般情况下对于判断条件较少的可以使用 if
条件语句,但是在实现一些多条件的判断中,就应该使用 switch
语句。
8. 循环
8.1 while循环
while
循环语句也称为前测试循环语句,它是利用一个条件来控制是否要继续重复执行这个语句。while
循环语句与 for
循环语句相比,无论是语法还是执行的流程,都较为简明易懂。while循环语句的语法格式如下:
while(表达式){语句
}
参数说明:
- 表达式:一个包含比较运算符的条件表达式,用来指定循环条件。
- 语句:用来指定循环体,在循环条件的结果为
true
时,重复执行。
while
循环语句之所以命名为前测试循环,是因为它要先判断此循环的条件是否成立,然后才进行重复执行的操作。也就是说,while
循环语句执行的过程是先判断条件表达式,如果条件表达式的值为true
,则执行循环体,并且在循环体执行完毕后,进入下一次循环,否则退出循环。while
循环语句的执行流程如下图所示。
例如,应用 while
语句输出1~10
这10个数字的代码如下:
<script>let i = 1;while (i <= 10) {console.log(i);i++;}
</script>
上述代码执行结果如下:
8.2 do…while循环
do…while
循环语句也称为后测试循环语句,它也是利用一个条件来控制是否要继续重复执行这个语句。与 while
循环所不同的是,它先执行一次循环语句,然后再去判断是否继续执行。do…while
循环语句的语法格式如下:
do{语句
} while(表达式);
参数说明:
- 语句:用来指定循环体,循环开始时首先被执行一次,然后在循环条件的结果为
true
时,重复执行。 - 表达式:一个包含比较运算符的条件表达式,用来指定循环条件。
do…while
循环语句执行的过程是:先执行一次循环体,然后再判断条件表达式,如果条件表达式的值为 true
,则继续执行,否则退出循环。也就是说,do…while
循环语句中的循环体至少被执行一次。do…while
循环语句的执行流程如下图所示。
do…while
循环语句同 while
循环语句类似,也常用于循环执行的次数不确定的情况下。do…while
语句结尾处的 while
语句括号后面有一个分号;
,为了养成良好的编程习惯,建议读者在书写的过程中不要将其遗漏。例如,应用 do…while
语句输出 1~10
这10个数字的代码如下:
<script>let j = 1;do {console.log(j);j++;} while (j <= 10);
</script>
do…while
语句和 while
语句的执行流程很相似。由于do…while
语句在对条件表达式进行判断之前就执行一次循环体,因此do…while
语句中的循环体至少被执行一次,下面的代码说明了这两种语句的区别。
<script>let i = 1; //声明变量while (i > 1) { //定义while语句,指定循环条件document.write("i的值是" + i); //输出i的值i--; //变量i自减1}let j = 1; //声明变量do { //定义do...while语句document.write("j的值是" + j); //输出变量j的值j--; //变量j自减1} while (j > 1);
</script>
上述代码执行结果如下:
8.3 for循环
for
循环语句也称为计次循环语句,一般用于循环次数已知的情况,在 JavaScript
中应用比较广泛。for循环语句的语法格式如下:
for(初始化表达式;条件表达式;更新表达式){语句
}
参数说明:
- 初始化表达式:初始化语句,用来对循环变量进行初始化赋值。
- 条件表达式:循环条件,一个包含比较运算符的表达式,用来限定循环变量的边限。如果循环变量超过了该边限,则停止该循环语句的执行。
- 更新表达式:用来改变循环变量的值,从而控制循环的次数,通常是对循环变量进行增大或减小的操作。
- 语句:用来指定循环体,在循环条件的结果为
true
时,重复执行。
for
循环语句执行的过程是:先执行初始化语句,然后判断循环条件,如果循环条件的结果为 true
,则执行一次循环体,否则直接退出循环,最后执行更新表达式,改变循环变量的值,至此完成一次循环。接下来将进行下一次循环,直到循环条件的结果为 false
,才结束循环。for
循环语句的执行流程如下图所示。
例如,应用 for
语句输出 1~10
这10个数字的代码如下:
<script>for (let i = 1; i <= 10; i++) {console.log(i);}
</script>
在使用 for
语句时,也一定要保证循环可以正常结束,也就是必须保证循环条件的结果存在为 false
的情况,否则循环体将无休止地执行下去,从而形成死循环。为使读者更好的了解for语句的使用,下面通过一个具体的实例来介绍 for
语句的使用方法。应用 for
循环语句计算 100以内所有奇数的和
,并在页面中输出计算后的结果。代码如下:
<script>let sum = 0;for (let i = 1; i <= 100; i++) {if (i % 2 != 0) {sum += i;}}console.log(`1-100的奇数和为${sum}`);
</script>
8.4 循环语句的嵌套
在一个循环语句的循环体中也可以包含其它的循环语句,这称为循环语句的嵌套。上述 3
种循环语句 (while循环语句、do…while循环语句和for循环语句) 都是可以互相嵌套的。如果循环语句 A
的循环体中包含循环语句 B
,而循环语句 B
中不包含其他循环语句,那么就把循环语句 A
叫做外层循环,而把循环语句 B
叫做内层循环。用嵌套的 for循环
语句输出乘法口诀表。代码如下:
<script>let i, j; //声明变量document.write("<pre>"); //输出<pre>标记for (i = 1; i < 10; i++) { //定义外层循环for (j = 1; j <= i; j++) { //定义内层循环if (j > 1) document.write("\t"); //如果j大于1就输出一个Tab空格document.write(j + "x" + i + "=" + j * i); //输出乘法算式}document.write("<br>"); //输出换行标记}document.write("</pre>"); //输出</pre>标记
</script>
上述代码执行结果如下:
8.5 continue和break
continue
语句用于跳过本次循环,并开始下一次循环。continue
语句只能应用在 while、for、do…while
语句中。例如,在 for
语句中通过 continue
语句输出 10以内不包括5
的自然数的代码如下:
<script>for (let i = 1; i <= 10; i++) {if (i == 5) {continue} //如果i等于5就跳过本次循环document.write(i + "\n"); //输出变量i的值}
</script>
上述代码执行结果如下:
当使用 continue
语句跳过本次循环后,如果循环条件的结果为 false
,则退出循环,否则继续下一次循环。在上面的 switch
语句中已经用到了 break
语句,当程序执行到 break
语句时就会跳出switch
语句。除了 switch
语句之外,在循环语句中也经常会用到break
语句。在循环语句中,break
语句用于跳出循环。break
语句通常用在for、while、do…while或switch
语句中。例如,在 for
语句中通过 break
语句跳出循环的代码如下:
<script>for (let i = 1; i <= 10; i++) {if (i == 5) break; //如果i等于5就跳出整个循环document.write(i + "\n"); //输出变量i的值}
</script>
上述代码执行结果如下:
JavsScript基础语法01相关推荐
- Python语法教程-基础语法01
目录 1. Python应用 2. 在Linux中写python 3. Python基础语法 1. 注释 2. 变量定义及类型 3. 格式化输出 4. 用户输入 5. 运算符 6.数据转换 7. 判断 ...
- Swif基础语法01
import Foundation /** * 1,第一个swift程序 */ println("Hello, World!") /** * 2,定义常量 */ let a = ...
- js基础语法(01)-JS中+号的三种含义
01-JS中+号的三种含义 (1)数学意义上的相加 : 1 + 1 会得到: 2 (2) 数学意义上的正负号: +5 正数 作用:可以把string类型转换成number类型 (3)字符串的连接符:' ...
- 【Java 基础语法01】 举例描述二进制和十进制的互转
本文笔记,参考课程图文 二进制和十进制互转 0.背景 人们生活:十进制数字 计算机:二进制 二进制:0.1两个数字,逢二进一位 示例: 1+1=10 逢二向前进一位 倒数第一位代表2的零次方=1 倒数 ...
- Verilog 基础语法01—逻辑值
逻辑值 逻辑 0:表示低电平,也就对应我们电路 GND: 逻辑 1:表示高电平,也就是对应我们电路的 VCC: 逻辑 X:表示未知,有可能是高电平,也有可能是低电平: 逻辑 Z:表示高阻态,外部没有激 ...
- Java初级·基础语法
基础语法* 01.关键字 关键字: Java预定义的有特殊含义的单词 特点 1.常用的开发工具高级记事本/IDE,能够变颜色的一些单词 2.都是小写字母组成 3.都是由特殊含义的单词 public : ...
- PHP的学习笔记 (php的基础语法)
目录 一.PHP基础语法 01.基础语法 1.标记与注释 2.输出语句 3.PHP标识符 4.PHP关键字 02.数据与运算 1.常量 2.变量 3.表达式 4.数据类型及转换 5.运算符及优先级 0 ...
- JSP、EL和JSTL-学习笔记01【JSP基础语法】
Java后端 学习路线 笔记汇总表[黑马程序员] JSP.EL和JSTL-学习笔记01[JSP基础语法] JSP.EL和JSTL-学习笔记02[MVC] JSP.EL和JSTL-学习笔记03[EL介绍 ...
- JavaScript学习笔记01【基础——简介、基础语法、运算符、特殊语法、流程控制语句】
w3school 在线教程:https://www.w3school.com.cn JavaScript学习笔记01[基础--简介.基础语法.运算符.特殊语法.流程控制语句][day01] JavaS ...
最新文章
- ggbiplot-最好看的PCA作图:样品PCA散点+分组椭圆+变量贡献与相关
- ElasticSearch教程——汇总篇
- 谷歌开放语音命令数据集,助力初学者利用深度学习解决音频识别问题
- 按字寻址与按字节寻址
- UNIX环境编程学习笔记(25)——信号处理进阶学习之 sigaction 函数
- 2016 Multi-University Training Contest 3
- leetcode 205. 同构字符串
- txt文件可存储最大值_Verilog边码边学:十六进制文件读取$readmemh
- 大数据学习笔记55:搭建HBase环境
- Pheatmap做热图数据处理过程
- 14.企业应用架构模式 --- Web表现模式
- axios的this指向_vue使用axios时this指向哪里
- 斐讯k2p 月光银 硬件版本A2-软件版本22.7.8.5 刷官改系统
- Win11到底意味着什么
- FreePic2PDF制作书签
- 陈家骏程序设计教程用c 语言编程答案,陈家骏程序设计教程用c 语言编程答案...
- 【运维心得】只有百度能打开,其他页面打不开怎么办?
- TCP/IP协议之常见的应用层协议——DNS域名系统
- CSS Reset(样式重置)
- sqlserver中计算日期差