谈谈你对ES6中Class类的理解_es6中的class常见使用场景
myzbx 2025-08-31 06:15 48 浏览
我们都知道ES6有了面向对象的概念,而class(类)就是ES6中新的基础性语法糖结构,虽然ES6 class表面上看起来可以支持正式的面向对象编程,但实际上它背后使用的仍然是原型和构造函数的概念,让对象原型的写法更加清晰、更像面向对象编程的语法。
一、为什么要有class
在JS语言中,以前我们生成实例对象的方法是通过构造函数创建。
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.call= function () {
console.log(`我叫${this.name}, 今年${this.age}岁`);
};
var p1 = new Person('Tom', 18);
上面这种写法跟传统的面向对象语言(比如C++和Java)差异很大,很容易让新学习这门语言的程序员感到困惑。
因此ES6提供了更接近传统语言的写法,引入了class这个概念,作为对象的模板。通过class关键字,就可以直接定义类。
class Person {
}
var p2 = new Person();
上面就是class的基本语法。它的绝大部分功能我们都可以通过ES5的构造函数以及原型做到,class写法只是让对象原型的写法更加清晰,更接近面向对象编程的语法。
下面我们来讲讲class的常用方法以及如何去使用。
二、class的方法
constructor()
constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法,默认返回实例对象(即this)。一个类必须有constructor方法,如果没有手动定义,JS引擎会自动为它添加一个空的constructor方法。
class Person {
// 构造
constructor(name, age) {
this.name = name;
this.age = age;
}
}
var p3 = new Person('Tom', 18);
通过上面的案例我们可以看到,Person类可以通过constructor方法给this,也就是实例对象身上添加对应的属性,除了这种方法,我们也可以直接将这些属性定义在类的最外层:
class Person {
brand = "Tom";
price = 18;
// 构造
constructor() {}
}
var p4 = new Person();
通过这种方式定义出来的属性我们把它称为实例属性,我们可以直接将其定义在类的顶部,这样一眼就能看出来这个类有哪些实例属性。
实例方法
和ES5不同,类中的方法不需要加function关键字就可以直接生成,同时多个方法之间也不需要用逗号进行分隔,否则会报错,实例方法调用时同样可以传递参数。
class Person {
// 构造
constructor(name, age) {
this.name = name;
this.age = age;
}
call() {
console.log(`我叫${this.name}, 今年${this.age}岁`);
}
play(ball) {
console.log(`我爱玩${ball}`);
}
}
var p5 = new Person("Tom", 18);
p5.call(); // 我叫Tom, 今年18岁
p5.play("足球"); // 我爱玩足球
静态属性
实例对象身上有自身的属性,那class本身也会有自己的属性,也就是静态属性:
Person.prop = 1;
console.log(Person.prop) // 1
目前,只有这种写法可行,因为ES6明确规定,class内部只有静态方法,没有静态属性。
static静态方法
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就是class的静态方法。
class Person {
constructor() {}
call() {
console.log(`我是实例方法`);
}
static staticFn() {
console.log(`我是静态方法`,this);
}
}
var p6 = new Person("Tom", 18);
p6.call();
Person.staticFn();
p6.staticFn();
我们可以看到静态方法中的this指向的是类,而不是实例对象;
静态方法可以与非静态方法重名。实例与类调用时会调用对应的方法;
父类的静态方法,可以被子类继承。
extends 类的继承
class之间可以通过extends关键字实现继承(继承父类的所有属性和方法)。
// 父类
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
call() {
console.log(`我叫${this.name}, 今年${this.age}岁`);
}
play(ball) {
console.log(`我喜欢玩${ball}`);
}
}
// 子类
class Student extends Person {
constructor(name, age, score) {
super(name, age);
this.score = score;
}
// 重写父类的方法
call() {
console.log(
`我叫${this.name},今年${this.age}岁, 考了${this.score}分`
);
}
}
var s1 = new Student("Tom", 18, 99);
s1.play("篮球"); // 我喜欢玩篮球
s1.call(); // 我叫Tom,今年18岁, 考了99分
从上面的案例中我们可以看到,当子类中出现与父类同名的方法时,会将父类的方法进行重写,从而使得子类实例能获取到最新的结果。
super
从上一个继承案例中我们可以发现有一个super关键字,子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。
ES5的继承是先创造子类的实例对象this,再将父类的方法添加到this上Person.apply(this),和ES5的机制不同,ES6先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。父类身上的静态方法同样会被子类继承。
取值函数(getter)和存值函数(setter)
这两个方法其实就是对对象的属性进行方法的绑定,当对某一个属性进行获取时,就会执行getter,当对某一个属性进行设置时,则执行setter。
class Person {
constructor(score) {
this.score = score;
}
get myScore() {
console.log("分数被读取了");
return this.score;
}
set myScore(newval) {
console.log("分数被修改了");
this.score = newval;
}
}
// 实例化对象
let p7 = new Person(99);
console.log(p7.myScore);
p7.myScore = 100;
console.log(p7.myScore);
上面的类中,我们自定义了score的读写方法,当读取p7的score属性时,就会调用get myScore方法,并且函数的返回值就是我们想要的score值;当对score进行重新赋值时,就会调用set myScore方法,在方法内部就会对this.score进行修改,这里要注意setter一定要传入修改后的参数,不然是接收不到新的值的。
三、class注意事项
不能重复声明
class Person { }
class Person { }
// 或
let Person = class {}
class Start { }
以上两种写法都会报错:语法错误:“Person”已经被声明。
不能直接调用(必须使用new关键字)
class Person {
constructor() {}
}
console.log(Person());
以上会报错:类型错:没有“new”不能调用类构造函数Person。
不存在提升(存在暂时性死区)
类不存在变量提升,这一点与 ES5 完全不同。
console.log(new Person());
class Person {
constructor() {}
}
以上就会报错:引用错误:初始化前无法访问“Person”。
因此子类必须在父类声明之后定义,实例的声明也是一样。
四、class的实例
ES6 class生成类的实例的写法,与 ES5 完全一样,也是使用new命令。前面说过,如果忘记加上new,像函数那样调用class(),就将会报错。
类的属性和方法,除非直接定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
call() {
console.log(`我叫${this.name}, 今年${this.age}岁`);
}
}
var p8 = new Person("Tom", 18);
console.log(p8.hasOwnProperty("name")); // true
console.log(p8.hasOwnProperty("age")); // true
console.log(p8.hasOwnProperty("call")); // false
console.log(p8.__proto__.hasOwnProperty("call")); // true
上面代码中,name和age都是实例对象p8(this)自身的属性,所以hasOwnProperty方法返回true,而call是原型对象的属性(因为直接定义在Person类上),所以hasOwnProperty方法返回false。这些都与ES5保持一致。并且类的所有实例共享一个原型对象。
var p8 = new Person("Tom", 18);
var p9 = new Person("Jack", 22);
console.log(p8.__proto__ === p9.__proto__) // true
上面代码中,p8和p9都是Person的实例,它们的原型都是Person.prototype,所以__proto__属性是全等的。
这也意味着,可以通过实例的__proto__属性为class添加方法。
__proto__ 并不是语言本身的特性,虽然目前很多浏览器的JS引擎中都提供了这个私有属性,它本质上是一个内部属性,而不是一个正式的对外的 API,只是由于浏览器广泛支持,才被加入了 ES6。标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好认为这个属性是不存在的。所以不建议在生产中使用该属性,避免对环境产生依赖。生产环境中,我们可以使用 Object.getPrototypeOf() 方法来获取实例对象的原型,然后再来为原型添加方法/属性。
var p8 = new Person("Tom", 18);
var p9 = new Person("Jack", 22);
p8.__proto__.play = function (ball) {
console.log(`我喜欢玩${ball}`);
};
p8.play("足球"); // 我喜欢玩足球
p9.play("篮球"); // 我喜欢玩篮球
var p10 = new Person("Jerry", 20);
p10.play("乒乓球"); // 我喜欢玩乒乓球
上面代码在p8的原型上添加了一个play方法,由于p8的原型就是p9的原型,因此p9也可以调用这个方法。而且,此后新建的实例p10也可以调用这个方法。这意味着,使用实例的__proto__属性改写原型,必须相当谨慎,不推荐使用,因为这会改变class的初始定义方法,影响到所有实例。
总结
- class类是基于原型的继承的语法糖;
 - class的出现使得代码更加优雅,代码量减少;
 - class类能清晰的指定构造函数和抽象方法;
 - class类在声明时就可以设定属性和方法,不需要再往函数的原型中添加方法;
 - 使用class类时必须实例化;
 - 使用extends关键字实现继承。
 
相关推荐
- 如何设计一个优秀的电子商务产品详情页
 - 
        
加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...
 
- 怎么在JS中使用Ajax进行异步请求?
 - 
        
大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...
 
- 中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革
 - 
        
前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...
 
- 前端监控 SDK 开发分享_前端监控系统 开源
 - 
        
一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...
 
- Ajax 会被 fetch 取代吗?Axios 怎么办?
 - 
        
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...
 
- 前端面试题《AJAX》_前端面试ajax考点汇总
 - 
        
1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...
 
- Ajax 详细介绍_ajax
 - 
        
1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...
 
- 6款可替代dreamweaver的工具_替代powerdesigner的工具
 - 
        
dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...
 
- 我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊
 - 
        
接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...
 
- 福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光
 - 
        
时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...
 
- 2021年超详细的java学习路线总结—纯干货分享
 - 
        
本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...
 
- 不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!
 - 
        
Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...
 
- 2025 年 Python 爬虫四大前沿技术:从异步到 AI
 - 
        
作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...
 
- 最贱超级英雄《死侍》来了!_死侍超燃
 - 
        
死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...
 
- 停止javascript的ajax请求,取消axios请求,取消reactfetch请求
 - 
        
一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...
 
- 一周热门
 
- 最近发表
 
- 标签列表
 - 
- HTML 简介 (30)
 - HTML 响应式设计 (31)
 - HTML URL 编码 (32)
 - HTML Web 服务器 (31)
 - HTML 表单属性 (32)
 - HTML 音频 (31)
 - HTML5 支持 (33)
 - HTML API (36)
 - HTML 总结 (32)
 - HTML 全局属性 (32)
 - HTML 事件 (31)
 - HTML 画布 (32)
 - HTTP 方法 (30)
 - 键盘快捷键 (30)
 - CSS 语法 (35)
 - CSS 轮廓宽度 (31)
 - CSS 谷歌字体 (33)
 - CSS 链接 (31)
 - CSS 定位 (31)
 - CSS 图片库 (32)
 - CSS 图像精灵 (31)
 - SVG 文本 (32)
 - 时钟启动 (33)
 - HTML 游戏 (34)
 - JS Loop For (32)
 
 
