• js中的类class class源码


    class

    js中类的类型也是function

    class Person {}
    
    console.log(typeof Person);
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    constructor 构造器
    构造器中实例化的属性配置 是 私有属性

    class Person {
      constructor(name = 'zhangsan', age = '18') {
        this.name = name;
        this.age = age;
      }
    }
    
    console.log(typeof Person);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    原型上的方法 是公有方法 直接写在类中

    class Person {
      constructor(name = 'zhangsan', age = '18') {
        this.name = name;
        this.age = age;
      }
      say() {
        console.log(`my name is ${this.name} and age is ${this.age}`);
      }
    }
    
    console.log(new Person());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    类内部的方法是不可枚举的

    class Person {
      constructor(name = 'zhangsan', age = '18') {
        this.name = name;
        this.age = age;
      }
      say() {
        console.log(`my name is ${this.name} and age is ${this.age}`);
      }
      drink() {
        console.log('I can drink');
      }
      eat() {
        console.log('I can eat');
      }
    }
    
    console.log(Object.keys(Person.prototype));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述
    当我们什么都不指定 只有一个空的class new出来也不会报错 会自动加一个constructor在原型上

    class Person {}
    
    console.log(new Person());
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    js中的类与函数非常相似

    function Person() {}
    
    console.log(new Person() instanceof Person);
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    class Person {}
    
    console.log(new Person() instanceof Person);
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    class Person {
      constructor() {
        return Object.create(null);
      }
    }
    
    console.log(new Person() instanceof Person);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    当我们创建一个函数时 如果把它赋值给一个变量 那么函数名就无意义了

    此时test1是可以省略的

    let test = function test1() {};
    
    let test = function () {};
    
    • 1
    • 2
    • 3

    那对于类有没有这种特殊情况的

    let Person = class Person1 {
      say() {
        console.log(1);
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我们尝试省略Person1
    发现是可以的

    let Person = class {
      say() {
        console.log(1);
      }
    };
    
    console.log(new Person().say());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    必须通过new 的方式执行 class

    这个样子是会报错的

    let Person = class {
      say() {
        console.log(1);
      }
    }();
    
    console.log(Person.say());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    let person = new (class {
      say() {
        console.log(1);
      }
    })();
    
    console.log(person.say());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    let person = new (class {
      constructor(name = 'zhangsan', age = '18') {
        this.name = name;
        this.age = age;
      }
      say() {
        console.log(1);
      }
    })('lisi', '19');
    
    console.log(person);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    类不能提升
    不存在暂时性死区(TDZ)

    console.log(new Person());
    
    class Person {}
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    没有公有属性

    公有函数私有化
    方式一 symbol

    const eat = Symbol();
    class Person {
      constructor(name, age) {
        this.age = age;
        this.name = name;
      }
      say() {
        console.log(1);
      }
      [eat]() {
        console.log(2);
      }
    }
    
    console.log(new Person().say());
    console.log(new Person().eat());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述
    方式二

    class Person {
      constructor(name, age) {
        this.age = age;
        this.name = name;
      }
      say(baz) {
        children.call(this, baz);
      }
    }
    
    function children(baz) {
      return (this.baz = baz);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    static定义静态属性与静态方法
    通过当前的类调用 不通过实例调用

    class Person {
      static a = 1;
      static foo() {
        return 2;
      }
    }
    console.log(Person.a);
    console.log(Person.foo());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    对象的get set 与类的get set
    对象的get set 直接使用.运算符使用

    var obj = {
      get a() {
        console.log(1);
      },
      set a(value) {
        console.log(value);
      },
    };
    console.log(obj.a);
    obj.a = 3;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    类的get 与set需要new 实例化后使用

    class Person {
      get a() {
        console.log(1);
      }
      set a(value) {
        console.log(value);
      }
    }
    
    let person = new Person();
    console.log(person.a);
    person.a = 2;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    extends

    继承
    继承的是父级共有属性的默认值

    class Parent {
      constructor(name = 'zhangsan') {
        this.name = name;
      }
    }
    
    class Child extends Parent {}
    
    console.log(new Child());
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    静态属性不继承

    class Parent {
      constructor(name = 'zhangsan') {
        this.name = name;
      }
      say() {
        console.log(1);
      }
      static a() {
        console.log(2);
      }
    }
    
    class Child extends Parent {}
    
    console.log(new Child().a());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述
    派生类
    必须在派生类中this前 使用super改变this指向
    如果不用就会报错

    class Parent {
      constructor(name = 'zhangsan') {
        this.name = name;
      }
      say() {
        console.log(1);
      }
      static a() {
        console.log(2);
      }
    }
    
    class Child extends Parent {
      constructor(age = '19') {
        this.age = age;
      }
    }
    
    console.log(new Child().age);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    class Parent {
      constructor(name = 'zhangsan') {
        this.name = name;
      }
      say() {
        console.log(1);
      }
      static a() {
        console.log(2);
      }
    }
    
    class Child extends Parent {
      constructor(name = 'lisi', age = '19') {
        super(name);
        this.type = 'child';
        this.age = age;
      }
    }
    
    console.log(new Child()); 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    let proto = {
      y: 20,
      z: 40,
    };
    let obj = {
      x: 10,
      foo() {
        console.log(super.y);
      },
    };
    
    Object.setPrototypeOf(obj, proto);
    
    obj.foo();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    super
    1.在对象当中 指代对象的原型
    2.在静态方法中 指向自己的父类

    class源码

    类的写法

    class Person {
      constructor(name = 'zhangsan', age = '18') {
        this.name = name;
        this.age = age;
      }
      say() {
        console.log('hello word');
      }
      drink() {
        console.log('drink');
      }
      static eat() {
        console.log('eat');
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    源码转为es5

    'use strict';
    
    var _createClass = (function () {
      function defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
          var descriptor = props[i];
          descriptor.enumerable = descriptor.enumerable || false;
          descriptor.configurable = true;
          if ('value' in descriptor) descriptor.writable = true;
          Object.defineProperty(target, descriptor.key, descriptor);
        }
      }
      return function (Constructor, protoProps, staticProps) {
        if (protoProps) defineProperties(Constructor.prototype, protoProps);
        if (staticProps) defineProperties(Constructor, staticProps);
        return Constructor;
      };
    })();
    
    function _classCallCheck(instance, Constructor) {
      if (!(instance instanceof Constructor)) {
        throw new TypeError('Cannot call a class as a function');
      }
    }
    
    
    
    var Person = (function () {
      function Person() {
        var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'zhangsan';
        var age = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '18';
    
        _classCallCheck(this, Person);
    
        this.name = name;
        this.age = age;
      }
    
      _createClass(
        Person,
        [
          {
            key: 'say',
            value: function say() {
              console.log('hello word');
            },
          },
          {
            key: 'drink',
            value: function drink() {
              console.log('drink');
            },
          },
        ],
        [
          {
            key: 'eat',
            value: function eat() {
              console.log('eat');
            },
          },
        ]
      );
    
      return Person;
    })();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
  • 相关阅读:
    MyBatis-Plus多数据源dynamic-datasource解决多数据源Redis Key 重复问题
    每天一个设计模式之单例模式(六种写法)
    最全Java中高级面试题汇总,全会月薪3W起
    深入浅出排序算法之希尔排序
    rk3399-linux_v2.8 编译报错 lb config: unrecognized option ‘--debootstrap-options‘
    时序分解 | MATLAB实现RIME-VMD霜冰优化算法优化VMD变分模态分解信号分量可视化
    22-07-04 西安 尚好房-项目经验总结(01)
    Linux文件编程详解
    再出发感怀
    adjustText库解决深度学习、视觉模型matplotlib画散点图时由于标签非常多导致的重叠现象
  • 原文地址:https://blog.csdn.net/weixin_65402230/article/details/127443372