function Parent(job){
this.job = job
}
Parent.prototype.showJob = function(){
alert(this.job);
}
var p = new Parent('teacher');
通过class关键字的语法糖,es6的写法为
class Parent {
constructor(job){
this.job = job;
}
showJob(){
alert(this.job)
}
fn1(){ }
fn2(){ }
...
}
constructor方法对应我们原来的构造函数,而showJob方法直接定义在了Parent构造函数的原型上,注意:这里的定义不需要加上function关键字,方法之间也不需要逗号(加上逗号会报错)。那么我们对es6的写法进行测试
typeof Parent // 'function'
Parent === Parent.prototype.constructor
与es5构造函数的行为基本一致,但是有一个隐藏的比较大的区别:
function Parent1(){ this.job = 'teacher' }
class Parent2(){
constructor(){
this.job = 'teacher';
}
}
Parent1() // undefined
Parent2() // 报错,只能通过new关键字来调用
而且,class不存在覆盖声明
class Parent {
}
...
class Parent{
}
//覆盖声明这个类会报错
不存在变量提升
var p = new Parent(); // 报错
class Parent{
}
在class中定义的方法不可枚举
Object.keys(Parent.prototype) // []
//这时候我们通过es5语法添加一个原形上的方法
Parent.prototype.toString = function(){ }
Object.keys(Parent.prototype) // ["toString"]
这虽然有点尴尬,但实际开发中我们一般不会需要去枚举原形上的方法
我们可以在class中使用Object.assign(ie不支持)来一次性添加许多方法
class Parent(){
...
Object.assign(Parent.prototype,{
showJob(){ },
toString(){ }
})
}
constructor方法的返回值是实例对象(this),可以指定返回另一个对象
class Parent {
constructor(){
return { }
}
}
var p = new Parent();
p instanceof Parent // false
当然确实没必要在constructor中返回其他对象,如果不写constructor,默认只返回一个实例对象,只是对象上的属性没有在构造中定义而已。
在继承中,constructor一定要写上super()
class Parent {
constructor(){
this.job = 'teacher'
}
}
class Child extends Parent{
constructor(){
super();
}
}
var child = new Child()
child.job // 'teacher'
es6的class还是没有提供私有方法的接口,只能曲线救国,将方法移出构造函数,使用call来调用
class Parent{
constructor(){
this.job = 'teacher';
}
showJob(){
_showJob.call(this);
}
}
function _showJob(){
alert(this.job);
}
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”
class Parent {
constructor(){
this.job = 'teacher';
}
static showJob() {
alert(this.job);
}
static showOther() {
alert('hello');
}
}
Parent.showJob(); // 'hello'
Parent.showJob(); // undefined,静态方法无法读取实例上属性
父类的静态方法,可以被子类继承
class Parent {
static showOther() {
alert('hello');
}
}
class Child extends Parent {
constructor() {
super();
}
}
Child.showOther(); // 'hello'
类的方法中如果含有this关键字(调用了类属性或者类方法),单独使用类的方法,有可能报错
class Parent{
constructor(){
this.job = 'teacher';
}
toShowJob(){
this.showJob();
}
showJob(){
alert(this.job)
}
}
var p = new Parent()
p.toShowJob() // alert('teacher')
//然而下面的写法会报错
const a = new Parent();
const { toShowJob } = a;
toShowJob() // 报错
一种解决方法是
class Parent{
constructor(){
//注意,绑定的是toShowJob方法
this.toShowJob = this.toShowJob.bind(this);
}
}
另一种方法是使用箭头函数,箭头函数会默默地绑定this
class Parent{
constructor(){
this.toShowJob =()=>{
this.showJob();
}
}
}
当然也可以考虑在new的时候const a = selfish(new Parent())再加一个中间函数selfish