最近在重新复习TypeScript,看到类这块的时候自然会和ES5中的类写法进行对比加深印象。

发现ES5的类与继承一些细节还是挺多的,时间久了容易忘记,特此记录下。

首先是ES5的类定义,这没什么好说的,直接上代码:

function Person () {
  this.name = 'xc' // 属性
  this.age = 30
  // 属性方法
  this.run = function () {
    console.log(this.name + '在跑步')
  }
}
// 静态方法
Person.staticWork = function () {
  console.log('静态方法在工作')
}
Person.prototype.sex = '男' // 原型链上属性
Person.prototype.work = function () { // 原型链上方法
  console.log(this.name + '在工作')
}
var person = new Person()
person.run()
console.log(person.age)
Person.staticWork()
person.work()

下面是显示结果:

ES4自定义对象 es5定义类_原型链

 

下来就是类的继承了,我们通常会用一种俗称"原型链+对象冒充组合继承"方式来实现类的继承。看起来有点复杂,我们下来慢慢剖析。

首先我们来看对象冒充继承,贴上代码:

// 定义继承类
function People () {
  Person.call(this) // 对象冒充继承
}
var people = new People()
console.log(people.name)
people.run()
console.log(people.sex)
people.work()

我们看到实际上对象冒充继承的意思就是通过call方法来实现,可是这样的继承方式会出现什么结果呢?

ES4自定义对象 es5定义类_ES4自定义对象_02

通过运行结果,我们可以发现通过对象冒充的这种继承方式,我们只能继承父类内部的属性和方法,原型链上的却无法继承。

好了,下来我们来说原型链的继承方式:

// 定义继承类
function People () {
}
People.prototype = new Person() // 通过原型链继承
var people = new People()
console.log(people.name)
people.run()
console.log(people.sex)
people.work()

同样,输出结果:

ES4自定义对象 es5定义类_静态方法_03

我们看到这里,大家会觉得通过原型链的继承方式,可以将父类的内部和原型链上的属性及方法都继承过来,那就没啥问题了。

看来还是很多同学还是想的太简单了,我们把代码修改下,给父类添加初始化参数再来试试:

function Person (name, age) { // 添加参数,并赋值给内部属性
  this.name = name // 属性
  this.age = age
  // 属性方法
  this.run = function () {
    console.log(this.name + '在跑步')
  }
}
// 静态方法
Person.staticWork = function () {
  console.log('静态方法在工作')
}
Person.prototype.sex = '男' // 原型链上属性
Person.prototype.work = function () { // 原型链上方法
  console.log(this.name + '在工作')
}

// 定义继承类
function People (name, age) {
}
People.prototype = new Person() // 通过原型链继承
var people = new People('xxc', 20)
console.log(people.name)
people.run()
console.log(people.sex)
people.work()

大家猜猜,结果是啥?

ES4自定义对象 es5定义类_父类_04

我们发现,父类通过参数赋值的内部属性在继承类中都无法使用了。好坑啊,那怎么办呢?

答案就是将我们前面提到过的对象冒充继承和原型链继承进行组合一起使用,最终版即:

function Person (name, age) { // 添加参数,并赋值给内部属性
  this.name = name // 属性
  this.age = age
  // 属性方法
  this.run = function () {
    console.log(this.name + '在跑步')
  }
}
// 静态方法
Person.staticWork = function () {
  console.log('静态方法在工作')
}
Person.prototype.sex = '男' // 原型链上属性
Person.prototype.work = function () { // 原型链上方法
  console.log(this.name + '在工作')
}

// 定义继承类
function People (name, age) {
  Person.call(this, name, age)
}
People.prototype = new Person() // 通过原型链继承
var people = new People('xxc', 20)
console.log(people.name)
people.run()
console.log(people.sex)
people.work()

最后看看结果:

 

ES4自定义对象 es5定义类_父类_05

上述就是ES5的类与继承