← 返回目录

11. class 类

class 就是面向对象的写法,用 class 定义类,new 创建对象。

核心三个:
constructor——构造函数,new 时自动调
方法——直接写在 class 里
extends——继承父类

坑:class 不会变量提升、super 调用父类方法、class 里的方法没有 this 绑定

11.1 互动演示

点按钮看 class / extends / static 的实际输出。

11.2 知识点讲解

① 基本写法:构造函数 + 原型 → class

以前造对象要写"构造函数"再往 prototype 上挂方法,东一块西一块;class 把数据和方法全收进一个花括号里,像把模具图纸钉在一张纸上。

// 以前:构造函数 + 手动挂原型,散在两处
// 构造函数:造手机时传品牌、价格
function Phone(brand, price) {

// 每个手机的品牌,存到 this 上
  this.brand = brand;

// 每个手机的价格,存到 this 上
  this.price = price;
}

// 手动把方法挂到原型上(所有手机共用)
Phone.prototype.makeCall = function () {

// 方法挂在原型上
  console.log("可以打电话");

// 现在:class,数据和方法写在一个块里
};

// 一个模具图纸,数据 + 方法钉在一张纸上
class Phone {

// 造对象时自动跑一次的初始化
  constructor(brand, price) {

// 把品牌存进这台手机
    this.brand = brand;

// 把价格存进这台手机
    this.price = price;
  }

// 方法直接写里面,不用再挂 prototype
  makeCall() {

// 这台手机能打电话
    console.log("可以打电话");
  }
}

// new 一下,模具压出一台手机
let p = new Phone("Huawei", 5999);

constructor 是"造对象时自动执行"的初始化函数,名字固定不能改。如果你写了 new Phone 却忘了传 brand/price,造出来的手机品牌就是 undefined。方法不用再挂 prototype,集中在类里一眼看清这模具能干什么。

② 继承:extends + super

有了"普通手机模具",想造"智能手机",不用重新开模,extends 就是"在旧模具上改个新模具",super 是"先让旧模具把它那部分造好"。

// 以前:原型链继承,写起来绕
// 智能手机构造函数
function Smart(brand) {

// 手动借父类构造(.call 把 this 借过去)
  Phone.call(this, brand);
}

// 手动把原型链连上父类
Smart.prototype = new Phone();

// 手动挂新方法
Smart.prototype.takePhoto = function () { console.log("拍照"); };

// 现在:extends + super,两行说清楚
// 新模具继承旧模具(extends = 在旧模具上改)
class Smart extends Phone {

// 智能手机自己的初始化
  constructor(brand, color) {

// ★ 先调用父类构造(必须写在 this 之前)
    super(brand);

// 新模具再加自己的属性(颜色)
    this.color = color;
  }

// 新模具加的新功能
  takePhoto() {
    console.log("拍照");
  }
}

// 压出一台智能手机
let s = new Smart("Xiaomi", "黑色");

如果你在子类的 constructor 里先写了 this.color = color 再调 super,浏览器会直接报错"必须先调用 super"。因为父类那部分还没初始化,this 这台"手机"都还没造出来,你没法给它贴颜色。

③ 静态成员:属于模具,不属于手机

想象模具上刻着一行"Made in 深圳"——这行字是模具自己的,任何一台出厂手机身上都没有。加 static 的东西就是这种"模具级"成员。

class Phone {

// 静态属性:刻在模具上,不属于任何一台手机
  static factory = "深圳某工厂";

// 静态方法:模具自己的功能,不用 new
  static upgrade() {

// 直接调模具本身
    console.log("模具升级了");
  }
}

// 深圳某工厂(用模具名访问)
console.log(Phone.factory);

// 模具升级了(用模具名调用)
Phone.upgrade();

// new 出来的手机访问不到 factory —— 那是模具上的字

如果你拿 new Phone 出来的手机去读 .factory,得到的是 undefined。因为 static 只挂在类本身上,不挂在实例上——像 Math.maxDate.now 这种"直接拿工具用、不用 new"的方法,就是静态方法的思路。

11.3 实战:用在哪 / 常见坑 / 怎么解决

① 可能在什么地方用:Vue/React 里的组件类、写工具类(如封装一个 Request 类、一个 Store 类)、做"多张同结构卡片"的数据模型(如 User、Order、Goods)、需要继承复用逻辑时(父类公共方法 + 子类个性化)。

② 常见的问题:子类 constructor 里 super 忘写或写在 this 之后直接报错;把 static 成员当实例成员读出来是 undefined;this 方法里传出去当回调后 this 丢失(比如 btn.onclick = obj.say)。

③ 解决思路:报错 "must call super" 就把 super 移到 constructor 第一行;读到 undefined 先确认是不是 static;this 丢了就用箭头函数绑住 this,或在 constructor 里 this.say = this.say.bind(this)

一句话:class = 生产对象的模具constructor 初始化、extends + super 继承、static 属于模具本身。

本页重点

API作用参数返回值代码示例
class 名 {}造对象的模具图纸-一个类class Phone {}
constructor() {}new 的时候自动跑一次的初始化参数初始化对象const c = 3;
extends子类继承父类的全部本事父类名一个子类class Smart extends Phone {}
super()先调父类构造,把旧部分造好参数父类实例super(brand);
static属于模具本身、不属于造出来的手机-类成员static factory = "厂";