class的基本语法

class Point{
  constructor(x, y){
     this.x = x;
     this.y = y;  
  }  

   tostring(){
      return '(' + this.x + ', ' + this.y + ')'; 
  }
}

在以上代码中,constructor就是构造方法,this关键字就代表实例对象。

类的数据类型实际上就是funtion,类本身就指向构造函数。

typeof Point === 'function' // true

Point === Point.prototype.constructor // true

创建实例对象时,也是使用new关键字。prototype原型对象,在class中也存在。class中的方法都是定义在prototype原型对象上的。

var  p = new Point();

class内部定义的方法,都是不可枚举的

Object.keys(Point.prototype) // []

constructor方法

是类的默认方法,当通过new创建实例时,都会默认调用该方法。每一个类都必须有一个constructor方法,如果没有显示定义,则会给其默认定义一个空的constructor方法。

class Point{
}
// 等同于
class Point{
  constructor(){}  
}

constructor默认返回实例对象,即this,也可以指定返回另一个对象

class Point{
  constructor(){
        return Object.create(null)
    }  
}
new Point() instanceof Point // false

类的实例

必须通过new关键字来创建类的实例,否则会报错。

和ES5一样,除非是显示定义在实例本身上的属性(即定义在this上的),其他的属性都是定义在实例的原型对象上(即定义在class上的)

class Point{
  constructor(x, y){
    this.x = x;
    this.y = y;
  }
  tostring(){
  return '(' + this.x + ', ' + this.y + ')';
}
}
var p = new Point(2, 3);

p.hasOwnProperty('x')// true
p.hasOwnProperty('y')// true
p.hasOwnProperty('tostring')// false
p.__proto__.hasOwnProperty('tostring')// true

与ES5一样,class的所有实例共享一个原型对象__proto__。通过一个实例更改了__proto__上面的属性或方法,通过其他实例获取__proto__上的属性或方法时也是更改后的值。所以使用__proto__时要慎重

取值函数和存值函数

与ES5一样,class内部也可以设置get和set方法来对设置属性和获取属性的操作进行拦截。存值函数和取值函数是设置在属性的 Descriptor 对象上的

属性表达式

类的属性名,可以采用表达式

let methodName = 'myMethod';
class Point{
  constructor(x, y){
       this.x = x;
       this.y = y;  
    }  
    [methodName](){}
}    

以上的Point类的方法名为myMethod

class表达式

class同样可以使用表达式定义

const myClass = class Me{
    getclassname(){
        return Me.name;
    }
} 

以上代码通过表达式定义了一个类,这个类的名称是Me,但是这个Me只能在类内部使用,在外部引用类只能使用myClass。如果类内部没有用到的话,可以省略Me。

可以通过这种方式创建立即执行类

let Person = new class{
            constructor(name){
                this.name = name;
            }
            getName(){
                console.log(this.name)
            }
        }('ashen')

注意点

  1. 严格模式:类内部默认是采用严格模式的
  2. 不存在提升。
  3. name属性。就是紧跟在class关键字后面的类名
  4. 如果类中某个方法是generator方法,那么这个方法默认返回一个该class类的遍历器,for...of..循环会自动调用这个遍历器
  5. 类内的this默认指向实例对象。但是如果将类内的方法单独提出来使用,this就会指向undefined,从而找不到该方法而报错。
    1. 可以通过在构造函数中绑定this解决
    2. 也可以通过使用箭头函数实现 
      constructor() {
          this.getThis = () => this;
        }

静态方法

类中定义方法时,如果带有关键字static,那么此方法是类的静态方法。只能被类调用,不能被类的实例对象调用。静态方法中的this指向class本身。

父类的静态方法,可以被子类继承。子类也可以通过super对象调用父类的静态方法

class father{
    static getTime(){
        return '12 点'
    }
}
class son extends father{
    static getTime(){
        return super.getTime() + ',too';
    }
}
son.getTime() // 12 点,too

实例属性的新写法

之前都把实例属性写在constructor函数中的this上,其实还可以定义在函数的顶层

class IncreasingCounter {
            _count = 0;
            get value() {
                console.log('Getting the current value!');
                return this._count;
            }
            increment() {
                this._count++;
            }
        }

在以上代码中,_count就是实例属性。其依然不存在于class的原型对象上

静态属性

在类外为类添加静态属性,这个属性是类的属性,不是实例的属性。

class Point{

}
Point.prop = 1; // 为Point类添加了一个静态属性prop

new.target属性

该属性一般在构造函数中使用,返回new命令作用于的那个构造函数。也可以用于判断实例是否是通过new命令创建的。

class内部使用new.target,返回的是class

当子类继承父类时,new.target会返回子类

posted @ 2020-04-17 16:37  ashen1999  阅读(271)  评论(0编辑  收藏  举报