class 类的运用

类(Class)


在这里插入图片描述

类的语法

为什么引入Class?

为了方便原型和原型链的编程书写方式更加像面向对象的方式,使其JavaScript更加完善了构造函数

类与构造函数对比

// ES6以前的构造函数
function Person(name, age){
    this.name = name;
    this.age = age;
}

Person.prototype.eat = function(){
    return '('+ this.age + '岁的' + this.name +'正在吃饭...'+')';
}

var p1 = new Person('张三',3);
p1.eat();


// ES6的构造函数(类)
class Person{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }

    eat(){
        return '('+ this.age + '岁的' + this.name +'正在吃饭...'+')';
    }

}

let p2 = new Person('张三',3);
p1.eat();
  • 可以是类在某种意义上就是构造函数的升级版
  • constructor:指向的就是Person类的构造函数(就算你不写,JavaScript引擎也会自动添加一个空的)
  • 在Person类里面编写的方法就是相当于在Person类的原型上编写
  • 类的内部的所有定义的方法,都是不可枚举的
  • 类必须通过new关键字调用,否则会报错

回到顶部 目录

类的取值函数(getter)和存值函数(setter)

class MyClass {
  get name() {
    return 'getter';
  }
  set name(value) {
    console.log('setter: '+value);
  }
}

var descriptor = Object.getOwnPropertyDescriptor(
  CustomHTMLElement.prototype, "name"
);
  • 类的get和set和以前的构造函数的是一样的
  • 存值函数和取值函数是设置在属性的 Descriptor 对象上的

类的奇葩写法(直接法)

// 1.
const MyClass = class My {
    getClassName() {
        return My.name;
    }
};

let my = new MyClass();

// 2.
const person  = new class My {
    getClassName() {
        return My.name;
    }
};
person.getClassName();
  • 外部调用用MyClass类名,内部调用用My类名

类注意点

  • 类的内部默认就是严格模式use strict
  • 类不存在声明提前,有临时性死区
  • this指向会随着调用者改变的

回到顶部 目录

静态方法和静态属性

语法:static 方法/属性

class Person{
    static a = 20;

    static fn(){
        return 'hello';
    }
}

Person.fn();
Person.a;
  • 静态方法/属性的调用:静态方法是写着原型上面的,但是不能被继承
    调用是直接调用:Person.fn();/Person.a;
  • 静态方法的this:指向类
  • 静态方法可以和非静态方法重名
  • 静态方法可以在子类的super对象中调用

私有方法和私有属性

私有方法和私有属性:只能在内部访问,外部不能访问。遗憾的是es6没有面向对象中的私有方法和私有属性

  • 第一种方法:在编程界内部人为规定一个,私有的用"_"开头
  • 第二种方法:Symbol数据类型(但是Reflect.ownKeys可以查看)
    const a = Symbol('a');
    const b = Symbol('b');
    
    class myClass{
        
        // 公有方法
        foo(baz) {
            this[a](baz);
        }
    
        // 私有方法
        [a](baz) {
            return this[b] = baz;
        }
    
    };
    
    var c = new myClass();
    Reflect.ownKeys(myClass.prototype)
    
  • 第三种方法:#前缀代表私有属性(还没有出来)

回到顶部 目录

保证构造函数是通过new调用的

ES6为new命令引入了一个new.target属性,该属性一般用在构造函数之中,返回new命令作用于的那个构造函数

如果构造函数不是通过new命令或Reflect.construct()调用的,new.target会返回undefined

function Person(name) {
    if (new.target === Person) {
        this.name = name;
    } else {
        throw new Error('必须使用 new 命令生成实例');
    }
}

该方法也可以判断类,毕竟二者区别不大

修饰

  • 类修饰:target(类本身)
  • 方法修饰:
    1. target(类的原型对象)
    2. name(修饰的属性名)
    3. descriptor(该属性的描述对象)

回到顶部 目录

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值