[06] JS-基础语法(二)
1. 判断、循环#
1.1 if-else#
- if 语句
- if else 语句
- if else if else 语句
e.g. 编写一个程序,获取一个用户输入的整数,然后显示这个数是奇数还是偶数。
// 编写一个程序,获取一个用户输入的整数
// let num = +prompt("请输入一个整数")
let num = parseInt(prompt("请输入一个整数"))
// 验证一下,用户的输入是否合法,只有是有效数字时,我们才检查它是否是偶数
if (isNaN(num)) {
alert("你的输入有问题,请输入整数!")
} else {
// 我们不能使用 == 或 === 来检查一个值是否是NaN,要使用isNaN()函数来检查一个值是否是NaN
// num % 1 !== 0 说明是浮点数
if (isNaN(num) || num % 1 !== 0) {
alert(`${num} 是偶数!`)
} else {
alert(`${num} 是奇数!`)
}
}
1.2 switch-case#
语法格式如下:
switch (表达式){
case value1:
statements1 // 当表达式的结果等于 value1 时,则执行该代码
break;
case value2:
statements2 // 当表达式的结果等于 value2 时,则执行该代码
break;
...
case valueN:
statementsN // 当表达式的结果等于 valueN 时,则执行该代码
break;
default :
statements // 如果没有与表达式相同的值,则执行该代码
}
- switch 语句是逐行执行的,当 switch 语句找到一个与之匹配的 case 子句时(全等比较),不仅会执行该子句对应的代码,还会继续向后执行,直至 switch 语句结束。为了防止这种情况产生,需要在每个 case 子句的末尾使用 break 来跳出 switch 语句。break 除了可以用来跳出 switch 语句外,还可以用来跳出循环语句(for、for in、while、do while 等)。
- case 子句可以省略语句,这样当匹配时,不管下一个 case 条件是否满足,都会继续执行下一个 case 子句的语句。
- 在 switch 语句中,case 子句只是指明了执行起点,但是没有指明执行的终点,如果在 case 子句中没有 break 语句,就会发生连续执行的情况,从而忽略后面 case 子句的条件限制,这样就容易破坏 switch 结构的逻辑。
- 如果在函数中使用 switch 语句,可以使用 return 语句终止 switch 语句,防止代码继续执行。
- default 是 switch 子句,可以位于 switch 内任意位置,不会影响其它 case 子句的正常执行。下面结合示例介绍使用 default 语句应该注意 3 个问题。
【例一】
var id = 1;
switch (id) {
default :
console.log("游客");
break;
case 1 :
console.log("普通会员");
break;
case 2 :
console.log("VIP会员");
break;
case 3 :
console.log("管理员");
break;
}
// ----------
// 普通会员
// ----------
【例二】在下面代码中,JS 先检测 case 表达式的值,由于 case 表达式的值都不匹配,则跳转到 default 子句执行,然后继续执行 case 1 和 case 2 子句。但是,最后不会返回 default 子句再重复执行。
id = 3;
switch (id) {
default :
console.log("游客");
case 1 :
console.log("普通会员");
case 2 :
console.log("VIP会员");
}
// ----------
// 游客
// 普通会员
// VIP会员
// ----------
default 语句与 case 语句简单比较如下:
- 语义不同:default 为默认项,case 为判例。
- 功能扩展:default 选项是唯一的,不可以扩展。而 case 选项是可扩展的,没有限制。
- 异常处理:default 与 case 扮演的角色不同,case 用于枚举,default 用于异常处理。
1.3 while#
while (条件表达式) {
// 要执行的代码
}
do {
// 需要执行的代码
} while (条件表达式);
1.4 for#
(1)for 循环适合在已知循环次数时使用
for(initialization; condition; increment) {
// 要执行的代码
}
for 循环中括号中的三个表达式是可以省略的,但是用于分隔三个表达式的分号不能省略。
(2)for-in 循环是一种特殊类型的循环,也是普通 for 循环的变体,主要用来遍历对象,使用它可以将对象中的属性依次循环出来。
for (variable in object) {
// 要执行的代码
}
其中,variable 为一个变量,每次循环时这个变量都会被赋予不同的值,我们可以在 {}
中使用这个变量来进行一系列操作;object 为要遍历的对象,在每次循环中,会将 object 对象中的一个属性的键赋值给变量 variable,直到对象中的所有属性都遍历完。
(3)for-of 是 ECMAScript6 中新添加的一个循环方式,与 for-in 循环类似,也是普通 for 循环的一种变体。使用 for-of 循环可以轻松的遍历数组或者其它可遍历的对象,例如字符串、对象等。
for (variable of iterable) {
// 要执行的代码
}
其中,variable 为一个变量,每次循环时这个变量都会被赋予不同的值,我们可以在后面的 {}
中使用这个变量来进行一系列操作;iterable 为要遍历的内容,在每次循环中,会将 iterable 中的一个值赋值给变量 variable,直到 iterable 中的所有值都遍历完。
2. 跳出循环#
2.1 break#
使用 break 语句可以跳出 switch 语句。其实使用 break 语句还可以用来跳出循环,让程序继续执行循环之后的代码(如果有的话)。
2.2 continue#
continue 语句用来跳过本次循环,执行下次循环。当遇到 continue 语句时,程序会立即重新检测条件表达式,如果表达式结果为真则开始下次循环,如果表达式结果为假则退出循环。
break 语句用来跳出整个循环,执行循环后面的代码;continue 语句用来跳过当次循环,继续执行下次循环。
2.3 JS 标签#
从 JavaScript 1.2 开始,可以将标签与 break 和 continue 结合使用,来更精确的控制程序的执行。
JavaScript 中的标签与 HTML 中的标签不同,JavaScript 中的标签就是一个标识符(类似变量名),后面跟随一个冒号:
。JavaScript 标签可以声明在任何语句或者代码块之前,并与 break 或 continue 配合来跳出特定的循环,例如当多个循环嵌套使用时,单纯使用 break 只能跳出当前的循环,无法跳出外层循环,如果将 break 与标签配合使用,则可以一次跳出多层循环。
outerloop: // 定义一个标签
for (var i = 0; i < 5; i++) {
document.write("外层循环: " + i + "<br />");
innerloop: // 定义一个标签
for (var j = 0; j < 5; j++) {
if (j > 3 ) break ; // 跳出内层循环
if (i == 2) break innerloop; // 跳出内层讯息
if (i == 4) break outerloop; // 跳出外层循环
document.write("内层循环: " + j + " <br />");
}
}
break 或 continue 与标签之间不能出现换行。另外,标签名称和相关循环之间不能出现其它代码。
3. JS 函数#
函数也是一个对象,它具有其他对象所有的功能。
函数是一组执行特定任务(具有特定功能)的,可以重复使用的代码块,前面几节中用到的 alert()、write() 就是 JavaScript 中内置的函数。
除了使用内置函数外,我们也可以自行创建函数(自定义函数),然后在需要的地方调用这个函数,这样不仅可以避免编写重复的代码,还有利于代码的后期维护。本节我们主要来介绍一下如何使用 JavaScript 编写一个自己的函数。
3.1 定义函数#
JS 函数声明需要以 function 关键字开头,之后为要创建的函数名称,function 关键字与函数名称之间使用空格分开,函数名之后为一个括号 ()
,括号中用来定义函数中要使用的参数(多个参数之间使用逗号 ,
分隔开),一个函数最多可以有 255 个参数,最后为一个花括号 {}
,花括号中用来定义函数的函数体(即实现函数的代码),如下所示:
// 1.函数声明
function 函数名() {
// 语句...
}
// 2.函数表达式
const 变量 = function() {
// 语句...
}
// 3.箭头函数
() => {
// 语句...
}
示例代码如下:
function fn(){
console.log("函数声明所定义的函数")
}
const fn2 = function() {
console.log("函数表达式")
}
const fn3 = () => {
console.log("箭头函数")
}
上面示例中定义了一个函数 sayHello(),该函数需要接收一个参数 name,调用该函数会在页面中输出“Hello! ...”。
3.2 参数说明#
JS 中不会检查参数的类型,可以传递任何类型的值作为参数。
形式参数
- 在定义函数时,可以在函数中指定数量不等的形式参数(形参)
- 在函数中定义形参,就相当于在函数内部声明了对应的变量但是没有赋值
实际参数
- 在调用函数时,可以在函数的()传递数量不等的实参
- 实参会赋值给其对应的形参
- 参数:
1.如果实参和形参数量相同,则对应的实参赋值给对应的形参
2.如果实参多于形参,则多余的实参不会使用
3.如果形参多于实参,则多余的形参为undefined
在 JS 中,函数也是一个对象(一等函数),别的对象能做的事情,函数也可以。所以函数也可以作为参数传递。
【参数的默认值】在定义函数时,您可以为函数的参数设置一个默认值,这样当我们在调用这个函数时,如果没有提供参数,就会使用这个默认值作为参数值,如下例所示:
// 定义参数时,可以为参数指定默认值。
function sayHello(name = "World"){
document.write("Hello " + name);
}
sayHello(); // 输出:Hello World
sayHello('TREE'); // 输出:Hello TREE
// 当箭头函数中只有一个参数时,可以省略()
const fn2 = a => {
console.log("a =", a);
}
3.3 调用函数#
一旦定义好了一个函数,我们就可以在当前文档的任意位置来调用它。调用函数非常简单,只需要函数名后面加上一个括号即可,例如 alert()、write()。注意,如果在定义函数时函数名后面的括号中指定了参数,那么在调用函数时也需要在括号中提供对应的参数。
function sayHello(name){
document.write("Hello " + name);
}
// 调用 sayHello() 函数
sayHello('TREE6x7');
JavaScript 对于大小写敏感,所以在定义函数时 function 关键字一定要使用小写,而且调用函数时必须使用与声明时相同的大小写来调用函数。
3.4 函数返回值#
在函数中可以使用 return 语句将一个值(函数的运行结果)返回给调用函数的程序,这个值可以是任何类型,例如数组、对象、字符串等。对于有返回值的函数,我们可以会使用一个变量来接收这个函数的返回值,示例代码如下:
function getSum(num1, num2){
return num1 + num2;
}
var sum1 = getSum(7, 12); // 函数返回值为:19
var sum2 = getSum(-5, 33); // 函数返回值为:28
return 语句通常在函数的末尾定义,当函数运行到 return 语句时会立即停止运行,并返回到调用函数的地方继续执行。
另外,一个函数只能有一个返回值,若要返回多个值则,则可以将值放入一个数组中,然后返回这个数组即可,如下例所示:
function division(dividend, divisor){
var quotient = dividend / divisor;
var arr = [dividend, divisor, quotient]
return arr;
}
var res = division(100, 4)
document.write(res[0]); // 输出:100
document.write(res[1]); // 输出:4
document.write(res[2]); // 输出:25
任何值都可以作为返回值使用(包括对象和函数之类),如果 return 后不跟任何值,则相当于返回 undefined;如果不写 return,那么函数的返回值依然是 undefined。
箭头函数的返回值可以直接写在箭头后,如果直接在箭头后设置对象字面量为返回值时,对象字面量必须使用 ()
括起来。
const sum = (a, b) => a + b
let result = sum(123, 456)
const fn = () => ({name:"孙悟空"})
result = fn()
console.log(result)
3.5 函数表达式#
函数表达式与声明变量非常相似,是另外一种声明函数的形式,语法格式如下:
var myfunction = function name(parameter_list){
// 函数中的代码
};
参数说明如下:
- myfunction:变量名,可以通过它来调用等号之后的函数;
- name:函数名,可以省略(一般情况下我们也会将其省略),如果省略那么该函数就会成为一个匿名函数;
- parameter_list:为参数列表,一个函数最多可以有 255 个参数。
示例代码如下(在函数声明中,不需要在右花括号后放置分号,但若使用函数表达式就应该在表达式的最后以分号结尾):
// 函数声明
function getSum(num1, num2) {
var total = num1 + num2;
return total;
}
// 函数表达式
const getSum = function(num1, num2) {
var total = num1 + num2;
return total;
};
上面示例中的两个函数是等价的,它们的功能、返回值、调用方法都是相同的。
函数声明和函数表达式虽然看起来非常相似,但它们的运行方式是不同的,如下例所示:
declaration(); // 输出: function declaration
function declaration() {
document.write("function declaration");
}
expression(); // 报错:Uncaught TypeError: undefined is not a function
var expression = function() {
document.write("function expression");
};
如上例所示,如果函数表达式在定义之前被调用,会抛出异常(报错),但函数声明则可以成功运行。这是因为在程序执行前,JavaScript 会先对函数声明进行解析,因此无论是在函数声明前还是声明后调用函数都是可行的。而函数表达式则是将一个匿名函数赋值给一个变量,所以在程序还没有执行到该表达式之前,相当于函数还未定义,因此无法调用。
4. 事件处理#
JS 事件(event)是当用户与网页进行交互时发生的事情,例如单机某个链接或按钮、在文本框中输入文本、按下键盘上的某个按键、移动鼠标等等。当事件发生时,您可以使用 JavaScript 中的事件处理程序(也可称为事件监听器)来检测并执行某些特定的程序。
一般情况下事件的名称都是以单词 on
开头的,例如点击事件 onclick、页面加载事件 onload 等。下表中列举了一些 JavaScript 中常用的事件:
4.1 事件绑定#
事件只有与 HTML 元素绑定之后才能被触发,为 HTML 元素绑定事件处理程序的方法由很多,最简单的就是通过 HTML 事件属性来直接绑定事件处理程序,例如 onclick、onmouseover、onmouseout 等属性。
以 onclick 属性为例,通过该属性我们可以为指定的 HTML 元素定义鼠标点击事件(即在该元素上单击鼠标左键时触发的事件),示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<button type="button" onclick="myBtn()">按钮</button>
<script type="text/javascript">
function myBtn(){
alert("Hello World!");
}
</script>
</body>
</html>
除了上述方法外,我们也可以直接使用 JavaScript 中提供的内置函数来为指定元素绑定事件处理程序,如下例所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<button type="button" id="myBtn">按钮</button>
<script>
function sayHello() {
alert('Hello World!');
}
document.getElementById("myBtn").onclick = sayHello;
</script>
</body>
</html>
4.2 事件示例#
一般情况下,事件可以分为 4 大类 —— 鼠标事件、键盘事件、表单事件和窗口事件,另外还有一些其它事件。下面通过几个示例来简单介绍一些比较常用的事件。
(1)onmouseover 事件
onmouseover 事件就是指当用户鼠标指针移动到元素上时触发的事件,示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<button type="button" onmouseover="alert('您的鼠标已经移动到了该按钮上');">请将鼠标移动至此处</button><br>
<a href="#" onmouseover="myEvent()">请将鼠标移动至此处</a>
<script>
function myEvent() {
alert('您的鼠标已经移动到了该链接上');
}
</script>
</body>
</html>
(2)onmouseout 事件
onmouseout 事件与 onmouseover 事件正好相反,onmouseout 事件会在鼠标从元素上离开时触发,示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<div style="width: 350px; height: 200px; border:1px solid black" id="myBox"></div>
<script>
function myEvent() {
alert('您的鼠标已经离开指定元素');
}
document.getElementById("myBox").onmouseout = myEvent;
</script>
</body>
</html>
(3)onkeydown 事件
onkeydown 事件是指当用户按下键盘上的某个按键时触发的事件,示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<input type="text" onkeydown="myEvent()">
<script>
function myEvent() {
alert("您按下了键盘上的某个按钮");
}
</script>
</body>
</html>
(4)onkeyup 事件
onkeyup 事件是指当用户按下键盘上的某个按键并将其释放(即按下并松开某个按键)时触发的事件,示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<input type="text" onkeyup="myEvent()">
<script>
function myEvent() {
alert("您按下了键盘上的某个按钮,并将其释放了");
}
</script>
</body>
</html>
5. 作用域#
在 JavaScript 中,您可以在任意位置声明变量,但不同的位置会影响变量的可用范围,这个范围称为作用域。作用域可以大致分为两种类型,分别是全局作用域和局部作用域。下面就来分别介绍一下。
5.1 全局作用域#
全局作用域是指变量可以在当前脚本的任意位置访问,拥有全局作用域的变量也被称为“全局变量”,一般情况下拥有以下特征的变量具有全局作用域:
- 最外层的函数和在最外层函数外面定义的变量拥有全局作用域;
- 所有未定义直接赋值的变量拥有全局作用域;
- 全局作用域中的变量是全局变量,可以在任意位置访问;
- 所有 window 对象的属性拥有全局作用域,例如 window.name、window.location、window.top 等。
示例代码如下:
var str = "Hello World!";
function myFun(){
document.write(str); // 输出:Hello World!
}
myFun();
document.write(str); // 输出:Hello World!
实际情况下,所有具有全局作用域的变量都会被绑定到 window 对象中,成为 window 对象的一个属性,如下例所示:
var str = "JavaScript";
document.write(str); // 输出:JavaScript
document.write(window.str); // 输出:JavaScript
document.write(str === window.str); // 输出:true
5.2 局部作用域#
-
块作用域
-
块作用域是一种局部作用域;
-
块作用域在代码块执行时创建,代码块执行完毕它就销毁;
-
在块作用域中声明的变量是局部变量,只能在块内部访问,外部无法访问。
-
-
函数作用域
- 函数作用域也是一种局部作用域;
- 函数作用域在函数调用时产生,调用结束后销毁;
- 函数每次调用都会产生一个全新的函数作用域;
- 在函数中定义的变量是局部变量,只能在函数内部访问,外部无法访问。
示例代码 1:
let a = "变量a"
{
let b = "变量b"
{
{
console.log(b)
}
}
}
{
console.log(b)
}
示例代码 2:
function myFun(){
var str = "Hello World!";
document.write(str); // 输出:Hello World!
}
document.write(str); // 报错:str is not defined
在函数内定义的局部变量只有在函数被调用时才会生成,当函数执行完毕后会被立即销毁。
5.3 作用域链#
当我们使用一个变量时,JS 解释器会优先在当前作用域中寻找变量,如果找到了则直接使用。如果没找到,则去上一层作用域中寻找,找到了则使用,还没找到则继续去上一层寻找,以此类推。如果一直到全局作用域都没找到,则报错 xxx is not defined。
6. 补充说明#
6.1 变量/函数·提升#
-
【变量的提升】使用 var 声明的变量,它会在所有代码执行前被声明,所以我们可以在变量声明前就访问变量。let 声明的变量实际也会提升,但是在赋值之前解释器禁止对该变量的访问。
-
【函数的提升】使用函数声明创建的函数,会在其他代码执行前被创建,所以我们可以在函数声明前调用函数。
6.2 立即执行函数#
希望可以创建一个只执行一次的匿名函数 => 立即执行函数(IIFE)
立即是一个匿名的函数,并它只会调用一次。可以利用 IIFE 来创建一个一次性的函数作用域,避免变量冲突的问题。
(function(){
let a = 10
console.log(111)
}());
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?