【技术积累】HTML+CSS+JavaScript中的基础知识【四】
JavaScript的条件结构
JavaScript中的条件结构主要包括if语句、if-else语句、if-else if语句和switch语句。这些条件结构用于根据不同的条件执行不同的代码块。
if语句
if语句用于在满足条件时执行一段代码块。语法如下:
if (condition) {
// code to be executed if condition is true
}
示例代码:
let num = 10;
if (num > 0) {
console.log("Number is positive");
}
解释:如果变量num的值大于0,则打印"Number is positive"。
if-else语句
if-else语句用于在满足条件时执行一个代码块,否则执行另一个代码块。语法如下:
if (condition) {
// code to be executed if condition is true
} else {
// code to be executed if condition is false
}
示例代码:
let num = -5;
if (num > 0) {
console.log("Number is positive");
} else {
console.log("Number is negative");
}
解释:如果变量num的值大于0,则打印"Number is positive",否则打印"Number is negative"。
if-else if语句
if-else if语句用于在满足多个条件时执行不同的代码块。语法如下:
if (condition1) {
// code to be executed if condition1 is true
} else if (condition2) {
// code to be executed if condition2 is true
} else {
// code to be executed if none of the conditions are true
}
示例代码:
let num = 0;
if (num > 0) {
console.log("Number is positive");
} else if (num < 0) {
console.log("Number is negative");
} else {
console.log("Number is zero");
}
解释:如果变量num的值大于0,则打印"Number is positive";如果变量num的值小于0,则打印"Number is negative";否则打印"Number is zero"。
switch语句
switch语句用于根据不同的条件执行不同的代码块。语法如下:
switch (expression) {
case value1:
// code to be executed if expression matches value1
break;
case value2:
// code to be executed if expression matches value2
break;
default:
// code to be executed if expression doesn't match any value
}
示例代码:
let day = 3;
switch (day) {
case 1:
console.log("Monday");
break;
case 2:
console.log("Tuesday");
break;
case 3:
console.log("Wednesday");
break;
default:
console.log("Other day");
}
解释:根据变量day的值,打印相应的星期几。
以上是JavaScript中常用的条件结构,根据不同的需求选择合适的条件结构来编写代码。
JavaScript的循环结构
在JavaScript中,循环结构用于重复执行一段代码,直到满足特定条件为止。JavaScript提供了多种循环结构,包括for循环、while循环和do-while循环。
for循环
for循环用于重复执行一段代码,可以指定循环的起始条件、终止条件和每次迭代的步长。
案例:计算1到10的和。
let sum = 0;
for (let i = 1; i <= 10; i++) {
sum += i;
}
console.log(sum); // 输出55
解释:在这个例子中,我们使用for循环从1到10迭代,每次迭代将当前的i值加到sum变量中。最后,我们输出sum的值,得到1到10的和。
while循环
while循环用于在满足特定条件时重复执行一段代码。
案例:计算1到10的和。
let sum = 0;
let i = 1;
while (i <= 10) {
sum += i;
i++;
}
console.log(sum); // 输出55
解释:在这个例子中,我们使用while循环来重复执行代码块,直到i的值大于10。在每次迭代中,我们将当前的i值加到sum变量中,并递增i的值。
do-while循环
do-while循环与while循环类似,但它会先执行一次代码块,然后再检查条件是否满足。
案例:计算1到10的和。
let sum = 0;
let i = 1;
do {
sum += i;
i++;
} while (i <= 10);
console.log(sum); // 输出55
解释:在这个例子中,我们使用do-while循环来重复执行代码块,直到i的值大于10。在每次迭代中,我们将当前的i值加到sum变量中,并递增i的值。由于do-while循环先执行一次代码块,所以即使条件不满足,代码块也会执行一次。
以上是JavaScript中常用的循环结构及其案例。这些循环结构可以根据具体的需求选择使用,用于重复执行一段代码,提高代码的复用性和效率。
JavaScript的循环控制
在JavaScript中,循环控制用于在循环执行过程中改变循环的行为,包括跳出循环、跳过当前迭代和终止整个脚本的执行。
break语句
break语句用于跳出循环,即使循环条件仍然满足。
案例:找到数组中的第一个负数。
const numbers = [1, 2, -3, 4, 5];
let firstNegative = null;
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] < 0) {
firstNegative = numbers[i];
break;
}
}
console.log(firstNegative); // 输出-3
解释:在这个例子中,我们使用for循环遍历数组numbers。当找到第一个负数时,我们使用break语句跳出循环,并将该负数赋值给firstNegative变量。
continue语句
continue语句用于跳过当前迭代,继续执行下一次迭代。
案例:计算数组中正数的和。
const numbers = [1, -2, 3, -4, 5];
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] < 0) {
continue;
}
sum += numbers[i];
}
console.log(sum); // 输出9
解释:在这个例子中,我们使用for循环遍历数组numbers。当遇到负数时,我们使用continue语句跳过当前迭代,继续执行下一次迭代。只有当数字为正数时,我们将其加到sum变量中。
return语句
return语句用于终止整个脚本的执行,不仅仅是循环。
案例:找到数组中的第一个负数,并返回其索引。
function findFirstNegative(numbers) {
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] < 0) {
return i;
}
}
return -1;
}
const numbers = [1, 2, -3, 4, 5];
const index = findFirstNegative(numbers);
console.log(index); // 输出2
解释:在这个例子中,我们定义了一个函数findFirstNegative,该函数使用for循环遍历数组numbers。当找到第一个负数时,我们使用return语句终止函数的执行,并返回负数的索引。如果没有找到负数,则返回-1。
以上是JavaScript中常用的循环控制语句及其案例。这些循环控制语句可以根据具体的需求选择使用,用于改变循环的行为,提供更灵活的控制和处理方式。
JavaScript执行上下文作用域
执行上下文是JavaScript中的一个概念,它定义了变量和函数的可访问性以及代码的执行顺序。每当JavaScript代码执行时,都会创建一个执行上下文,并将其添加到执行上下文栈中。
执行上下文作用域是指在当前执行上下文中可访问的变量、函数和对象。JavaScript中有三种类型的执行上下文作用域:全局作用域、函数作用域和块级作用域。
全局作用域
全局作用域是在代码中没有嵌套在任何函数或块级作用域中的部分。在全局作用域中声明的变量和函数可以在代码的任何地方访问。
案例:在全局作用域中声明和访问变量。
let message = "Hello, world!";
function showMessage() {
console.log(message);
}
showMessage(); // 输出Hello, world!
解释:在这个例子中,变量message在全局作用域中声明,并且可以在函数showMessage中访问和使用。
函数作用域
函数作用域是在函数内部声明的变量和函数所在的作用域。在函数作用域中声明的变量和函数只能在函数内部访问。
案例:在函数作用域中声明和访问变量。
function showMessage() {
let message = "Hello, world!";
console.log(message);
}
showMessage(); // 输出Hello, world!
console.log(message); // 报错,message未定义
解释:在这个例子中,变量message在函数作用域中声明,并且只能在函数内部访问和使用。在函数外部尝试访问message变量会导致错误。
块级作用域
块级作用域是在代码块(例如if语句、for循环等)内部声明的变量和函数所在的作用域。在块级作用域中声明的变量和函数只能在该代码块内部访问。
案例:在块级作用域中声明和访问变量。
if (true) {
let message = "Hello, world!";
console.log(message);
}
console.log(message); // 报错,message未定义
解释:在这个例子中,变量message在块级作用域中声明,并且只能在if语句的代码块内部访问和使用。在代码块外部尝试访问message变量会导致错误。
执行上下文作用域决定了变量和函数的可访问性。了解不同类型的执行上下文作用域可以帮助我们编写更具可读性和可维护性的代码,并避免变量冲突和作用域污染的问题。
async和defer
async和defer是用于控制脚本加载和执行的属性,它们通常用于在HTML文档中引入外部JavaScript文件。
async属性
async属性用于异步加载脚本文件。当浏览器遇到带有async属性的脚本标签时,它会立即开始下载脚本文件,并在下载完成后立即执行脚本,而不会等待其他资源的加载和解析。
案例:使用async属性异步加载脚本文件。
<!DOCTYPE html>
<html>
<head>
<title>Async Example</title>
</head>
<body>
<script async src="script.js"></script>
<h1>Hello, world!</h1>
</body>
</html>
解释:在这个例子中,我们使用async属性在HTML文档中异步加载脚本文件script.js。浏览器会立即开始下载脚本文件,而不会阻塞HTML文档的解析和其他资源的加载。因此,页面上的"h1"标签会在脚本加载和执行过程中显示出来。
defer属性
defer属性用于延迟加载脚本文件。当浏览器遇到带有defer属性的脚本标签时,它会继续解析HTML文档,并在文档解析完成后再按照顺序执行延迟加载的脚本文件。
案例:使用defer属性延迟加载脚本文件。
<!DOCTYPE html>
<html>
<head>
<title>Defer Example</title>
</head>
<body>
<script defer src="script.js"></script>
<h1>Hello, world!</h1>
</body>
</html>
解释:在这个例子中,我们使用defer属性在HTML文档中延迟加载脚本文件script.js。浏览器会继续解析HTML文档,并在文档解析完成后按照顺序执行延迟加载的脚本文件。因此,页面上的"h1"标签会在脚本加载和执行完成后显示出来。
async和defer属性都可以用于优化脚本加载和执行的顺序,提高页面的性能和用户体验。它们的选择取决于脚本的依赖关系和执行时机的要求。
JavaScript闭包
JavaScript闭包指的是函数创建时的作用域仍然存在于函数调用之后的能力,即函数可以访问它所创建的作用域内的变量和函数,即使这个作用域已经被销毁了。
闭包是由函数和函数内部状态(即函数运行时能访问的变量)构成的组合体。在JavaScript中,只要有内部函数,就有闭包的产生。
闭包的具体作用包括:
- 保护变量不受全局污染。使用闭包可以将变量封装在函数内部,避免其污染全局变量。
- 记录函数执行时的状态。通过闭包,可以记录函数执行时的状态,这在事件函数和回调函数中会有很大的作用。
- 延长局部变量的生命周期。如果局部变量在函数执行结束后就被销毁,但是如果其被闭包所引用,那么这个变量将一直存在于内存中,不会被销毁。
使用闭包时需要注意以下几点:
- 闭包会占用内存,过多的闭包可能会导致内存泄漏,应该尽量避免使用过多的闭包。
- 闭包中的变量在被引用时必须已经存在,否则会出现undefined的情况。因此需要注意函数调用的顺序。
- 闭包的作用域链不应该太长,否则会影响代码的性能。
function createCounter() {
let count = 0;
function increment() {
count++;
console.log(count);
}
return increment;
}
const counter = createCounter();
counter(); // 输出1
counter(); // 输出2
counter(); // 输出3
解释:在这个例子中,我们定义了一个外部函数createCounter,该函数内部定义了一个变量count和一个内部函数increment。内部函数increment可以访问并修改外部函数作用域中的变量count。我们通过调用外部函数createCounter,将内部函数increment作为返回值返回,并将其赋值给变量counter。每次调用counter函数时,它都会访问并更新外部函数作用域中的count变量,并将其打印出来。
因此,通过使用闭包,可以实现记忆计数器的功能,不需要使用全局变量或者类似的论坛限制方式。