Class的基本语法
简介和基本用法
基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已.
- 语法对比1
es5写法
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 Point {
constructor(x,y){
this.x = x;
this.y = y;
}
toString(){
return '('+this.x+','+this.y+')';
}
}
- 语法对比2
class Point {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
// 等同于
Point.prototype = {
constructor() {},
toString() {},
toValue() {},
};
静态方法 static
1.类相当于实例的原型,所有在类中定义的方法,都会被实例继承。
2.加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod() //报错:TypeError: foo.classMethod is not a function
- 注意,如果静态方法包含this关键字,这个this指的是类,而不是实例。
- 虽然既然类的静态方法不可被实例所继承,但是却可以被子类继承。
class Foo {
static bar() {
this.baz();
}
static baz() {
console.log('hello');
}
baz() {
console.log('world');
}
}
Foo.bar() // hello
class继承
Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
- 子类必须在constructor方法中调用super方法,否则新建实例时会报错。
class Cat{
constructor(name){
this.name = name;
}
run(){return 'catrun'}
}
// 重点看这个
class Dog extends Cat{ //狗继承猫
constructor(name){
super(name);// 继承属性
}
run (){return 'dogrun'}
sport(){
return this.name + ' ' + super.run();//继承的方法使用
}
}
//输出:小明 catrun
- 父类的静态方法,也会被子类继承
class A {
static hello() {
console.log('hello world');
}
}
class B extends A {
}
B.hello() // hello world
类的prototype属性和_proto_属性
大多数浏览器的ES5实现中,每一个对象都有一个_prop_属性,指向相应的构造函数的prototype属性。
Class作为构造函数的语法糖,同时有prototype属性和_prop_属性,因此同时存在两条继承链。
- 子类的_prop_属性,表示构造函数的继承,总是指向父类。
- 子类prototype属性的_prop_属性,表示方法的继承,总是指向父类的prototype属性。
class A {
}
class B extends A {
}
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true