ES6语法之 Class

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/TDCQZD/article/details/82390749

一、基本介绍

1、Class
JavaScript 语言中,生成实例对象的传统方法是通过构造函数。例如:

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

Point.prototype.toString = function () {
        return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);

这种写法跟传统的面向对象语言差异很大。于是ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

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

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

ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。constructor方法相当于是之前的Point方法。

2、注意事项
定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。

Point类除了构造方法,还定义了一个toString方法。这个toString方法相对于被绑到了Point的原型上。
问题:
(Point的原型?Point不是一个类吗?为什么会有原型?)
typeof Point // “function” 说白了Point就是一个函数 只是套了一个类的壳

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

二、 constructor

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

当然返回的对象是可以显示指定的。

类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。

三、实例对象

生成类的实例对象使用的是new命令。如果忘记加上new,像函数那样
Class,将会报错。

class Point {
  // ...
}
// 报错 var point = Point(2, 3);
// 正确 var point = new Point(2, 3);

四、 静态方法

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

如果静态方法包含this关键字,这个this指的是类,而不是实例

class Foo {
  static classMethod() {
    return 'hello';
  }
}
Foo.classMethod() 
var foo = new Foo(); // 'hello'
foo.classMethod()  // TypeError: foo.classMethod is not a function

五、 getter&setter

与 ES5 一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

class MyClass {
  constructor() {
    // ...
  }
  get prop() {
    return 'getter';
  }
  set prop(value) {
    console.log('setter: '+value);
  }
}
let inst = new MyClass();
inst.prop = 123; // setter: 123
inst.prop //getter

注意:一般绑定属性使用constructor,除非 绑定get&set式属性。

六、 静态属性&实例属性(成员属性)

静态属性指的是 Class 本身的属性。目前,只有以下写法可行,因为 ES6 明确规定,Class 内部只有静态方法,没有静态属性。

class Foo {}
Foo.prop = 1;

提案(现在未实现)
类的实例属性可以用等式,写入类的定义之中

class MyClass {
  myProp = 42;
  constructor() {
    console.log(this.myProp); // 42
  }
}

类的静态属性只要在上面的实例属性写法前面,加上static关键字就可以了

class MyClass {
      static myStaticProp = 42;

      constructor() {
        console.log(MyClass.myStaticProp); // 42
      }
}

注意:静态方法给对象显示原型,实例方法给对象本身

七、 继承

1、基本介绍
Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

class Point {}
class ColorPoint extends Point {}

2、 super

super这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。
第一种情况,super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。Super在调用时内部的this指的是子类。

第二种情况,super作为对象时,在普通方法中,指向父类的显示原型对象;在静态方法中,指向父类。

3、 Object.getPrototypeOf
Object.getPrototypeOf方法可以用来从子类上获取父类。

Object.getPrototypeOf(Son) === Father   // true

因此,可以使用这个方法判断,一个类是否继承了另一个类

4、 注意事项

  • 1.父类的静态方法,会被子类继承
  • 2.子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。
  • 3.super函数必须在constructor中被顶行调用
  • 4.子类中没有constructor时
    默认: constructor() {super()}

5、代码示例:

<script>
    class Father {
        constructor(name,age) {
            this.name=name;
            this.age = age;
        }
        //静态方法可以被继承
        static DAMU(){
           console.log("damu");
        }
    }

    class Son extends Father{
        //不写默认有
        /*constructor(){
            super() //一定要顶行  先等父类的构造器调完才能实例化子类
        }*/
    }
    var son = new Son();
    console.log(Son,son);
    Father.DAMU();
    Son.DAMU();
</script>

八、使用细节和注意事项

1、不存在提升
类不存在提升(hoist),这一点与 ES5 完全不同。

new Foo(); // ReferenceError
class Foo {}

猜你喜欢

转载自blog.csdn.net/TDCQZD/article/details/82390749