一般实现
本文直接在代码中说明,需要掌握原型和原型链的知识,这个还是比较基础的知识,还不会的可以百度一下,这里不做过多的介绍。
function Person(name,age) {
this.name = name
this.age = age
/* this.setName = function(newName){
console.log("我的名字"+this.name)
this.name = newName
} */
}
Person.prototype.setName = function (newName){
console.log("我是原型上面的方法 ")
this.name = newName
}
let p = new Person('gege',23)
p.setName('feifei') //先在自身找,找不到去原型上找,接着沿着原型链找
//因为所有person实例都需要有一个setName,我们就直接放到原型上,这样减少内存开销
console.log(p) //Person {name: "feifei", age: 23}
上面代码还是easy的,接着看
function Student(name,age,score) {
//这里借用Person的构造函数
Person.apply(this,[name,age])
this.score = score
}
Student.prototype.sayHi = function () {
console.log("我是学生"+this.name+"我考了"+this.score+"分")
}
let lihua = new Student('lihua',12,100)
lihua.sayHi() //我是学生lihua我考了100分
上面这个也是相当easy的。
下面是这样一个需求:
我现在想调用Person的方法改个名字
lihua.setName(‘tom’)
lihua.sayHi()
这时候就需要让子类原型成为父类的一个实例
function Student(name,age,score) {
Person.apply(this,[name,age])
this.score = score
}
//原型链继承,让子类的原型成为父类的实例
Student.prototype = new Person()
//修正构造Student的构造函数
Student.prototype.constructor = Student
//console.log(Student.prototype.constructor) //function Student(){}
Student.prototype.sayHi = function () {
console.log("我是学生"+this.name+"我考了"+this.score+"分")
}
let lihua = new Student('lihua',12,100)
lihua.sayHi()
//我现在想调用Person的方法改个名字
lihua.setName('tom')
lihua.sayHi()
定义完Student的构造函数直接修改原型为父类的实例,这里需要修改它的构造函数时自身,因为在上一步的时候会把Student实例的构造函数都设置成Person,这是由错误的,不过不影响使用,所以做出修正,代码中也有注释。
这时Student实例就成功看到了Person原型中的方法。
ES6中的class
ES6的写法,比上面的方法简单了许多
class Person{
constructor(name,age){
this.name = name
this.age = age
}
setName(newname) {
this.name = newname
}
}
let p = new Person('feifei',20)
console.log(p)
class Student extends Person{
constructor(name,age,score){
super(name,age)
this.score = score
}
sayHi(){
console.log("我是"+this.name+'我的分数:'+this.score)
}
}
let lihua = new Student('lihua',20,100)
console.log(lihua )
lihua.sayHi()
//console.log(Student.prototype.constructor)
lihua.setName('tom')
lihua.sayHi()