这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战
ES6 的 class 可以看作一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
一、ES6 中的类与 ES5 中的类
1.1 constructor
ES6 中:
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
return 'hello, I am ' + this.name;
}
}
var kevin = new Person('Kevin');
kevin.sayHello(); // hello, I am Kevin
ES5 中:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function () {
return 'hello, I am ' + this.name;
};
var kevin = new Person('Kevin');
kevin.sayHello(); // hello, I am Kevin
我们可以看到 ES5 的构造函数 Person,对应 ES6 的 Person 类的 constructor 方法。
注意:ES6 类的内部所有定义的方法,都是不可枚举的(non-enumerable)
在 ES6 中:
Object.keys(Person.prototype); // []
Object.getOwnPropertyNames(Person.prototype); // ["constructor", "sayHello"]
在 ES5 中:
Object.keys(Person.prototype); // ['sayHello']
Object.getOwnPropertyNames(Person.prototype); // ["constructor", "sayHello"]
1.2 实例属性
在 ES6 中,以前我们定义实例属性,只能写在类的 constructor 方法里面。比如:
class Person {
constructor() {
this.state = {
count: 0
};
}
}
然而现在有一个提案,对实例属性和静态属性都规定了新的写法,而且 Babel 已经支持。现在我们可以写成:
class Person {
state = {
count: 0
};
}
在 ES5 中:
function Person() {
this.state = {
count: 0
};
}
1.3 静态方法
所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上 static 关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为静态方法。
在 ES6 中:
class Person {
static sayHello() {
return 'hello';
}
}
Person.sayHello() // 'hello'
var kevin = new Person();
kevin.sayHello(); // TypeError: kevin.sayHello is not a function
在 ES5 中:
function Person() {}
Person.sayHello = function() {
return 'hello';
};
Person.sayHello(); // 'hello'
var kevin = new Person();
kevin.sayHello(); // TypeError: kevin.sayHello is not a function
1.4 静态属性
静态属性指的是 Class 本身的属性,即
Class.propName,而不是定义在实例对象(this)上的属性。
在 ES6 中,以前我们添加静态属性只可以这样:
class Person {}
Person.name = 'kevin';
因为上面提到的提案,现在可以写成:
class Person {
static name = 'kevin';
}
在 ES5 中:
function Person() {};
Person.name = 'kevin';
1.5 new
注意:类必须使用 new 调用,否则会报错。普通构造函数不用 new 也可以执行。
class Person {}
Person(); // TypeError: Class constructor Foo cannot be invoked without 'new'
1.6 getter 和 setter
在 ES6 中与 ES5 一样,在类的内部可以使用 get 和 set 关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。
class Person {
get name() {
return 'kevin';
}
set name(newName) {
console.log('new name 为:' + newName)
}
}
let person = new Person();
person.name = 'daisy';
// new name 为:daisy
console.log(person.name);
// kevin
在 ES5 中:
function Person(name) {}
Person.prototype = {
get name() {
return 'kevin';
},
set name(newName) {
console.log('new name 为:' + newName)
}
}
let person = new Person();
person.name = 'daisy';
// new name 为:daisy
console.log(person.name);
// kevin