Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ES6之class的基础用法和class的继承 #17

Open
heyushuo opened this issue Dec 27, 2019 · 0 comments
Open

ES6之class的基础用法和class的继承 #17

heyushuo opened this issue Dec 27, 2019 · 0 comments

Comments

@heyushuo
Copy link
Owner

一.class 的基础用法

1.ES6 引入 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。

class Point {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  toString() {
    console.log(this.name + this.age);
  }
}
// ES5实现ES6同样的效果
function Point(name, age) {
  this.name = name;
  this.age = age;
}
Point.prototype.toString = function() {
  console.log(this.name + this.age);
};
  • ES6 类的 constructor(构造方法)函数相当于 ES5 的构造函数
  • 定义“类”的方法的时候,前面不需要加上 function 这个关键字
  • 类的所有方法都定义在类的 prototype 属性上面。
  • 类内部定义的方法,它是不可枚举的。这一点与 ES5 的行为不一致(可以枚举的)。
// ES6
class Point {
  constructor(x, y) {
    // ...
  }
  toString() {
    // ...
  }
}
Object.keys(Point.prototype);
//[]   不可枚举的
ES6;
var Point = function(x, y) {
  // ...
};
Point.prototype.toString = function() {
  // ...
};
Object.keys(Point.prototype);
// ["toString"]   可以枚举的

2.constructor 方法

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

3.类的实例对象

生成类的实例对象的写法,与 ES5 完全一样,也是使用 new 命令

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

4.Class 表达式

const MyChild = class Child {
  toString() {
    console.log(Child.name); //name属性总是返回紧跟在class关键字后面的类名。
  }
};
//类的名字是MyChild而不是Child,Child只在Class内部代码可用
let mychild = new MyChild();
mychild.toString(); // Child
//如果函数内部用不到Child,也可以省略
const MyChild = class {
  // ...
};

5.Class 的静态方法

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

class Foo {
  static className() {
    console.log("heyushuo");
  }
}
Foo.className(); //heyushuo 不能通过实例调用会报错
// 注意,如果静态方法包含this关键字,这个this指的是类,而不是实例。
class Foo {
  static bar() {
    this.baz();
  }
  static baz() {
    console.log("hello");
  }
  baz() {
    console.log("world");
  }
}
Foo.bar(); // hello
// 1.静态方法bar调用了this.baz,这里的this指的是Foo类,而不是Foo的实例,等同于调用Foo.baz。
// 2.静态方法可以与非静态方法重名。
// 父类的静态方法,可以被子类继承。
class Foo {
  static classMethod() {
    return "hello";
  }
}
class Bar extends Foo {}
Bar.classMethod(); // 'hello'

二.类的继承

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

class Parent {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  toString() {
    console.log("年龄:" + this.age + "姓名:" + this.name);
  }
}
class Child extends Parent {
  constructor(name, age, height) {
    super(name, age); //调用父类的constructor(构造方法)
    this.height = height;
  }
  sayInfo() {
    super.toString(); // 调用父类的toString()
    console.log(`身高:${this.height}`);
  }
}
var person = new Child("heyushuo", 24, 180);
person.sayInfo(); //年龄:24姓名:heyushuo   身高:180
  • 通过 extends 关键字 Child 继承了 Parent 的说有的属性和方法
  • 子类必须在 constructor 方法中调用 super 方法,使子类获得自己的 this 对象,否则新建实例时会报错。
  • 在子类的构造函数中,只有调用 super 之后,才可以使用 this 关键字,否则会报错。

父类的静态方法,也会被子类继承。

// 父类的静态方法,也会被子类继承。
class A {
  static hello() {
    console.log("hello world");
  }
}
class B extends A {}
B.hello(); // hello world
// hello()是A类的静态方法,B继承A,也继承了A的静态方法。

2.super 关键字

super 关键字,既可以当做函数使用,也可以当做对象使用.

super 作为函数

  • super 作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次 super 函数。
  • super 虽然代表了父类 A 的构造函数,但是返回的是子类 B 的实例,即 super 内部的 this 指的是 B
  • super()只能用在子类的构造函数之中,用在其他地方就会报错。
class A {}
class B extends A {
  constructor() {
    super();
  }
}
// 注意, super虽然代表了父类A的构造函数, 但是返回的是子类B的实例,
//即super内部的this指的是B,因此super() 在这里相当于A.prototype.constructor.call(this)。

super 作为对象时

  • 在普通方法中指向父类的原型对象,在静态方法中指向父类
  • super 指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过 super 调用的。
  • 子类普通方法中通过 super 调用父类的方法时,方法内部的this 指向当前的子类实例。
  • super 作为对象,用在静态方法之中,这时super 将指向父类,在普通方法之中指向父类的原型对象

参考:

阮一峰 ES6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant