4. JavaScript核心基础:变量与数据类型、运算符、流程控制、函数、对象与数组、DOM操作

JavaScript,说白了就是让网页「活过来」的语言。没有它,网页就是一本书,翻来翻去就那几页。有了它,网页才能跟你互动、响应你的点击、动态更新内容。

我个人习惯把JS比作「网页的肌肉」。HTML是骨架,CSS是皮肤,JS就是让骨架动起来的肌肉。今天我们就来把这套肌肉系统拆开看看。

JavaScript 核心基础 变量与数据类型 运算符 流程控制 函数 对象与数组 let / const / var + - * / % === if / for / while 声明 / 调用 / 作用域 {} / [] / 方法 DOM 操作

4.1 变量与数据类型

变量就是存东西的盒子。JavaScript里声明变量有三种方式:var、let、const。

我刚开始写JS时,一直用var,后来踩了不少坑。比如变量提升(hoisting)这个问题,var声明的变量会被提升到作用域顶部,但赋值不会。你想想看,代码还没跑到那行,变量就已经存在了,只是值是undefined。这很容易让人困惑。

推荐做法:现在写代码,我基本只用let和const。const用于不会重新赋值的变量,let用于会变的。至于var……嗯,就当它不存在吧。

// 声明变量
let name = '张三';
const age = 25;
var oldWay = '别用我'; // 不推荐

// 数据类型
let str = '字符串';          // String
let num = 42;               // Number
let isOk = true;            // Boolean
let nothing = null;         // Null
let notDefined;             // Undefined
let bigNumber = 123n;       // BigInt
let sym = Symbol('id');     // Symbol

console.log(typeof str);    // "string"

小技巧:用typeof运算符可以快速检查变量类型。不过要注意,typeof null返回的是"object",这是JS的一个历史遗留bug,记住就好。

4.2 运算符

运算符就是用来做运算的符号。加减乘除不用说,重点说说几个容易搞混的。

比较运算符:==和===的区别,我面试时经常问别人。前者只比较值,后者比较值和类型。

console.log(5 == '5');   // true(类型转换后相等)
console.log(5 === '5');  // false(类型不同)

// 我曾经在项目中遇到过这样的bug:
let score = '100';
if (score == 100) {
  // 这里会执行,因为'100'被转成了100
  console.log('相等');
}
// 改成 === 就安全了

避坑指南:永远使用===和!==,不要用==和!=。我曾经因为==的类型转换机制,在判断用户输入时出了个隐蔽的bug,排查了整整两个小时。

逻辑运算符:&&(与)、||(或)、!(非)。它们有短路特性,这个特性在实际开发中很实用。

// 短路求值
let user = null;
let displayName = user || '匿名用户';  // '匿名用户'

// 三元运算符
let age = 18;
let status = age >= 18 ? '成年' : '未成年';

4.3 流程控制

流程控制就是决定代码走哪条路。说白了,就是「如果……就……否则……」的逻辑。

if/else:最基础的条件判断。

let hour = 14;
if (hour < 12) {
  console.log('上午');
} else if (hour < 18) {
  console.log('下午');
} else {
  console.log('晚上');
}

switch:当判断条件比较多时,用switch比if/else更清晰。

let day = 3;
switch (day) {
  case 1:
    console.log('周一');
    break;
  case 2:
    console.log('周二');
    break;
  default:
    console.log('其他');
}

注意:别忘了写break!不写的话会「穿透」到下一个case。有时候可以利用这个特性,但大多数情况下是bug。

循环:for、while、do...while。

// for循环 - 最常用
for (let i = 0; i < 5; i++) {
  console.log(i);
}

// while循环
let count = 0;
while (count < 3) {
  console.log(count);
  count++;
}

// for...of - 遍历数组
let fruits = ['苹果', '香蕉', '橘子'];
for (let fruit of fruits) {
  console.log(fruit);
}

4.4 函数

函数就是一段可以重复调用的代码块。我习惯把函数想象成「小工具」,需要的时候拿出来用一下。

// 函数声明
function greet(name) {
  return '你好,' + name + '!';
}

// 函数表达式
const add = function(a, b) {
  return a + b;
};

// 箭头函数(ES6)
const multiply = (a, b) => a * b;

console.log(greet('小明'));   // "你好,小明!"
console.log(add(3, 4));      // 7
console.log(multiply(3, 4)); // 12

作用域:函数内部声明的变量,外部访问不到。这就是「局部作用域」。我刚开始学的时候,经常在函数外面想访问函数里面的变量,结果拿到undefined,一脸懵。

function test() {
  let x = 10;
  console.log(x); // 10
}
// console.log(x); // 报错!x is not defined

4.5 对象与数组

对象和数组是JS里最常用的数据结构。对象用花括号{},数组用方括号[]。

对象:用来描述一个「东西」的多个属性。

// 创建对象
let person = {
  name: '李四',
  age: 30,
  city: '北京',
  sayHi: function() {
    console.log('大家好,我是' + this.name);
  }
};

// 访问属性
console.log(person.name);    // "李四"
console.log(person['age']);  // 30
person.sayHi();              // "大家好,我是李四"

数组:用来存一组数据。

// 创建数组
let colors = ['红', '绿', '蓝'];

// 常用方法
colors.push('黄');           // 末尾添加
colors.pop();                // 末尾删除
colors.unshift('紫');        // 开头添加
colors.shift();              // 开头删除

// 遍历
colors.forEach(function(color, index) {
  console.log(index + ': ' + color);
});

// map - 映射出新数组
let upperColors = colors.map(c => c + '色');
console.log(upperColors);    // ["红色", "绿色", "蓝色"]

经验之谈:数组的map、filter、reduce这三个方法,在实际项目中用得非常多。我建议你多练习它们,能写出更简洁、更函数式的代码。

4.6 DOM操作

DOM(Document Object Model)就是浏览器把HTML文档解析成的一棵树。JS通过操作这棵树,来改变网页的内容和样式。

说白了,DOM操作就是「找到元素,然后改它」。

// 获取元素
let title = document.getElementById('title');
let items = document.getElementsByClassName('item');
let firstItem = document.querySelector('.item');
let allItems = document.querySelectorAll('.item');

// 修改内容
title.textContent = '新标题';
title.innerHTML = '<span>带标签的内容</span>';

// 修改样式
title.style.color = 'red';
title.style.fontSize = '20px';

// 添加/删除类
title.classList.add('active');
title.classList.remove('inactive');
title.classList.toggle('highlight');

// 创建和插入元素
let newDiv = document.createElement('div');
newDiv.textContent = '我是新来的';
document.body.appendChild(newDiv);

避坑指南:我曾经在项目中频繁操作DOM,导致页面卡顿。后来才明白,每次DOM操作都会触发浏览器的重排(reflow)或重绘(repaint)。优化方法是:先把要改的内容拼好,一次性插入。或者用document.createDocumentFragment()来批量操作。

// 批量插入 - 性能更好
let fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  let li = document.createElement('li');
  li.textContent = '项目 ' + i;
  fragment.appendChild(li);
}
document.getElementById('list').appendChild(fragment);

事件监听:让元素响应用户操作。

let btn = document.getElementById('myBtn');
btn.addEventListener('click', function(event) {
  console.log('按钮被点击了!');
  console.log('事件对象:', event);
});

// 常用事件:click, mouseover, mouseout, keydown, submit

嗯,到这里,JavaScript的核心基础就讲完了。这些内容看起来多,但说白了就是「存数据、做运算、走分支、写函数、用对象数组、操作页面」。每一个知识点,你写代码时都会反复用到。

我个人觉得,学JS最好的方式就是动手写。打开浏览器的控制台(F12),直接敲代码试试看。看到结果的那一刻,比看十遍教程都有用。

最后一个小建议:遇到不懂的,先查MDN文档。那是最权威的JS参考资料,比任何博客都靠谱。

可可精品资料库