ES6的class及深入理解(constrctor,static)

class的基本语法

class 声明创建一个基于原型继承的具有给定名称的新类。
ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

class Polygon {
  constructor(height, width) {
    this.area = height * width;
  }
}

console.log(new Polygon(4, 3).area);
// expected output: 12

和类表达式一样,类声明体在严格模式下运行。构造函数是可选的。

类声明不可以提升(这与函数声明不同)。

和ES5的写法对比

在这里插入图片描述
在这里插入图片描述
ES6 的class与ES5写法的几个核心注意点:

  • ES5 的构造函数Point,对应 ES6 的Point类的构造方法。
  • 类的所有方法都定义在类的prototype属性上面。
  • 定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了
  • 方法之间不需要逗号分隔,加了会报错
  • ES6的class使用方法与ES5的构造函数一模一样

在类的实例上面调用方法,其实就是调用原型上的方法。
在这里插入图片描述

上面代码表明,类的数据类型就是函数,类本身就指向构造函数。
在这里插入图片描述

类的内部所有定义的方法,都是不可枚举的
(non-enumerable)。

class Point{
    constructor(x,y){

    }
    fn(){

    }
}

console.log(Object.getOwnPropertyNames(Point.prototype));//(2) ["constructor", "fn"]


console.log(Object.keys(Point.prototype));//[]

通过Object.assign方法往类的原型上添加的方法,
constructor不可枚举, 其他的可以枚举

在这里插入图片描述

class的constructor()

constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象

class Ep{
    
}

const c = new Ep()

console.log(c);
console.log(c instanceof Ep); //true

class Ep{
    constructor(){
        return {}
    }
}

const c = new Ep()

console.log(c);//{}
console.log(c instanceof Ep); //false

得是在创造class时就定义设置的, 在创造完class后,通过Object.assign的方式是没法改变构造函数的返回值的
在这里插入图片描述

class的唯一调用方式

类必须使用new调用,否则会报错。
在这里插入图片描述

class的get和set


class MyClass{
    get myAtribute(){
        return 'getter'
    }
    set myAtribute(value){
        console.log(`setter:${value}`);
    }
}

const a = new MyClass() //setter:5

a.myAtribute = 5

console.log(a.myAtribute); //getter

上面代码中, attribute属性有对应的存值函数和取值函数, 因此赋值和读取行为都被自定义了。
存值函数和取值函数是设置在属性的 descriptor 对象上的。

上面的写法等价于

在这里插入图片描述

表达式表示法

类的属性名,可以采用表达式
在这里插入图片描述

class表达式
在这里插入图片描述
上面代码使用表达式定义了一个类。需要注意的是,这个类的名字是Me,但是Me只在 Class 的内部可用,指代当前类。在 Class 外部,这个类只能用MyClass引用。

如果类的内部没用到的话,可以省略Me,

一些注意事项

1,类和模块的内部,默认就是严格模式

2,不存在提升在这里插入图片描述
上面代码中,Foo类使用在前,定义在后,这样会报错,因为 ES6 不会把类的声明提升到代码头部。

name 属性
在这里插入图片描述
由于本质上,ES6 的类只是 ES5 的构造函数的一层包装,所以函数的许多特性都被Class继承,包括name属性。

在这里插入图片描述

printName方法中的this,默认指向Logger类的实例。但是,如果将这个方法提取出来单独使用,this会指向该方法运行时所在的环境(由于 class 内部是严格模式,所以 this 实际指向的是undefined),从而导致找不到print方法而报错。

怎么解决这个问题

一个比较简单的解决方法是,在构造方法中绑定this,这样就不会找不到print方法了。

在这里插入图片描述

bind之后返回的函数里面的this就永久锁死了

另一种解决方法是使用箭头函数。

在这里插入图片描述

箭头函数位于构造函数内部,它的定义生效的时候,是在构造函数执行的时候。这时,箭头函数所在的运行环境,肯定是实例对象,所以this会总是指向实例对象。

class的属性的定义方式

属性既可以 定义在构造函数里面 也可以定义在构造函数外面

在这里插入图片描述

class的静态属性和方法

类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
注意,如果静态方法包含this关键字,这个this指的是类,而不是实例。静态方法可以与非静态方法重名。

class Coder{
    static coding(){
        console.log(this);
        return '我会敲代码'
    }

    coding(){
        return '正在学习class语法'
    }
}

console.log(Coder.coding()); //我会敲代码

const xiao_hong = new Coder()
console.log(xiao_hong.coding());

在这里插入图片描述

父类的静态方法,可以被子类继承

在这里插入图片描述

静态方法也是可以从super对象上调用的。
在这里插入图片描述

静态属性指的是 Class 本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性。
在这里插入图片描述
目前,只有这种写法可行,因为 ES6 明确规定,Class 内部只有静态方法,没有静态属性

怎么实现class的私有方法和属性

私有方法和私有属性:是只能在类的内部访问的方法和属性,外部不能访问。
这是常见需求,有利于代码的封装,但 ES6 不提供,只能通过变通方法模拟实现。

在这里插入图片描述
方法是利用Symbol值的唯一性,将私有方法的名字命名为一个Symbol值。

new.target属性

ES6 为new命令引入了一个new.target属性,该属性一般用在构造函数之中,返回new命令作用于的那个构造函数。如果构造函数不是通过new命令调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用的。

在这里插入图片描述

Class 内部调用new.target,返回当前 Class。

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值