class可以理解为是一个语法糖,将js只能通过构造函数创建实例的方法进行了补充
构造函数:
- function Person ({ name, age=18 }) {
- this.name = name
- this.age = age
- }
- new Person({name: '张三'})
- class Person {
- constructor ({ name, age=18 }) {
- this.name = name
- this.age = age
- }
- }
- new Person({name: '张三'})
类的属性名可以动态设置
静态方法/属性,通过在属性和方法前添加static关键字,静态方法和属性不会被实例继承
静态方法里面的this指向的是类而不是实例,所以静态方法里面this === A
class定义实例的属性 直接" 属性名=属性值"
console.log(typeof class A {})
- class A {}
- console.log(A.prototype.constructor === A)
- class A {}
- var a = new A()
- console.log(a.constructor === A)
- class A {
- fn () {}
- toString() {}
- }
-
- var a = new A()
- console.log(a);
- class A {
- constructor () {
- this.name = 'a';
- this.fn = function() {};
- }
- fn1() {}
- }
- console.log(new A())
注意方法如果单独使用会报错,class内部是严格模式,所以 this 实际指向的是undefined
普通函数通过实例调用可调用:但是直接结构后调用,普通函数没有找到是谁调用就会报错 。将普通函数改为箭头函数后,箭头函数定义位置在class中,所以this表示当前类的实例的原型
- class Logger {
- printName(name = 'world') {
- console.log(this, 'this')
- this.print(`Hello ${name}`)
- }
- print(text) {
- console.log(text)
- }
- }
-
- // let logger = new Logger();
- // // 通过实例调用可以调用
- // logger.printName()
- let {printName} = new Logger();
- printName(); //没有找到谁调用会报错
- class Logger {
- printName = (name = 'world') => {
- // 类中方法的this指向当前class的实例
- console.log(this, 'this')
- this.print(`Hello ${name}`)
- }
- print = (text) => {
- console.log(text)
- }
- }
- let { printName } = new Logger();
- printName(); //没有找到谁调用会报错
分析:
注意:本身class上面定义的普通函数,是在实例的原型上,但是如果使用的是箭头函数,则当前属性和函数就在类的实例上面了
为什么还能箭头函数中printName还能打印出this?因为箭头函数定义本身没有this,所以它的this的位置指向的是当前实例
- class Logger {
- printName(name = 'world') {
- console.log(this, 'this')
- this.print(`Hello ${name}`)
- }
- print(text) {
- console.log(text)
- }
- }
-
- console.log(new Logger());
- class Logger {
- printName = (name = 'world') => {
- // 类中方法的this指向当前class的实例
- console.log(this, 'this')
- this.print(`Hello ${name}`)
- }
- print = (text) => {
- console.log(text)
- }
- }
- console.log(new Logger());
设置后就可以通过实例设置和获取值时触发这两个方法
- class A {
- get name() {
- return '1'
- }
- set name(value) {
- console.log('setter:' + value)
- }
- }
-
- var a = new A()
- console.log(a.name);
- a.name = "lmf"
- let methodName = 'test'
- class A {
- [methodName] () {
- console.log("test-----");
- }
- }
-
- var a = new A()
- a.test()
通过在属性和方法前添加static关键字,静态方法和属性不会被实例继承;静态方法和普通方法可以重名
- class A {
- static fn () {
- //静态方法的this指的是类,所以这里this.getValue() === A.getValue()
- this.getValue()
- console.log(this === A);//true
- }
- static getValue () {
- console.log('张三')
- }
- getValue() {
- console.log('李四')
- }
- }
-
- var a = new A()
- A.getValue()
- a.getValue()
- A.fn();//静态方法的this指的是类,所以这里this.getValue() === A.getValue()
- class A {
- a = 1
- b = 'SUCCESS'
- }
- class F {
- constructor (sMoney) {
- this.money = 100 + sMoney
- }
- fn () {}
- }
- //通过extends实现继承
- class S extends F{
- //子类中显示调用constructor时必须同时调用super()方法
- constructor (money) {
- // 在super调用前子类是没有this,如果使用会报错
- //子类调用super(money)会触发父类的constructor并将参数传过去
- super(money)
-
- }
- }
- console.log(new S(10))
- // 类在继承时属性会被直接添加到实例中,方法则保留在类的原型上
- console.log(S.prototype.__proto__ === F.prototype); //true