1. JavaScript基础语法与数据类型全面解析
作为一名前端开发者,掌握JavaScript的基础语法和数据类型是必备技能。今天我将系统梳理JavaScript的核心基础内容,结合自己多年的开发经验,分享一些教科书上不会讲的实用技巧和常见坑点。
1.1 JavaScript的引入方式
在HTML中使用JavaScript有两种主要方式:
- 内联脚本:直接在HTML文件中使用
<script>标签包裹JavaScript代码
<script> console.log("这是内联JavaScript"); </script>- 外部脚本:通过src属性引入外部.js文件
<script src="path/to/your/script.js"></script>实际开发中强烈建议使用外部脚本方式,这有利于代码维护和缓存优化。现代前端工程通常会把脚本放在
<body>标签的底部,或者使用async/defer属性控制加载行为。
1.2 数据输出的三种方式
JavaScript提供了多种数据输出方式,各有适用场景:
- console.log()- 开发者调试利器
console.log("调试信息"); // 输出到浏览器控制台 console.table([1,2,3]); // 以表格形式输出数组/对象- document.write()- 直接写入HTML文档
document.write("<h1>Hello World</h1>");注意:document.write()在页面加载完成后调用会覆盖整个文档,实际开发中很少使用
- alert()- 弹出对话框
alert("警告信息"); // 阻塞式弹窗虽然简单,但alert会阻塞页面交互,现代前端开发更推荐使用自定义模态框或console调试
2. JavaScript数据类型深度剖析
JavaScript是弱类型语言,理解其数据类型对避免类型相关bug至关重要。
2.1 基本数据类型
- undefined- 未定义
let a; console.log(a); // undefined常见误区:undefined不是关键字,而是一个全局属性,可以被重写(不建议)
- null- 空值
let b = null; console.log(b); // nullnull表示"无对象",typeof null返回"object"是历史遗留bug
- Boolean- 布尔值
let isTrue = true; let isFalse = false;- Number- 数字类型
let int = 10; let float = 3.14; let hex = 0xFF; // 255JavaScript没有真正的整数,所有数字都是64位浮点数
- String- 字符串
let str1 = '单引号'; let str2 = "双引号"; let str3 = `模板字符串`;模板字符串支持多行和插值:
Hello ${name}
- BigInt- 大整数
const bigNum = 9007199254740991n;解决Number类型无法精确表示大于2^53-1的整数问题
- Symbol- 唯一值
const sym1 = Symbol(); const sym2 = Symbol('描述');每个Symbol都是唯一的,常用作对象属性键
2.2 引用数据类型
- Object- 对象
let obj = { name: 'John', age: 30 };- Array- 数组
let arr = [1, 2, 3];- Function- 函数
function greet() { console.log('Hello'); }3. 类型转换与比较
3.1 全等与相等运算符
JavaScript有两种相等比较方式:
'5' == 5; // true,类型转换后比较 '5' === 5; // false,严格比较类型和值实际开发中强烈建议使用===,避免隐式类型转换带来的意外结果
3.2 Boolean类型转换规则
以下值会被转换为false:
Boolean(null); // false Boolean(undefined); // false Boolean(0); // false Boolean(''); // false Boolean(NaN); // false其他所有值(包括空对象和数组)都会转换为true:
Boolean({}); // true Boolean([]); // true Boolean('0'); // true Boolean(' '); // true3.3 字符串转换
显示转换:
String(123); // "123" true.toString(); // "true"隐式转换(常用技巧):
123 + ''; // "123"3.4 Number类型转换
Number()函数的转换规则:
Number(null); // 0 Number(undefined); // NaN Number(true); // 1 Number(false); // 0 Number('123'); // 123 Number('123.45'); // 123.45 Number('123abc'); // NaN3.5 数值解析函数
parseInt和parseFloat的区别:
parseInt('123.45'); // 123 parseFloat('123.45'); // 123.45 parseInt('10px'); // 10 parseInt('010'); // 10(ES5+),8(ES3)建议总是指定parseInt的基数:parseInt('010', 10)
4. 流程控制与函数
4.1 条件语句
if...else if...else结构:
if (score >= 90) { grade = 'A'; } else if (score >= 80) { grade = 'B'; } else { grade = 'C'; }switch语句:
switch(day) { case 0: dayName = 'Sunday'; break; case 1: dayName = 'Monday'; break; default: dayName = 'Unknown'; }忘记break会导致case穿透,这是常见错误点
4.2 循环结构
for循环:
for (let i = 0; i < 10; i++) { console.log(i); }while循环:
let i = 0; while (i < 10) { console.log(i); i++; }for...in循环(遍历对象属性):
const obj = {a:1, b:2}; for (let key in obj) { console.log(key, obj[key]); }for...of循环(遍历可迭代对象):
const arr = [1, 2, 3]; for (let value of arr) { console.log(value); }for...in遍历键名,for...of遍历值,这是重要区别
4.3 函数定义与使用
函数声明:
function add(a, b) { return a + b; }函数表达式:
const add = function(a, b) { return a + b; };箭头函数(ES6+):
const add = (a, b) => a + b;4.4 异常处理
try...catch...finally结构:
try { // 可能出错的代码 JSON.parse('invalid json'); } catch (error) { console.error('解析出错:', error.message); } finally { console.log('无论成功失败都会执行'); }抛出异常:
function divide(a, b) { if (b === 0) { throw new Error('除数不能为零'); } return a / b; }5. 实战经验与常见问题
5.1 类型判断最佳实践
typeof的局限性:
typeof null; // "object"(历史遗留问题) typeof []; // "object" typeof new Date();// "object"更可靠的类型检查方法:
Array.isArray([]); // true Object.prototype.toString.call(null); // "[object Null]"5.2 浮点数精度问题
JavaScript的浮点数计算存在精度问题:
0.1 + 0.2 === 0.3; // false解决方案:
// 使用toFixed限制小数位数 (0.1 + 0.2).toFixed(2); // "0.30" // 转换为整数计算 (0.1*10 + 0.2*10)/10; // 0.35.3 变量提升与暂时性死区
var的变量提升:
console.log(a); // undefined var a = 1;let/const的暂时性死区:
console.log(b); // ReferenceError let b = 2;5.4 数组遍历的陷阱
for...in遍历数组的问题:
Array.prototype.customMethod = function() {}; const arr = [1, 2, 3]; for (let index in arr) { console.log(index); // 会输出"0","1","2","customMethod" }遍历数组应该使用for循环、forEach或for...of
5.5 函数参数默认值
ES5实现方式:
function greet(name) { name = name || 'Guest'; console.log('Hello ' + name); }ES6更优雅的方式:
function greet(name = 'Guest') { console.log(`Hello ${name}`); }6. 现代JavaScript开发建议
6.1 使用严格模式
在脚本或函数顶部添加:
'use strict';严格模式的好处:
- 消除静默错误
- 防止意外创建全局变量
- 禁止使用未来可能成为关键字的标识符
6.2 优先使用const和let
现代JavaScript开发建议:
- 默认使用const
- 需要重新赋值时使用let
- 避免使用var
6.3 模板字符串的优势
传统字符串拼接:
const greeting = 'Hello ' + name + ', today is ' + day;模板字符串方式:
const greeting = `Hello ${name}, today is ${day}`;支持多行字符串和表达式插值
6.4 解构赋值技巧
数组解构:
const [first, second] = [1, 2];对象解构:
const {name, age} = {name: 'John', age: 30};函数参数解构:
function greet({name, age}) { console.log(`Hello ${name}, you are ${age}`); }6.5 展开运算符的应用
数组合并:
const arr1 = [1, 2]; const arr2 = [3, 4]; const combined = [...arr1, ...arr2];对象合并:
const obj1 = {a: 1}; const obj2 = {b: 2}; const merged = {...obj1, ...obj2};函数参数传递:
const numbers = [1, 2, 3]; Math.max(...numbers);掌握这些JavaScript基础知识是成为合格前端开发者的第一步。在实际项目中,类型转换、循环遍历和函数使用是最容易出问题的地方,需要特别注意。建议通过实际编码练习来巩固这些概念,遇到问题时多查阅MDN文档。