ES6 类的扩展

类的声明:

在 ES6 之前其实是不存在类的,因为 JavaScript 并不是一门基于类的语言,它使用函数来创建对象,并通过原型将它们关联在一起。

我们来看个 ES5 语法的近类结构,首先创建一个构造函数,然后定义另一个方法并赋值给构造函数的原型。

function MyClass(num){
    this.num = num;
    this.engines = false;
}
MyClass.prototype.start = function(){
console.log("starting...");
this.engines = true;
};
const myclass = new MyClass(1);
myclass.start();

MyClass 是一个构造函数创建了MyClass类型对象.

使用this声明并初始化MyClass 的属性num 和 engines

在原型中存储了一个可供所有实例调用的方法start

使用"new+"的构造方法实现创建实例对象myclass 最后调用start方法.

在ES6中提供了class创建方法:

class Clothes{
constructor(color,size){
    this.size = size;
    this.color = color;
    }
}
const lan = new Clothes("蓝","L");
const bai = new Clothes("白","XL");

在上面代码中 constructor 是类的构造函数,它是定义类的默认方法,当你使用 new 来创建对象实例化时,会自动调用该方法。如果没有在类中添加 constructor,也会默认有一个 constructor 方法,所以它在类中是必须有的。

用class关键字改造MyClass函数

function MyClass(num){
    this.num = num;
    this.engines = false;
}
MyClass.prototype.start = function(){
console.log("starting...");
this.engines = true;
};
const myclass = new MyClass(1);
myclass.start();

//
class Myclass{
    constructor(num){
    this.num = num;
    this.engines = false;
}
start(){
    console.log("starting...");
    this.engines = true;
    }
}
const myclass = new MyClass(1);
myclass.start();

类和函数有两种存在形式:

声明形式:function\class

表达式形式:const A = class{}

创建一个狗的类型(ES6写法)

function Dog(name){
    this.name = name;
}
Dog.prototype.sayName = function(){
    console.log(this.name);
};
let dog = new Dog("柯基");
dog.sayName();
console.log(dog instanceof Dog);

匿名类写法:

let Dog = class{
    construcor(name){
        this.name = name;
}
sayName(){
    console.log(`${this.name}`);
    }
};
let dog = new Dog("柯基");
dog.sayName();

命名类表达式:

let Dog = class MyClass{
    constructor(name){
        this.name = name;
}
sayName(){
    console.log(this.name);
    }
};

类可以在类表达式中命名类名,类名不能在类的外使用.

ES6中提供了继承关键字extends

class child_class_name extends parent_class_name {}

上面代码的意思是 child_class_name 类继承了 parent_class_name 类。

class Animal{
    constructor(name,age,apeed){
        this.name = name;
        this.age = age;
        this.speed = speed;
}
run(){
    console.log(`${this.name}🐕${this.age}岁了,跑了${this.speed}的速度`);}
stop(){
    consle.log(`${this.name}停止了奔跑。`);
    }
}
class Dog extends Aniaml{}//Dog类继承了Animal类
//实例化狗
let dog = new Dog("柯基","1",5);
dog.run();
dog.stop();

ES6 为我们提供了超级函数 super 我们的继承变得完整且具备可扩展性。

super.method(...)调用父级方法

super(...)调用父构造方法

在 JavaScript 中,继承类的构造函数和其他函数是有区别的。继承类的构造函数有一个特殊的内部属性 [[ConstructorKind]]:"derived"。通过该属性会影响 new 的执行:

  • 当一个普通(即没有父类的类)的构造函数运行时,它会创建一个空对象作为 this,然后继续运行。
  • 但是当子类的构造函数运行时,与上面说的不同,它将调用父构造函数来完成这项工作。

所以,继承类的构造函数必须调用 super() 才能执行其父类的构造函数,否则 this 不会创建对象。

这里会给大家介绍以下两种类的属性和方法:

  • 静态方法
  • 静态属性
  • 私有方法
  • 私有属性

静态方法:好处是不需要实例化,可以直接通过类名访问,不需要消耗资源反复创建

//Es5语句
function Dog(name){
    this.name = name;
}
Dog.create = function(name){
    return new Dog(name);
};
Dog.prototype.sayName = function(){
    console.log(`${this.name}`);
};
let dog = Dog.create("柯基");
dog.sayName();

上述代码解析如下:

  • 创建一个构造函数 DogType
  • 以“类名.方法名”的方式为其定义一个静态方法 create,该方法最终创建一个 DogType 实例。
  • 在其原型上添加 sayName 方法。
  • 使用“类名.方法名”的方式调用其静态方法 create 创建一个实例对象 dog
  • 使用 dog 调用 sayName 方法输出自我介绍的信息。

由于 create 方法可以直接通过类名去访问,不需在被实例化时创建,因而可以被认为是 DogType 类的一个静态方法。

在ES6中提供了static关键字定义静态方法.

static methodName(){
}

有一点需注意一下,如果静态方法中包含 this 关键字,这个 this 关键字指的是类,而不是实例。

没有创建实例化对象,直接用「类名.方法名」就可以访问该方法,这就是静态方法的特点了。除了这个特点外,静态方法不能被其实例调用,我们来试试。

class MYClass{
    static method1(){
        this.method2();
}
static method2(){
    console.log("hello");
    }
}
let myClass = new MyClass();
myclass.method2();

可以看到使用 myclass 实例对象调用 method2 静态方法会报错,则说明静态方法只能通过“类名.方法名”调用.

静态属性具有全局唯一性,静态属性只有一个值,任何一次修改都是全局性的影响。

当我们类中需要这么一个具有全局性的属性时,我们可以使用静态属性。

class Dog{
    static dogName = "柯基";
}
console.log(Dog.dogName);

在上面的代码中,我们使用 static 关键字给 Dog 类定义了一个名为 dogName 的静态属性。

静态方法和静态属性是可以被继承的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值