• ES6 Class和Class继承


    1.class的基本语法

    class可以理解为是一个语法糖将js只能通过构造函数创建实例的方法进行了补充

    构造函数:

    1. function Person ({ name, age=18 }) {
    2. this.name = name
    3. this.age = age
    4. }
    5. new Person({name: '张三'})

    Class类

    1. class Person {
    2. constructor ({ name, age=18 }) {
    3. this.name = name
    4. this.age = age
    5. }
    6. }
    7. new Person({name: '张三'})

    2.深入了解class的特性

    • class的数据类型是一个函数
    • class的原型的constructor指向class
    • 通过new关键字创建出来的实例的constructor指向class
    • class内部的方法是定义在实例的原型上,class内部的属性和constructor里面的方法和属性定义在实例上(构造函数方法定义在实例的原型上,属性定义在实例上 )
    • 通过类创建对象的本质是调用类的constructor,如果类未定义constructor,则会在使用时默认添加。
    • class不能直接调用,需要通过new关键字(构造函数可以直接调用,也可以new 创建实例)
    • class内部方法this指向的是实例,class内部是严格模式(严格模式下不存在变量提升)
    • class中箭头函数的this和普通函数的指向不同:class上面定义的普通函数是在实例的原型上箭头函数this指向定义位置所在的作用域即实例本身,通过解构出来的方法直接调用普通函数的this是undefined,箭头函数是当前实例
    • class可以有取值函数(getter)和存值函数(setter)
    • 类的属性名可以动态设置

    • 静态方法/属性,通过在属性和方法前添加static关键字,静态方法和属性不会被实例继承

    • 静态方法里面的this指向的是类而不是实例,所以静态方法里面this === A

    • class定义实例的属性 直接" 属性名=属性值"

    1. class的数据类型是一个函数

      console.log(typeof class A {})

    2. class的原型的constructor指向class(类比:构造函数的原型的constructor指向构造函数)

    1. class A {}
    2. console.log(A.prototype.constructor === A)

    3. 通过 new 关键字创建出的实例的constructor指向该class(类比:new构造函数创建的实例的constructor指向构造函数本身)

    1. class A {}
    2. var a = new A()
    3. console.log(a.constructor === A)

    4. class内部的方法实际上都是定义在类实例的prototype上;属性定义在实例上;constructor中的方法和实例都定义在原型上

    1. class A {
    2. fn () {}
    3. toString() {}
    4. }
    5. var a = new A()
    6. console.log(a);

     

    5. 通过类创建对象的本质是调用类的constructor,如果类未定义constructor,则会在使用时默认添加。

    1. class A {
    2. constructor () {
    3. this.name = 'a';
    4. this.fn = function() {};
    5. }
    6. fn1() {}
    7. }
    8. console.log(new A())

    6. class不能直接调用,需要通过new关键字(构造函数可以直接调用,也可以new 创建实例)

    7. class内部方法this指向的是实例,class内部是严格模式(严格模式下不存在变量提升)

    注意方法如果单独使用会报错,class内部是严格模式,所以 this 实际指向的是undefined

    普通函数通过实例调用可调用:但是直接结构后调用,普通函数没有找到是谁调用就会报错 。将普通函数改为箭头函数后,箭头函数定义位置在class中,所以this表示当前类的实例的原型

    1. class Logger {
    2. printName(name = 'world') {
    3. console.log(this, 'this')
    4. this.print(`Hello ${name}`)
    5. }
    6. print(text) {
    7. console.log(text)
    8. }
    9. }
    10. // let logger = new Logger();
    11. // // 通过实例调用可以调用
    12. // logger.printName()
    13. let {printName} = new Logger();
    14. printName(); //没有找到谁调用会报错
    1. class Logger {
    2. printName = (name = 'world') => {
    3. // 类中方法的this指向当前class的实例
    4. console.log(this, 'this')
    5. this.print(`Hello ${name}`)
    6. }
    7. print = (text) => {
    8. console.log(text)
    9. }
    10. }
    11. let { printName } = new Logger();
    12. printName(); //没有找到谁调用会报错

    分析:

    • 1.this 实际指向的是undefined,如果想要可以正常调用,可以使用箭头函数(箭头函数的this是由定义位置决定,所以就能获取到this为当前实例)

    注意:本身class上面定义的普通函数,是在实例的原型上,但是如果使用的是箭头函数,则当前属性和函数就在类的实例上面了

    为什么还能箭头函数中printName还能打印出this?因为箭头函数定义本身没有this,所以它的this的位置指向的是当前实例

    • 2.this 实际指向的是undefined,在constructor中对printName进行bind改写this

    8.class中箭头函数的this和普通函数的指向不同:class上面定义的普通函数是在实例的原型上箭头函数this指向定义位置所在的作用域即实例本身,通过解构出来的方法直接调用普通函数的this是undefined,箭头函数是当前实例

    1. class Logger {
    2. printName(name = 'world') {
    3. console.log(this, 'this')
    4. this.print(`Hello ${name}`)
    5. }
    6. print(text) {
    7. console.log(text)
    8. }
    9. }
    10. console.log(new Logger());

    1. class Logger {
    2. printName = (name = 'world') => {
    3. // 类中方法的this指向当前class的实例
    4. console.log(this, 'this')
    5. this.print(`Hello ${name}`)
    6. }
    7. print = (text) => {
    8. console.log(text)
    9. }
    10. }
    11. console.log(new Logger());

     

    3.构造函数与class的区别?结合上面的几个特性回答

    • class只能通过new关键字调用
    • class内部是严格模式(直接解构出方法执行this会返回undefined)
    • class里面定义的方法和属性都在实例的原型上,constructor里面定义的属性和方法才在实例上;构造函数方法定义在实例的原型上,属性定义在实例上
    • class可以通过static关键字来定义静态方法

    4.class的取值函数(getter)和存值函数(setter)

    设置后就可以通过实例设置和获取值时触发这两个方法

    1. class A {
    2. get name() {
    3. return '1'
    4. }
    5. set name(value) {
    6. console.log('setter:' + value)
    7. }
    8. }
    9. var a = new A()
    10. console.log(a.name);
    11. a.name = "lmf"

    5.类的属性名可以动态设置

    1. let methodName = 'test'
    2. class A {
    3. [methodName] () {
    4. console.log("test-----");
    5. }
    6. }
    7. var a = new A()
    8. a.test()

    6.静态方法/属性

    通过在属性和方法前添加static关键字,静态方法和属性不会被实例继承;静态方法和普通方法可以重名

    1. class A {
    2. static fn () {
    3. //静态方法的this指的是类,所以这里this.getValue() === A.getValue()
    4. this.getValue()
    5. console.log(this === A);//true
    6. }
    7. static getValue () {
    8. console.log('张三')
    9. }
    10. getValue() {
    11. console.log('李四')
    12. }
    13. }
    14. var a = new A()
    15. A.getValue()
    16. a.getValue()
    17. A.fn();//静态方法的this指的是类,所以这里this.getValue() === A.getValue()

    7.静态方法里面的this指向的是类而不是实例

    8.定义实例的属性

    1. class A {
    2. a = 1
    3. b = 'SUCCESS'
    4. }

    9. 类的继承

    • 类的继承通过extends关键字
    • 子类中的constructor不写时会隐式生成一个constructor函数,如果显示写了constructor则必须调用super,否则就会报错。
    • 子类调用super会触发父类的constructor并将参数传递过去
    • 在super调用前子类是没有this,如果使用会报错
    • 类在继承时属性会被直接添加到实例中,方法则保留在类的原型上(跟类本身属性和方法的位置一样,类本身方法在原型上,属性在实例上,constructor中的方法和属性在实例上)
    1. class F {
    2. constructor (sMoney) {
    3. this.money = 100 + sMoney
    4. }
    5. fn () {}
    6. }
    7. //通过extends实现继承
    8. class S extends F{
    9. //子类中显示调用constructor时必须同时调用super()方法
    10. constructor (money) {
    11. // 在super调用前子类是没有this,如果使用会报错
    12. //子类调用super(money)会触发父类的constructor并将参数传过去
    13. super(money)
    14. }
    15. }
    16. console.log(new S(10))
    17. // 类在继承时属性会被直接添加到实例中,方法则保留在类的原型上
    18. console.log(S.prototype.__proto__ === F.prototype); //true

  • 相关阅读:
    Linux网络编程——IO多路复用
    Markdown和PlantUML的基本使用
    mapboxgl加载tiff
    Cobalt Strike(三)DNS bacon 的使用与原理
    白盒测试之语句覆盖、判定覆盖、条件覆盖等
    #816 Div2E. Long Way Home 斜率优化dp
    基于控制性能指标的重放攻击编码检测方案
    零售数据分析师熬夜整理:人、货、场、供、财这样做
    微信小程序-入门
    论文的三种状态
  • 原文地址:https://blog.csdn.net/qq_34569497/article/details/133922824