JavaScript 类 Class 完整知识点讲解
·
一、基础概念
ES6 引入 class 语法,是构造函数的语法糖,本质还是基于原型继承,只是写法更贴近传统面向对象语言(Java/C#)。 作用:封装属性、方法,统一创建同类对象。
1. 基础定义与实例化
js
运行
// 定义类
class Person {
// 构造函数:创建实例时自动执行,接收参数
constructor(name, age) {
// 实例属性,绑定到每个实例
this.name = name;
this.age = age;
}
// 实例方法:存在原型上,所有实例共享,节省内存
sayHi() {
console.log(`我是${this.name},今年${this.age}`);
}
}
// new 实例化
const p1 = new Person("张三", 22);
p1.sayHi(); // 我是张三,今年22
console.log(p1.name); // 张三
关键点:
constructor固定构造方法,一个类只能有一个 constructor,不写会自动生成空构造;- 必须用
new调用类,直接Person()会报错; this指向当前 new 出来的实例。
二、实例属性、原型方法、静态属性 / 静态方法
1. 实例属性
两种写法: 1)构造函数内 this.xxx(常用) 2)类内部直接声明(ES2022 实例字段)
js
运行
class User {
// 直接声明实例属性,所有实例默认拥有
gender = "男";
constructor(name) {
this.name = name;
}
}
const u = new User("李四");
console.log(u.gender, u.name); // 男 李四
2. 实例方法(原型方法)
写在 class 大括号内,不加 function,自动挂载到 类.prototype 所有实例共用一份函数,不会每次 new 新建函数:
js
运行
class Car {
run() {
console.log("车在跑");
}
}
const c1 = new Car();
const c2 = new Car();
console.log(c1.run === c2.run); // true
3. 静态 static(属于类本身,不属于实例)
加 static 关键字,只能类名。方法调用,实例访问不到。 常用于工具方法、全局常量。
js
运行
class MathUtil {
// 静态属性
static PI = 3.1415;
// 静态方法
static sum(a, b) {
return a + b;
}
}
console.log(MathUtil.PI);
console.log(MathUtil.sum(1,2)); // 3
const util = new MathUtil();
console.log(util.sum); // undefined 实例拿不到静态方法
静态方法内的 this 指向当前类,不是实例。
三、访问器 Getter / Setter(拦截属性读写)
监听属性读取、修改,常用于数据校验、格式化:
js
运行
class Student {
constructor(realAge) {
this._realAge = realAge;
}
// 读取时触发 stu.age
get age() {
return this._realAge + "岁";
}
// 赋值时触发 stu.age = xx
set age(val) {
if (typeof val !== "number") {
throw new Error("年龄必须是数字");
}
this._realAge = val;
}
}
const s = new Student(18);
console.log(s.age); // 18岁 get执行
s.age = 20; // set执行
s.age = "二十"; // 报错
约定:内部真实数据用 _xxx 命名,表示私有(早期无真正私有)。
四、私有属性 / 私有方法 #(ES2022)
# 开头代表私有,只能在类内部访问,外部、子类都拿不到。
1. 私有字段
js
运行
class Book {
#price; // 私有属性声明
constructor(name, price) {
this.name = name;
this.#price = price;
}
showPrice() {
console.log(this.#price); // 内部可访问
}
}
const b = new Book("JS高级", 59);
console.log(b.#price); // 语法报错,外部禁止访问
b.showPrice(); // 59
2. 私有方法
js
运行
class Demo {
#log() {
console.log("私有方法");
}
run() {
this.#log(); // 内部调用正常
}
}
const d = new Demo();
d.#log(); // 报错
五、继承 extends + super(核心面向对象)
extends 实现类继承,子类拥有父类所有属性、方法; super() 代表调用父类构造函数,子类 constructor 第一行必须写 super ()。
基础继承
js
运行
// 父类
class Animal {
constructor(name) {
this.name = name;
}
eat() {
console.log(`${this.name}吃东西`);
}
}
// 子类 Dog 继承 Animal
class Dog extends Animal {
constructor(name, color) {
// 调用父类构造,给父类属性赋值
super(name);
// 子类独有属性
this.color = color;
}
// 重写父类方法(覆盖)
eat() {
// super.方法() 调用父类原有逻辑
super.eat();
console.log(`${this.color}小狗啃骨头`);
}
}
const dog = new Dog("旺财", "黄色");
dog.eat();
/*
旺财吃东西
黄色小狗啃骨头
*/
super 两种用法:
super(参数):构造器中调用父类构造;super.xxx():方法内调用父类同名方法。
继承规则
- 子类不写 constructor,会自动补全
constructor(...args) { super(...args) }; - 子类构造函数在
super()执行前,不能使用this; - 静态方法也能继承,子类可通过
super.静态方法()调用父类静态。
六、类的 this 指向大坑
1. 普通实例方法:this 默认指向实例
js
运行
class Test {
fn() {
console.log(this);
}
}
const t = new Test();
t.fn(); // Test 实例
2. 方法单独提取调用,this 丢失(变成 undefined)
严格模式下 class 内代码默认严格模式,this 不会指向 window:
js
运行
const fn = t.fn;
fn(); // undefined
解决三种方案:
- constructor 内 bind 绑定 this
js
运行
constructor() {
this.fn = this.fn.bind(this);
}
- 箭头函数实例字段(推荐 React 组件使用)
js
运行
class Test {
fn = () => {
console.log(this);
}
}
- 调用时
fn.call(t)临时绑定
七、类与传统构造函数对比
class 是语法糖,底层原型逻辑完全一致:
js
运行
// ES5 构造函数
function Person(name) {
this.name = name;
}
Person.prototype.say = function(){}
// ES6 class 等价于上面
class Person {
constructor(name) { this.name = name }
say(){}
}
区别:
- class 不能直接调用,必须 new;构造函数可直接执行;
- class 内部默认严格模式;
- class 方法不可枚举,ES5 prototype 方法可枚举;
- class 有私有字段、static、extends 更简洁。
八、常用实操案例:封装工具类
js
运行
// 日期工具类
class DateUtil {
static format(timestamp) {
const date = new Date(timestamp);
const y = date.getFullYear();
const m = date.getMonth() + 1;
const d = date.getDate();
return `${y}-${m}-${d}`;
}
}
console.log(DateUtil.format(Date.now()));
九、高频面试考点总结
- class 是构造函数语法糖,底层基于原型;
- constructor 只能一个,new 触发;
- static 属于类本身,实例无法访问;
-
私有属性只能类内访问,子类也无法直接读取;
- extends 继承,子类构造必须先 super ();
- super () 调用父构造,super. 方法调用父类方法;
- 类方法单独取出执行 this 为 undefined,箭头字段可修复;
- getter/setter 拦截属性读写,用于数据校验;
- 所有类方法不存在变量提升,不能先使用再定义。
更多推荐

所有评论(0)