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/falsetypeof 为 boolean
    • 对象类型:new Boolean() 创建,typeof 为 object
    • 转换规则:0""nullundefinedNaN 转为 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 的语法特性和编程思维,可作为基础算法和逻辑处理的参考模板。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值