Python Day31 JavaScript 基础核心知识点详解 及 例题分析
一、数据类型与类型转换
JavaScript 中的数据类型分为原始类型(值类型)和对象类型(引用类型),两者在存储方式、类型判断和比较规则上有本质区别。
1. 数字类型(Number)
类型特性:
- 原始类型:直接存储数值,
typeof
结果为number
- 对象类型:通过
new Number()
创建,typeof
结果为object
- 自动类型转换:
Number()
函数可将其他类型转为数字(无法转换时返回NaN
)
- 原始类型:直接存储数值,
代码示例:
// 原始类型数字 let a = 10; let b = Number('10'); // 转换字符串为数字(原始类型)// 数字对象(引用类型) let c = new Number('10');// 类型判断 console.log(typeof a); // "number"(原始类型) console.log(typeof c); // "object"(对象类型)// 比较规则 console.log(a == c); // true(仅比较值,对象会自动转为原始值) console.log(a === c); // false(严格比较,类型和值必须同时相同)
常用方法:
toFixed(n)
:保留 n 位小数(返回字符串类型)toString(radix)
:按指定基数(2-36)转换为字符串parseInt(str, radix)
:解析字符串为指定基数的整数
// 保留小数 let pi = 3.14159; console.log(pi.toFixed(2)); // "3.14"(注意返回字符串)// 进制转换 let num = 20; console.log(num.toString(2)); // "10100"(二进制) console.log(num.toString(16)); // "14"(十六进制)// 解析十六进制字符串 console.log(parseInt('0xFF', 16)); // 255
2. 字符串类型(String)
类型特性:
- 原始类型:用单引号 / 双引号声明,
typeof
为string
- 对象类型:
new String()
创建,typeof
为object
- 不可变性:原始字符串一旦创建无法修改,操作会返回新字符串
- 原始类型:用单引号 / 双引号声明,
代码示例:
// 原始字符串 let str1 = 'hello'; let str2 = String(123); // 转换数字为字符串// 字符串对象 let str3 = new String('world');// 类型与比较 console.log(typeof str1); // "string" console.log(typeof str3); // "object" console.log(str1 == str3); // true(值相等) console.log(str1 === str3); // false(类型不同)
3. 布尔类型(Boolean)
类型特性:
- 原始类型:
true
/false
,typeof
为boolean
- 对象类型:
new Boolean()
创建,typeof
为object
- 转换规则:
0
、""
、null
、undefined
、NaN
转为false
,其余通常为true
- 原始类型:
代码示例:
// 原始布尔值 let bool1 = true; let bool2 = Boolean(0); // 转换为 false// 布尔对象 let bool3 = new Boolean(false);// 类型与比较 console.log(bool2); // false(原始类型) console.log(bool3); // [Boolean: false](对象类型) console.log(bool2 == bool3); // true(值相等) console.log(bool2 === bool3); // false(类型不同)
二、运算符详解
1. 算术运算符
包含 +
、-
、*
、/
、%
(取余)、**
(幂运算),需注意特殊计算规则:
// 除数为0的特殊情况
console.log(5 / 0); // Infinity(正无穷)
console.log(5 % 0); // NaN(非数)// 取余运算规则(余数符号与除数一致)
console.log(7 % 3); // 1(7 = 3*2 + 1)
console.log(7 % -3); // -2(7 = -3*(-3) + (-2))// 幂运算
console.log(2 **3); // 8(2的3次方)
2. 自增 / 自减运算符(++/--)
a++
:先使用变量当前值,再自增++a
:先自增变量值,再使用新值
let x = 5;
let result = (x++) + (--x) + (x++);
// 执行步骤:
// 1. x++ → 使用5,x变为6
// 2. --x → x先变为5,使用5
// 3. x++ → 使用5,x变为6
console.log(result); // 5 + 5 + 5 = 15
console.log(x); // 6
3. 比较运算符
==
:宽松比较,会自动类型转换后比较值===
:严格比较,同时检查类型和值- 特殊判断:
NaN
不等于任何值(包括自身),需用Number.isNaN()
判断
// 宽松比较(自动转换类型)
console.log(10 == '10'); // true
console.log(0 == false); // true// 严格比较(不转换类型)
console.log(10 === '10'); // false
console.log(0 === false); // false// NaN 判断
console.log(NaN === NaN); // false(特殊规则)
console.log(Number.isNaN(NaN)); // true(正确判断方式)// +0 与 -0 的区别
console.log(+0 === -0); // true
console.log(Object.is(+0, -0)); // false(更严格的比较)
4. 逻辑运算符
&&
(与):遇假则停,返回第一个假值或最后一个真值||
(或):遇真则停,返回第一个真值或最后一个假值!
(非):转换为布尔值后取反
// 逻辑与(&&)
console.log(3 && 0 && 5); // 0(遇到第一个假值0就返回)// 逻辑或(||)
console.log('' || 'hello' || 'world'); // "hello"(遇到第一个真值返回)// 逻辑非(!)
console.log(!0); // true(0转为false,取反为true)
console.log(!!''); // false(双重否定等价于Boolean()转换)
三、流程控制语句
1. 条件判断(if/else if/else)
根据条件执行不同代码块,条件表达式会被转换为布尔值判断。
let score = 75;
if (score >= 90) {console.log('优秀');
} else if (score >= 60) {console.log('及格'); // 满足此条件,输出"及格"
} else {console.log('不及格');
}
2. 分支选择(switch/case)
适合多值匹配场景,注意使用 break
防止穿透(不写 break
会继续执行下一个 case
)。
let month = 2;
switch (month) {case 1:case 3:case 5:case 7:case 8:case 10:case 12:console.log('31天');break;case 4:case 6:case 9:case 11:console.log('30天');break;default: // 所有case不匹配时执行console.log('28天或29天'); // 2月匹配此处
}
3. 循环语句
- for 循环:适合已知循环次数的场景
- while 循环:适合未知循环次数,先判断后执行
- do-while 循环:至少执行一次,先执行后判断
// for循环:打印1-5
for (let i = 1; i <= 5; i++) {console.log(i); // 1,2,3,4,5
}// while循环:计算1-100的和
let sum = 0;
let num = 1;
while (num <= 100) {sum += num;num++;
}
console.log(sum); // 5050// do-while循环:至少执行一次
let count = 3;
do {console.log('执行次数:', count);count--;
} while (count > 3); // 条件不成立,但仍执行1次
四、函数深入理解
1. 函数定义方式
- 声明式:
function 函数名() {}
- 表达式:
let 变量 = function() {}
(匿名函数) - 箭头函数:
(参数) => {}
(简洁语法,特殊 this 绑定)
// 声明式函数
function add(a, b) {return a + b;
}// 函数表达式(匿名函数)
let multiply = function(a, b) {return a * b;
};// 箭头函数
let square = x => x **2; // 单参数可省括号,单行返回可省大括号console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
console.log(square(3)); // 9
2. 函数参数特性
- 默认参数:为参数指定默认值,调用时可省略
- 不定项参数:
...args
接收所有剩余参数(返回数组) arguments
:函数内置对象,存储所有传入参数(类数组)
// 默认参数与不定项参数
function fn(a, b = 10, ...rest) {console.log(rest); // 接收剩余参数的数组return a + b;
}
console.log(fn(5)); // 15(b使用默认值10)
console.log(fn(5, 2, 8)); // 7(rest为[8])// arguments对象
function sumAll() {let total = 0;for (let i = 0; i < arguments.length; i++) {total += arguments[i];}return total;
}
console.log(sumAll(1, 2, 3, 4)); // 10
3. 闭包(Closure)
定义:嵌套函数中,内部函数引用外部函数的变量,且内部函数被返回 / 暴露,形成闭包。
作用:延长外部变量的生命周期,实现私有变量。
function createCounter() {let count = 0; // 外部函数变量,被内部函数引用// 内部函数形成闭包return function() {return ++count;};
}let counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2(count变量未被销毁,持续累加)
4. 生成器函数(Generator)
定义:用 function*
声明,通过 yield
关键字暂停执行,next()
方法恢复执行。
用途:生成迭代序列(如无限序列、延迟计算)。
// 斐波那契数列生成器
function* fibonacci() {let [a, b] = [0, 1];while (true) {yield b; // 暂停并返回当前值[a, b] = [b, a + b]; // 更新下一组值}
}let fib = fibonacci();
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2
console.log(fib.next().value); // 3
总结
本部分涵盖了 JavaScript 基础核心知识点,包括:
- 数据类型的区分(原始类型 vs 对象类型)及转换规则
- 各类运算符的特性与特殊用法
- 流程控制语句(条件判断、分支选择、循环)的应用
- 函数的多种定义方式、参数特性、闭包和生成器等高级特性
这些知识点是 JavaScript 编程的基础,理解其底层逻辑(如类型存储、作用域、函数特性)对后续学习对象、原型、异步编程等内容至关重要。代码示例与解析结合的方式,既能直观看到运行效果,又能理解背后的原理。
一、循环应用实例
1. 正整数转 16 进制(循环实现)
功能:使用循环将任意一个正整数转换为 16 进制表示
let a = 16075;
let ret = '';
while (a > 0) {// 取最后4位二进制对应的10进制值(0-15)let remainder = a & 15;// 转换为16进制字符(需补充:10-15应转为A-F)ret = remainder + ret;// 右移4位(相当于除以16)a >>= 4;
}
console.log(ret); // 正确实现需补充10-15的字符转换
说明:原代码需完善 10-15 到 A-F 的转换,可通过条件判断实现
2. 百元百鸡问题(嵌套 for 循环)
问题:公鸡 5 元 / 只,母鸡 3 元 / 只,小鸡 1 元 / 3 只,用 100 元买 100 只鸡的方案
for (let g = 0; g < 21; g++) { // 公鸡最多20只(100/5)for (let m = 0; m < 34; m++) { // 母鸡最多33只(100/3)let k = 100 - m - g; // 小鸡数量// 满足总钱数100元和总数量100只if ((g*5 + m*3 + k/3 == 100) && (g + m + k == 100)) {console.log(`公鸡=${g}, 母鸡=${m}, 小鸡=${k}`);}}
}
结果:会输出所有符合条件的组合(如 g=0,m=25,k=75 等)
3. 100 以内素数计算(for 循环)
功能:找出 100 以内所有只能被 1 和自身整除的数
for (let i = 2; i < 101; i++) {let isPrime = 1; // 标记是否为素数// 只需判断到平方根,减少计算量for (let j = 2; j < parseInt(i**0.5) + 1; j++) {if (i % j == 0) { // 能被其他数整除,不是素数isPrime = 0;break;}}if (isPrime == 1) {console.log(i); // 输出素数}
}
优化点:通过平方根限制内层循环,提高效率
4. 循环接收用户输入(do...while)
功能:不断接收用户输入,直到输入 "exit" 时退出并返回拼接结果
let inputStr = '';
let input;
do {// 接收用户输入(浏览器环境用prompt,Node环境用readline)input = prompt("请输入内容(输入exit退出):");if (input !== 'exit') {inputStr += input; // 拼接输入内容}
} while (input !== 'exit');
console.log("所有输入内容:", inputStr);
说明:利用 do...while 的特性,确保至少执行一次输入操作
二、分支与运算符应用
1. 三元运算符判断性别
功能:根据性别代码(S/M/F)输出对应性别
let gender = 'M';
// 嵌套三元运算符实现多条件判断
gender == 'S' ? console.log('保密') :
gender == 'M' ? console.log('男') :
console.log('女'); // 输出:男
说明:三元运算符可嵌套使用,实现类似 if-else if-else 的逻辑
2. switch 分支判断月份天数
功能:根据月份判断该月的最大天数(2 月按 29 天处理)
let mon = 6;
switch (mon) {case 1: case 3: case 5: case 7: case 8: case 10: case 12:console.log('31天');break;case 4: case 6: case 9: case 11:console.log('30天'); // 6月输出30天break;default: // 2月console.log('29天'); // 原代码39天为笔误,应修正
}
修正:原代码 default 分支的 39 天是错误,应改为 29 天
三、函数应用
1. 创建问候语函数
功能:生成包含问候语和姓名的字符串,支持默认参数
function createGreeting(greeting = "Hello", name = "World") {return `${greeting}: ${name}`;
}// 测试
console.log(createGreeting()); // "Hello: World"
console.log(createGreeting("Hi", "Alice")); // "Hi: Alice"
特点:使用 ES6 默认参数语法,简化函数调用
四、数组处理
1. 数组扁平化
功能:将多层嵌套数组转换为一维数组(如 [1, [2, [3,4],5],6] → [1,2,3,4,5,6])
const nestedArr = [1, [2, [3, 4], 5], 6];function flattenArray(arr) {let result = [];arr.forEach(item => {// 判断是否为数组(精确类型判断)if (Object.prototype.toString.apply(item).slice(8, -1) === 'Array') {// 递归处理嵌套数组,并合并结果result = result.concat(flattenArray(item));} else {result.push(item);}});return result;
}const flatArr = flattenArray(nestedArr);
console.log(flatArr); // [1, 2, 3, 4, 5, 6]
核心:通过递归调用和数组类型判断,逐层展开嵌套数组
总结
这些实例覆盖了 JavaScript 中循环(while/for/do...while)、分支(switch / 三元运算符)、函数(默认参数)和数组处理(扁平化)的核心应用:
- 循环擅长处理重复计算和遍历问题
- 分支结构适合多条件判断场景
- 函数通过参数和返回值实现代码复用
- 数组处理常结合递归解决嵌套结构问题
每个实例都体现了 JavaScript 的语法特性和编程思维,可作为基础算法和逻辑处理的参考模板。