提示:
本文为JavaScript栏目:JavaScript高级系列——ES6新特性章节 第九章
JavaScript高级学习:ES6新特性09——ES6中类的使用
前言
本文讲解ES6中类的使用。
提示:以下是本篇文章正文内容,下面案例可供参考
ES6中类的使用
类的声明
ES5中类的声明与使用
function Student(name, age) {
this.name=name;
this.age=age;
this.show=function () {
console.log(this.name,this.age);
}
}
Student.prototype.sex="男";
Student.prototype.play=function () {
console.log(this.name+"正在玩游戏");
}
let stu=new Student("张三",18);
console.log(stu.name); //张三
console.log(stu.age); //18
console.log(stu.sex); //男
stu.show(); //张三 18
stu.play(); //张三正在玩游戏
ES6中类的声明与使用
class Stu{
constructor(name,age) {
this.name=name;
this.age=age;
this.show=function () {
console.log(this.name,this.age);
}
}
// 在类中直接声明属性表示原型属性,不能使用var或者let关键字
// 在类中直接声明方法表示原型方法,不能使用function关键字
play(){
console.log(this.name+"正在玩游戏");
}
}
let stu2=new Stu("李四",20);
console.log(stu2.name); //李四
console.log(stu2.age); //20
console.log(stu2.sex); //男
stu2.show(); //李四 20
stu2.play(); //李四正在玩游戏
ES6中类的声明与使用:class关键字
- JS中虽然引入了类的创建方式,但是JS中依旧是没有类的概念的。
- class关键字的这种用法只是ES5中构造函数和原型的替代方案。
- 下面代码底层编译的时候,会把这段代码自动改写为ES5的方式去运行
class Stu{
/*类的构造函数必须要有,如果没写,代码在编译的时候会自动加上*/
constructor(name,age) {
console.log("我是Stu的构造函数");
// 类中的this都表示该类的实例对象,this只能在类中的方法使用。
this.name=name;
this.age=age;
this.show=function () {
console.log(this.name,this.age);
}
}
// 在类中直接声明属性表示原型属性,不能使用var或者let关键字
sex="男";
// 在类中直接声明方法表示原型方法,不能使用function关键字
play(){
console.log(this.name+"正在玩游戏");
}
}
// 类的调用必须使用new关键字,在new关键字调用的时候,会自动执行constructor函数
let stu2=new Stu("李四",20);
console.log(stu2.name);
console.log(stu2.age);
console.log(stu2.sex);
stu2.show();
stu2.play();
创建一个类,没有显示的表示构造函数,编译时会自动加上。等价于下方的Book2
class Book{
}
class Book2 {
constructor() {
// 类的构造函数默认返回this,不用写
// 可以主动更改类的构造函数的返回值
return new Stu("张无忌 ",20);
}
}
let b1=new Book();
let b2=new Book2();
console.log(b1);
console.log(b2);
构造函数
创建一个类,没有显式的表示构造函数,编译时会自动加上。等价于下方的Book2
class Book{
}
class Book2{
constructor() {
/*类的构造函数默认返回this,不用写*/
/*可以主动更改类的构造函数的返回值*/
return new Stu("张无忌",20);
}
}
let b1=new Book();
let b2=new Book2();
console.log(b1);
console.log(b2);
ES6中设置set和get
变量或者函数前用#修饰,表示该属性为私有属性,则该属性只能在当前类的作用域中使用,超出则不能使用
class Student{
#_name;
#_age;
constructor() {
}
/*set函数必须传参,set函数其实创建新属性*/
set name(value){
this.#_name=value;
}
get name(){
return this.#_name;
}
set age(value){
if(value>120){
this.#_age=120;
}else if(value<0){
this.#_age=0;
}else{
this.#_age=value;
}
}
get age(){
return this.#_age;
}
show(){
console.log(this.name,this.age);
}
}
let stu=new Student("张三丰",18);
console.log(stu); //Student {#_name: undefined, #_age: undefined}
stu.name="彭祖";
stu.age=800;
stu.show(); //彭祖 120
console.log(stu.age); //120
// console.log(stu.#_age);//私有属性在类的作用域外面无法使用
类的表达式方式声明
表达式方式声明类
表达式方式声明类,此时这个类是无名类
let Student = class {
show(){
console.log("表达式class");
}
}
let stu=new Student();
stu.show();
表达式方式声明类,此时的类可以有名字
let Student2 = class Stu {
show(){
/*这里输出的Student2和Stu的结果是一样的*/
/*区别在于Stu只能在当前类的作用域中使用*/
/*Student2可以在任意位置使用*/
console.log(Student2);
console.log(Stu);
}
}
let stu2=new Student2();
stu2.show();
/*
class Stu {
show(){
console.log(Student2);
console.log(Stu);
class Stu {
show(){
console.log(Student2);
console.log(Stu);
*/
console.log(Student2);
/*
class Stu {
show(){
console.log(Student2);
console.log(Stu);
*/
// console.log(Stu); // Stu在类的外部使用会报错
自动执行的类
一般用于只用类创建一个对象的时候使用
let stu3=new class{
constructor(name,age) {
this.name=name;
this.age=age;
}
show(){
console.log(this.name,this.age);
}
}("张三",18);
stu3.show();//张三 18
类的作用域
类的作用域内使用的是严格模式,严格模式中没有window的概念。严格模式是NodeJs的概念
class Book {
constructor(name="JS从入门到放弃") {
this.name=name;
}
info() {
/*info函数在Book类中被调用,this指向Book类的实例对象*/
console.log(this); //Book类中的this是Book
// console.log(this.name); 报错
}
}
let book=new Book();
book.info(); //Book {name: "JS从入门到放弃", show: ƒ}
单独获取函数
let bookInfo=book.info;//bookInfo中的this是undefined
let bookInfo2=function () {
console.log(this); //this为window
// console.log(this.book);
}
bookInfo();//undefined
bookInfo2();//Window {window: Window, self: Window, document: document, name: "", location: Location, …}
info函数在Book类中被调用,this指向Book类的实例对象。
info函数如果在Book类外被单独赋值出去,那么this的值会变成undefined,info函数改为箭头函数可以解决这个问题。
class Book {
constructor(name="JS从入门到放弃") {
this.name=name;
}
info() {
console.log(this); //Book类中的this是Book
// console.log(this.name);
}
show=()=>{
console.log(this);
console.log(this.name);
}
}
let bookShow=book.show;
//Book {name: "JS从入门到放弃", show: ƒ}
book.show();//JS从入门到放弃
bookShow();//JS从入门到放弃
类的静态方法和实例方法
静态方法
class Dog{
static color="yellow";
static run(){
/*静态方法中的this表示的是类,不是类的实例*/
console.log(this);
console.log(this.color+"小狗正在奔跑");
}
}
console.log(Dog.color);//yellow
Dog.run(); //yellow小狗正在奔跑
/*
class Dog{
static color="yellow";
static run(){
/*静态方法中的this表示的是类,不是类的实例*/
console.log(this);
console.log(this.color+"小狗正在奔跑");
}
play(){…
*/
实例方法
class Dog{
static color="yellow";
static run(){
console.log(this);
console.log(this.color+"小狗正在奔跑");
}
play(){
/*实例方法中this表示的是当前类的实例*/
console.log(this);
}
constructor() {
/*实例属性/方法可以和静态属性/方法重名*/
this.color="red";
this.run=function () {
console.log(this.color+"正在奔跑");
}
}
}
let d=new Dog();
d.play();
/*
Dog {color: "red", run: ƒ}
*/
console.log(d.color); //red
d.run(); //red正在奔跑