跳到主要内容

循环

循环结构

循环结构用于重复执行代码块,直到满足特定条件。常见的循环结构包括 forwhiledo...while

for 循环

for (let i = 0; i < 10; i++) {
console.log(i);
}

循环执行步骤

// 1. 声明变量 i = 0;
// 2. 判断条件 i < 10,如果为真,则执行代码块
// console.log(i);
// 3. 执行迭代表达式 i++
// 4. 重复步骤 2 和 3,直到条件不满足,停止循环

for 循环与 while 循环的转换

for 循环和 while 循环在功能上是等价的,可以相互转换。

// 使用 for 循环
for (let i = 0; i < 10; i++) {
console.log(i);
}

// 转换为 while 循环
let i = 0;
while (i < 10) {
console.log(i);
i++;
}

死循环

死循环是指循环条件永远为真,导致循环无法终止。

// 使用 for 循环创建死循环
for (let i = 1; ; ) {
console.log(i);
i++;
}

// 使用 while 循环创建死循环
let j = 1;
while (j) {
console.log(j);
j++;
}

使用条件判断跳出循环

在循环中使用条件判断,可以在满足特定条件时终止循环。

let i = 1;
while (i) {
console.log(i);
i++;
if (i === 11) {
i = 0; // 设置 i 为 0,结束循环
}
}

break 终止循环

break 语句用于立即终止当前循环。

let i = 1;
let sum = 0;

for (; i; ) {
sum += i;
i++;
if (sum >= 100) {
break; // 当 sum 大于或等于 100 时,跳出循环
}
console.log(`i: ${i}, sum: ${sum}`);
}

continue 跳过当前循环

continue 语句用于跳过当前循环的剩余部分,继续下一个循环。

for (let i = 0; i <= 100; i++) {
if (i % 7 === 0 || i % 7 === 7) {
continue; // 跳过能被7整除的数字
}
console.log(i);
}

打印 0~100 的数字

使用 for 循环打印 0100 的数字,且不使用比较操作和 i++i--

for (let i = 100; i--; ) {
console.log(i);
}

whiledo...while 循环

do...while 循环至少会执行一次循环体,然后再判断条件是否满足。

let i = 0;
while (i < 10) {
console.log(i);
i++;
}

do {
console.log('开始循环');
} while (i < 10);

循环练习

计算 10 的 N 次方

const exponent = 5;
let result = 1;
for (let i = 0; i < exponent; i++) {
result *= 10;
}
console.log(result); // 输出: 100000

计算 N 的阶乘

const n = 5;
let factorial = 1;
for (let i = 1; i <= n; i++) {
factorial *= i;
console.log(`i: ${i}, factorial: ${factorial}`);
}
// 输出:
// i: 1, factorial: 1
// i: 2, factorial: 2
// i: 3, factorial: 6
// i: 4, factorial: 24
// i: 5, factorial: 120

取数字的各位

const number = 857;
const units = number % 10;
console.log(units); // 输出: 7

const tens = Math.floor((number % 100) / 10);
console.log(tens); // 输出: 5

const hundreds = Math.floor(number / 100);
console.log(hundreds); // 输出: 8

结果

取数字各位结果

判断素数

素数是指大于 1 的自然数,除了 1 和它本身外,不能被其他自然数整除的数。

for (let i = 2; i < 100; i++) {
let isPrime = true;
for (let j = 2; j <= Math.sqrt(i); j++) {
if (i % j === 0) {
isPrime = false;
break; // 如果找到因子,退出内层循环
}
}
if (isPrime) {
console.log(i);
}
}

引用类型

引用类型包括 ArrayObjectFunctionRegExp 等。

数组

数组用于存储有序的数据集合。

const numbers = [1, 2, 3, 4, 5, 6];
numbers[3] = null;
console.log(numbers); // 输出: [1, 2, 3, null, 5, 6]
console.log(numbers.length); // 输出: 6

for (let i = 0; i < numbers.length; i++) {
numbers[i] += 2;
}
console.log(numbers); // 输出: [3, 4, 5, 2, 7, 8]

对象

对象用于存储键值对的数据。

const person = {
name: '蟹老板',
age: 18,
height: 180,
weight: 140,
job: 'Web 开发',
};

// 修改属性
person.name = '海绵宝宝';

// 访问属性
console.log(person.name); // 输出: 海绵宝宝

数据类型转换

JavaScript 中的数据类型转换分为显式转换和隐式转换。

显式类型转换

显式类型转换通过函数或方法将一种数据类型转换为另一种数据类型。

使用 Number 转换

console.log('1.' + typeof null); // 输出: object
// 这是因为 typeof null 的结果是 'object',这是历史遗留的bug。

console.log('2.' + typeof undefined); // 输出: undefined
console.log('3.' + typeof function () {}); // 输出: function
console.log('4.' + typeof NaN); // 输出: number
console.log('5.' + typeof ''); // 输出: string
console.log('6.' + typeof Array); // 输出: function
console.log('7.' + typeof Object); // 输出: function
console.log('8.' + typeof (1 - 1)); // 输出: number
console.log('9.' + typeof (1 - '1')); // 输出: number
console.log('10.' + typeof ('1' - '1')); // 输出: number

let a;
console.log('11.' + typeof a); // 输出: undefined

console.log('12.' + typeof typeof a); // 输出: string
console.log('13.' + typeof typeof 123); // 输出: string

结果

类型转换结果

使用 parseInt 转换

const a = '123';
console.log(`${parseInt(a)} - ${typeof parseInt(a)}`); // 输出: 123 - number

const b = 'true';
console.log(`${parseInt(b)} - ${typeof parseInt(b)}`); // 输出: NaN - number

const c = 'null';
console.log(`${parseInt(c)} - ${typeof parseInt(c)}`); // 输出: NaN - number

const d = 'undefined';
console.log(`${parseInt(d)} - ${typeof parseInt(d)}`); // 输出: NaN - number

const e = 'a';
console.log(`${parseInt(e)} - ${typeof parseInt(e)}`); // 输出: NaN - number

const f = 'a1';
console.log(`${parseInt(f)} - ${typeof parseInt(f)}`); // 输出: NaN - number

const g = '3.14';
console.log(`${parseInt(g)} - ${typeof parseInt(g)}`); // 输出: 3 - number

结果

parseInt 转换结果

进制转换

const a = '16';
console.log(parseInt(a, 16)); // 输出: 22

const b = '12';
console.log(parseInt(b, 8)); // 输出: 10

const c = '11';
console.log(parseInt(c, 2)); // 输出: 3

const d = 'abc123';
console.log(parseInt(d)); // 输出: NaN

const e = '123abc';
console.log(parseInt(e)); // 输出: 123

const f = '12abc3';
console.log(parseInt(f)); // 输出: 12

结果

进制转换结果

浮点数

使用 parseFloat 转换字符串为浮点数,并使用 toFixed 方法控制小数位数。

const num = parseFloat('3.1465');
console.log(num.toFixed(2)); // 输出: 3.15

结果

浮点数转换结果

转换为字符串

console.log(typeof String(123)); // 输出: string

let str = null;
try {
console.log(str.toString());
} catch (error) {
console.log(error.message); // 输出: Cannot read property 'toString' of null
}

let str1 = undefined;
try {
console.log(str1.toString());
} catch (error) {
console.log(error.message); // 输出: Cannot read property 'toString' of undefined
}

布尔类型

console.log(Boolean(1)); // 输出: true
console.log(Boolean(null)); // 输出: false
console.log(Boolean(undefined)); // 输出: false
console.log(Boolean(0)); // 输出: false
console.log(Boolean('')); // 输出: false
console.log(Boolean(NaN)); // 输出: false

结果

布尔类型转换结果

隐式类型转换

JavaScript 在某些情况下会自动进行类型转换。

隐式 Number 转换

let a = '123';
a++;
console.log(a); // 输出: 124

let b = '3' * 2;
console.log(b); // 输出: 6

结果

隐式 Number 转��换结果 隐式 Number 转换结果

正负号转换

const num1 = '123';
console.log(`${typeof +num1}: ${+num1}`); // 输出: number: 123
console.log(`${typeof -num1}: ${-num1}`); // 输出: number: -123

const num2 = 'abc';
console.log(`${typeof +num2}: ${+num2}`); // 输出: number: NaN
console.log(`${typeof -num2}: ${-num2}`); // 输出: number: NaN

结果

正负号转换结果

关系运算符的隐式转换

let a = '1' > 2;
console.log(a); // 输出: false

let b = 1 > '2';
console.log(b); // 输出: false

let c = 1 == '1';
console.log(c); // 输出: true

结果

关系运算符转换结果

隐式字符串转换

let a = 'a' + 1;
console.log(a); // 输出: a1

结果

字符串转换结果

比较 ASCII 码

let a = 'a' > 'b';
console.log(a); // 输出: false

结果

ASCII 比较结果

其他转换

// 全等比较不进行隐式转换
let a1 = 1 === '1';
console.log(`1. ${a1}`); // 输出: 1. false

// NaN 不等于任何值,包括自身
let a2 = NaN == NaN;
console.log(`2. ${a2}`); // 输出: 2. false

// 复杂的比较运算
let a3 = 2 > 1 > 3;
console.log(`3. ${a3}`); // 输出: 3. false

let a4 = 2 > 1 == 1;
console.log(`4. ${a4}`); // 输出: 4. false

// undefined 和 null 的比较
let a6 = undefined == 0;
console.log(`6. ${a6}`); // 输出: 6. false

let a7 = null == 0;
console.log(`7. ${a7}`); // 输出: 7. false

let a8 = undefined == null;
console.log(`8. ${a8}`); // 输出: 8. true

结果

其他转换结果

isNaN 判断是否为非数

isNaN 函数用于判断一个值是否为 NaN

console.log(`1. ${isNaN(NaN)}`); // 输出: 1. true
console.log(`2. ${isNaN(123)}`); // 输出: 2. false
console.log(`3. ${isNaN('123')}`); // 输出: 3. false
console.log(`4. ${isNaN('a')}`); // 输出: 4. true
console.log(`5. ${isNaN(null)}`); // 输出: 5. false
console.log(`6. ${isNaN(undefined)}`); // 输出: 6. true

结果

isNaN 结果

斐波那契数列

斐波那契数列是由 1 1 2 3 5 8 开始,每一位都是前两位的和。以下示例使用 for 循环打印斐波那契数列的第 N 位数字。

const n = parseInt(window.prompt('请输入第几位'));
let n1 = 1;
let n2 = 1;
let n3;

if (n <= 0) {
console.log('输入错误');
} else if (n === 1 || n === 2) {
console.log(1);
} else {
for (let i = 2; i < n; i++) {
n3 = n1 + n2;
n1 = n2;
n2 = n3;
// 向右移动
}
console.log(n3);
}

JavaScript 函数

函数声明与调用

函数是执行特定任务的代码块,可以重复使用。

function greet(name) {
return `Hello, ${name}!`;
}

const message = greet('海绵宝宝');
console.log(message); // 输出: Hello, 海绵宝宝!

函数表达式

函数可以作为表达式赋值给变量。

const add = function (a, b) {
return a + b;
};

console.log(add(2, 3)); // 输出: 5

箭头函数

箭头函数是更简洁的函数写法,尤其适用于匿名函数。

const multiply = (a, b) => a * b;

console.log(multiply(4, 5)); // 输出: 20

回调函数

回调函数是作为参数传递给另一个函数的函数,用于异步操作或事件处理。

function fetchData(callback) {
setTimeout(() => {
const data = { id: 1, name: '海绵宝宝' };
callback(data);
}, 1000);
}

fetchData(function (data) {
console.log('接收到数据:', data);
});
// 输出(延迟1秒后): 接收到数据: { id: 1, name: '海绵宝宝' }

匿名函数

匿名函数是没有名称的函数,常用于回调或立即执行函数表达式(IIFE)。

// 作为回调使用
setTimeout(function () {
console.log('这是一个匿名函数');
}, 2000);

// 立即执行函数表达式
(function () {
console.log('立即执行的匿名函数');
})();

递归函数

递归函数是调用自身的函数,用于解决分解为更小的同类问题的问题。

function factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}

console.log(factorial(5)); // 输出: 120

正则表达式

正则表达式用于匹配字符串中的模式。

创建正则表达式

可以使用字面量或构造函数创建正则表达式。

// 使用字面量
const regex1 = /hello/i;

// 使用构造函数
const regex2 = new RegExp('hello', 'i');

常用方法

test 方法

test 方法用于测试字符串是否匹配正则表达式,返回布尔值。

const regex = /world/i;
console.log(regex.test('Hello World')); // 输出: true
console.log(regex.test('Hello')); // 输出: false

exec 方法

exec 方法用于执行匹配,返回匹配结果数组或 null

const regex = /(\w+) (\w+)/;
const result = regex.exec('Hello World');

console.log(result);
// 输出: ["Hello World", "Hello", "World", index: 0, input: "Hello World", groups: undefined]

字符集与量词

const regex = /^[A-Za-z0-9]{5,10}$/;
console.log(regex.test('abc123')); // 输出: true
console.log(regex.test('ab')); // 输出: false

常用模式

  • ^:匹配字符串开头。
  • $:匹配字符串结尾。
  • .:匹配除换行符外的任何单个字符。
  • *:匹配前一个字符零次或多次。
  • +:匹配前一个字符一次或多次。
  • ?:匹配前一个字符零次或一次。
  • \d:匹配数字。
  • \w:匹配字母、数字或下划线。
  • \s:匹配空白字符。