JavaScript 完整详细教程

IT 技术 12 阅读 更新于 2026-10-05 21:42

JavaScript 完整详细教程

适合零基础入门,由浅入深,包含语法、DOM、ES6+、异步、实战要点。
JS 是一门弱类型、动态、解释型语言,既可在浏览器运行,也可在 Node.js 后端运行。

一、JS 三种引入方式

1. 行内(不推荐)

<button onclick="alert('Hello')">点我</button>

2. 内嵌 script

<script>
  // JS代码写这里
  console.log("内嵌JS");
</script>

3. 外部文件(推荐,后缀 .js)

<script src="main.js"></script>

注意:script 默认阻塞页面解析,可加 defer / async

  • defer:下载脚本,等HTML解析完再按顺序执行
  • async:下载完立刻执行,顺序不确定
<script src="main.js" defer></script>

二、基础语法

1. 输出

console.log("控制台打印");
alert("弹窗");
document.write("页面输出");

2. 变量声明:var / let / const

关键字作用域是否可修改提升
var函数作用域可重新赋值、重复声明变量提升
let块级作用域 {}可赋值,不可重复声明存在提升,暂时性死区
const块级作用域常量,不可重新赋值;对象属性可改存在提升,暂时性死区

✅ 推荐:优先 const,需要修改用 let,尽量不用 var

let name = "张三";
const age = 18;
name = "李四";
// age = 20; // 报错,const不能重新赋值

块级作用域:if / for / {} 内部,外面访问不到 let/const

3. 数据类型

JS 分为 原始类型(基本类型) 和 引用类型

原始类型(值拷贝)

  1. string 字符串:"abc" / 'abc' / \模板字符串``
  2. number 数字:整数、小数、NaN、Infinity
  3. boolean 布尔:true / false
  4. null:空值(typeof null === 'object' 历史bug)
  5. undefined:未定义,变量声明没赋值
  6. symbol ES6:唯一标识
  7. bigint ES2020:超大整数

引用类型(地址拷贝)

object 对象、array 数组、function 函数、Date、RegExp 等

let obj1 = {name:"A"}
let obj2 = obj1; // 复制地址,不是复制对象
obj2.name = "B";
console.log(obj1.name); // B

判断类型

typeof "abc" // 'string'
typeof 123 // 'number'
typeof true // 'boolean'
typeof undefined // 'undefined'
typeof null // 'object' ❗
typeof {} // 'object'
typeof [] // 'object'
typeof function(){} // 'function'

// 判断数组
Array.isArray([]) // true
// 判断null
myVal === null

4. 运算符

算术运算符

+ - * / % ++ --

+ 遇到字符串会变成字符串拼接

1 + "2" // "12"

赋值运算符

= += -= *= /= %=

比较运算符

> < >= <= == === != !==

  • ==:宽松相等,自动类型转换
  • ===:严格相等,值和类型都要一样,推荐使用
1 == "1" // true
1 === "1" // false

逻辑运算符

&& 与,|| 或,! 非

短路特性:
a && b:a为真才执行b;a假直接返回a
a || b:a为真直接返回a;a假返回b

三元运算符

let res = age >=18 ? "成年":"未成年";

三、流程控制

1. if else

let score = 80;
if(score >=90){
  console.log("优秀");
}else if(score >=60){
  console.log("及格");
}else{
  console.log("不及格");
}

2. switch

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

switch 使用 === 判断,记得加 break,否则穿透

3. for 循环

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

4. while / do while

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

// do while 先执行一次再判断
let j=0;
do{
  console.log(j);
  j++;
}while(j<3)

5. for...in 遍历对象(不推荐遍历数组)

let obj = {name:"小明",age:16}
for(let key in obj){
  console.log(key, obj[key])
}

6. for...of ES6 遍历可迭代对象:数组、字符串、Map、Set

let arr = [10,20,30]
for(let item of arr){
  console.log(item)
}

关键字

break:跳出循环;continue:结束本次循环,进入下一次


四、函数 Function

1. 函数声明

function sayHi(name){
  console.log("Hi,"+name);
  return "ok"; // return 返回值,没有return默认返回undefined
}
sayHi("张三");

2. 函数表达式

const say = function(){
  console.log("函数表达式");
}
say();

3. ES6 箭头函数(重点)

const add = (a,b) => a+b;
// 多行需要{} + return
const test = (x)=>{
  let res = x*2;
  return res;
}

⚠️ 箭头函数特点

  1. 没有自己的this,继承外层作用域this
  2. 不能用作构造函数 new
  3. 没有 arguments 对象,可以用剩余参数 ...args

4. 参数

  • 默认参数
function fn(a=10){
  console.log(a);
}
fn(); //10
  • 剩余参数 ...args,必须放最后
function sum(a,...args){
  console.log(a, args);
}
sum(1,2,3,4);

5. 作用域 & 闭包

  • 全局作用域、函数作用域、块级作用域 {}>

闭包:函数A内部返回函数B,B可以访问A的变量,即使A执行完毕

function outer(){
  let num = 10;
  return function inner(){
    console.log(num);
  }
}
const f = outer();
f(); // 10

闭包用途:保存私有变量;缺点:变量常驻内存,容易内存泄漏

6. this 指向(高频考点)

  1. 普通函数调用:this -> window(浏览器)/ global(node),严格模式下 undefined
  2. 对象方法调用:this 指向调用方法的对象
  3. new 构造函数:this 指向新实例
  4. call / apply / bind:手动绑定this
  5. 箭头函数:this 定义时外层的this,和调用无关
let obj = {
  name:"test",
  fn:function(){
    console.log(this.name);
  }
}
obj.fn(); // this是obj

call / apply / bind

function hello(){console.log(this.name)}
let user = {name:"老王"}
hello.call(user);
hello.apply(user);
const boundHello = hello.bind(user);
boundHello();

call( thisArg, 参数1,参数2 )
apply( thisArg, [参数数组] )
bind 返回新函数,不会立刻执行


五、数组 Array

let arr = [1,2,3];

常用方法(改变原数组)

push() 末尾添加;pop() 删除末尾;unshift() 头部添加;shift() 删除头部
splice(start, deleteCount, 新增元素):增删改
reverse() 反转;sort() 排序(默认按字符排序!数字排序需要回调)

let nums = [2,1,10];
nums.sort((a,b)=>a-b); //升序

不改变原数组

slice(start,end) 截取;concat() 拼接;join() 转字符串;indexOf / includes 判断是否存在

ES6 数组迭代方法(非常常用)

const list = [1,2,3,4];
// map:返回新数组,对每个元素加工
const res1 = list.map(item=>item*2);

// filter:过滤,返回满足条件元素组成新数组
const res2 = list.filter(item=>item>2);

// reduce:累加器
const total = list.reduce((sum,item)=>sum+item,0);

// forEach:遍历,无返回值
list.forEach(item=>console.log(item));

// some:只要一个true,返回true
// every:全部true才返回true

六、对象 Object

const user = {
  name:"小李",
  age:20,
  say:function(){
    console.log(this.name)
  }
}
// 访问属性
console.log(user.name);
console.log(user["name"]); // 方括号支持变量

// 添加/修改属性
user.gender = "男";
// 删除
delete user.age;

ES6 对象简写

let name = "Tom";
const obj = {
  name, // name:name简写
  hello(){ // 方法简写
    console.log("hi")
  }
}

对象常用API

Object.keys(obj) // 获取所有key数组
Object.values(obj) // 获取所有value数组
Object.entries(obj) // [key,value]数组
Object.assign(target, source) // 对象浅拷贝合并

浅拷贝:只拷贝第一层;嵌套对象仍然是引用。深拷贝需要递归或者结构化克隆


七、ES6+ 核心语法

1. 解构赋值

// 对象解构
const {name,age} = user;

// 数组解构
const [a,b] = [10,20];

// 剩余
const [x,...rest] = [1,2,3]

2. 模板字符串 \`

let n = "小明";
let str = `名字:${n}`; //支持换行、变量嵌入

3. 展开运算符 ...

const arr1 = [1,2];
const arr2 = [...arr1,3,4]; //复制数组
const o1 = {a:1};
const o2 = {...o1, b:2}; //对象浅拷贝

4. Set / Map

  • Set:集合,元素唯一
const s = new Set([1,2,2,3]);
console.log([...s]); //去重数组
  • Map:键可以是任意类型(Object key只能是字符串/Symbol)
const m = new Map();
m.set("name","test");
m.get("name");

八、DOM 文档对象模型(浏览器JS)

DOM:把HTML文档转成JS对象树,可以操作页面元素。

获取元素

// id
document.getElementById("box");
// class
document.getElementsByClassName("item");
// 标签
document.getElementsByTagName("div");
// css选择器(推荐)
document.querySelector(".box"); //匹配第一个
document.querySelectorAll(".item"); //返回NodeList集合

操作内容

ele.innerText //纯文本
ele.innerHTML // 支持html标签
ele.value //表单input的值

操作属性

ele.setAttribute("data-id",100);
ele.getAttribute("data-id");
ele.removeAttribute("data-id");
// 原生属性直接 .
ele.src = "xxx.jpg";

操作样式

ele.style.backgroundColor = "red"; //行内样式,驼峰命名
// 类名控制(推荐,不要直接写大量style)
ele.classList.add("active");
ele.classList.remove("active");
ele.classList.toggle("active"); //有就删,没有就加
ele.classList.contains("active");

节点操作

const newDiv = document.createElement("div");
parent.appendChild(newDiv); //末尾追加
parent.insertBefore(newDiv, oldNode);
parent.removeChild(child);
ele.cloneNode(true); //true深度克隆,包含子节点

事件

绑定事件

const btn = document.querySelector("button");
btn.addEventListener("click", function(e){
  console.log("点击");
  e.target //触发事件元素
  e.preventDefault(); //阻止默认行为(a跳转、表单提交)
  e.stopPropagation(); //阻止事件冒泡
})

事件流:捕获 -> 目标 -> 冒泡。addEventListener第三个参数true为捕获,默认false冒泡。

常用事件:click、input、change、mouseover、mouseout、keydown、keyup、load


九、BOM 浏览器对象模型

BOM:浏览器窗口相关API

window.alert()
window.location.href = "[https://xxx.com](https://xxx.com)"; //跳转页面
location.reload(); //刷新
console.log(navigator.userAgent); //浏览器信息
history.back(); history.forward(); //历史记录

// 定时器
const timer = setTimeout(()=>{
  console.log("延迟1秒");
},1000);
clearTimeout(timer);

// 循环定时器
const inter = setInterval(()=>{
  console.log("每隔1秒");
},1000);
clearInterval(inter);

JS 是单线程,定时器不是精确到时间,放入任务队列等待主线程空闲才执行


十、异步 JavaScript(重点难点)

JS 单线程,同步代码阻塞,异步用来处理请求、定时器、文件读写。

1. 回调函数(回调地狱)

// 回调嵌套过多,可读性差
getData(function(a){
  getMore(a, function(b){

  })
})

2. Promise ES6

Promise 三种状态:pending等待、fulfilled成功、rejected失败。状态一旦改变不可回退。

function fetchData(){
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      resolve("数据成功");
      // reject("失败");
    },1000)
  })
}

fetchData()
.then(res=>{console.log(res)})
.catch(err=>{console.log(err)})
.finally(()=>{console.log("不管成功失败都会执行")})

链式调用:.then 返回新Promise
Promise.all([p1,p2]):全部成功才成功,一个失败直接失败
Promise.race([p1,p2]):谁先完成返回谁

3. async / await ES2017(Promise语法糖)

async 修饰函数,返回Promise;await 只能在async函数内部,等待Promise完成

async function load(){
  try{
    const res = await fetchData();
    console.log(res);
  }catch(err){
    console.log(err);
  }
}
load();

宏任务、微任务(事件循环 Event Loop)

执行顺序:

  1. 先执行同步代码
  2. 执行所有微任务(Promise.then、queueMicrotask、MutationObserver)
  3. 再取一个宏任务执行(setTimeout、setInterval、AJAX、DOM渲染),然后清空微任务,循环往复。

十一、JSON & 网络请求

// 对象转JSON字符串
const jsonStr = JSON.stringify(user);
// JSON字符串转回对象
const obj = JSON.parse(jsonStr);

fetch(浏览器原生网络请求)

async function getApi(){
  const res = await fetch("https://xxx/api");
  const data = await res.json();
  console.log(data);
}

旧方案:XMLHttpRequest


十二、错误处理

try{
  // 可能出错代码
  let a = b +1;
}catch(err){
  console.log("捕获错误:",err.message);
}finally{
  console.log("一定会执行");
}

手动抛出错误:throw new Error("自定义错误")


十三、面向对象 OOP ES6 Class

class Person{
  constructor(name){ //构造函数,new的时候自动执行
    this.name = name;
  }
  say(){
    console.log(this.name);
  }
}
const p1 = new Person("张三");
p1.say();

// 继承 extends
class Student extends Person{
  constructor(name,score){
    super(name); //调用父类构造,必须写在前面
    this.score = score;
  }
}

十四、常见坑 & 最佳实践

  1. 不要用 ==,一律 ===
  2. 全局变量尽量少,污染命名空间
  3. 定时器用完记得清除,防止内存泄漏
  4. 闭包慎用,避免内存无法释放
  5. 数组sort默认字符排序,数字一定要传回调
  6. this 是动态的,箭头函数不要滥用
  7. DOM操作尽量少,频繁操作会重绘重排,性能差
  8. const优先,let次之,var废弃

十五、学习路线建议

  1. 基础语法、变量、循环、函数(敲代码练习)
  2. 数组对象、ES6语法
  3. DOM操作,写小案例:计数器、待办Todo、轮播
  4. 异步:Promise、async await、事件循环
  5. 网络请求,接口联调
  6. 学习框架:Vue / React(JS基础扎实后)
  7. Node.js,后端JS

如果你想要,我可以继续提供:

  1. 配套可直接复制练习的练习题
  2. 简易实战项目:Todo清单
  3. 单独一份 JS面试核心精简版
  4. 分章节Markdown文档版本方便导入Obsidian

你想要哪一种?

← 返回IT 技术 yicool 百科 · JavaScript 完整详细教程

评论 0