• ES6 类的扩展


    类的声明:

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

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

    1. function MyClass(num){
    2. this.num = num;
    3. this.engines = false;
    4. }
    5. MyClass.prototype.start = function(){
    6. console.log("starting...");
    7. this.engines = true;
    8. };
    9. const myclass = new MyClass(1);
    10. myclass.start();

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

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

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

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

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

    1. class Clothes{
    2. constructor(color,size){
    3. this.size = size;
    4. this.color = color;
    5. }
    6. }
    7. const lan = new Clothes("蓝","L");
    8. const bai = new Clothes("白","XL");

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

    用class关键字改造MyClass函数

    1. function MyClass(num){
    2. this.num = num;
    3. this.engines = false;
    4. }
    5. MyClass.prototype.start = function(){
    6. console.log("starting...");
    7. this.engines = true;
    8. };
    9. const myclass = new MyClass(1);
    10. myclass.start();
    11. //
    12. class Myclass{
    13. constructor(num){
    14. this.num = num;
    15. this.engines = false;
    16. }
    17. start(){
    18. console.log("starting...");
    19. this.engines = true;
    20. }
    21. }
    22. const myclass = new MyClass(1);
    23. myclass.start();

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

    声明形式:function\class

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

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

    1. function Dog(name){
    2. this.name = name;
    3. }
    4. Dog.prototype.sayName = function(){
    5. console.log(this.name);
    6. };
    7. let dog = new Dog("柯基");
    8. dog.sayName();
    9. console.log(dog instanceof Dog);

    匿名类写法:

    1. let Dog = class{
    2. construcor(name){
    3. this.name = name;
    4. }
    5. sayName(){
    6. console.log(`${this.name}`);
    7. }
    8. };
    9. let dog = new Dog("柯基");
    10. dog.sayName();

    命名类表达式:

    1. let Dog = class MyClass{
    2. constructor(name){
    3. this.name = name;
    4. }
    5. sayName(){
    6. console.log(this.name);
    7. }
    8. };

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

    ES6中提供了继承关键字extends

    class child_class_name extends parent_class_name {}

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

    1. class Animal{
    2. constructor(name,age,apeed){
    3. this.name = name;
    4. this.age = age;
    5. this.speed = speed;
    6. }
    7. run(){
    8. console.log(`${this.name}🐕${this.age}岁了,跑了${this.speed}的速度`);}
    9. stop(){
    10. consle.log(`${this.name}停止了奔跑。`);
    11. }
    12. }
    13. class Dog extends Aniaml{}//Dog类继承了Animal类
    14. //实例化狗
    15. let dog = new Dog("柯基","1",5);
    16. dog.run();
    17. dog.stop();

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

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

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

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

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

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

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

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

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

    1. //Es5语句
    2. function Dog(name){
    3. this.name = name;
    4. }
    5. Dog.create = function(name){
    6. return new Dog(name);
    7. };
    8. Dog.prototype.sayName = function(){
    9. console.log(`${this.name}`);
    10. };
    11. let dog = Dog.create("柯基");
    12. dog.sayName();

    上述代码解析如下:

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

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

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

    1. static methodName(){
    2. }

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

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

    1. class MYClass{
    2. static method1(){
    3. this.method2();
    4. }
    5. static method2(){
    6. console.log("hello");
    7. }
    8. }
    9. let myClass = new MyClass();
    10. myclass.method2();

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

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

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

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

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

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

  • 相关阅读:
    linux 系统启动过程
    Oracle 19c OCP的1Z0-082-CHN、1Z0-083-CHN和1Z0-082、1Z0-083有什么不同
    如何写好github上的README
    二叉树题目:从前序与中序遍历序列构造二叉树
    vue 使用 lodash 防抖
    最新,2022年国自然立项数量统计出炉
    GoLang连接mysql数据库
    十二、Sequential
    打造高效医患沟通:陪诊小程序开发技术指南
    个人前端编程技巧总结
  • 原文地址:https://blog.csdn.net/weixin_74314406/article/details/136597757