通过原型链实现继承
` function Person(name, age, sex) { this.arr = [33, 44, 55]; this.name = name this.age = age this.sex = sex }
Person.prototype.sayHello = function () {
console.log(`你好,我是${this.name}今年${this.age}岁了,我是${this.sex}生`);
}
function Student(name, age, sex, address) {
this.name = name
this.age = age
this.sex = sex
this.address = address
}
// 原型链实现继承
Student.prototype = new Person()
// 子类可以重写父类方法
Student.prototype.sayHello = function () {
console.log(`敬礼!,你好,我是${this.name}今年${this.age}岁了,我是${this.sex}生,我家在${this.address}`);
}
var xm = new Student('小明', 6, '男', '翻斗花园')
xm.sayHello()
var xh = new Person('小红', 7, '女')
xh.sayHello()
console.log(xh.arr);
xm.arr.push(123)
console.log(xm.arr);
`
通过原型链实现继承的问题
- 问题1: 如果父类属性中有引用类型属性 则会被所有子类共享
- 问题2: 子类中重复定义父类定义过的属性
- 使用组合式继承即可解决以上问题
组合式继承
`
function People(name, sex, age) { this.name = name this.age = age this.sex = sex }
People.prototype.sayHello = function () {
console.log(`你好,我是` + this.name + '今年' + this.age + '岁了');
}
People.prototype.sleep = function () {
console.log(this.name + '睡觉');
}
function Student(name, sex, age, school, sid) {
// 借助构造函数
People.call(this, name, sex, age)
this.school = school
this.sid = sid
}
Student.prototype = new People()
Student.prototype.exam = function () {
console.log(this.name + '正在考试');
}
Student.prototype.sayHello = function () {
console.log('敬礼!你好我是' + this.name + '我今年' + this.age + '岁了,我是' + this.sex + '生,我的学校是' + this.school + '我的学号是' + this.sid);
}
var xiaoming = new Student('小明', '男', 12, 'pk学校', 10086)
xiaoming.sayHello()
xiaoming.sleep()
xiaoming.exam()
`
组合式继承缺点
- 会调用两次父类的构造函数 造成效率浪费
通过Object.create()实现寄生组合式继承
function inheritPrototype(subType, superType) {
var prototype = Object.create(superType.prototype)
subType.prototype = prototype
}
function People(name, sex, age) {
this.name = name
this.age = age
this.sex = sex
}
People.prototype.sayHello = function () {
console.log(`你好,我是` + this.name + '今年' + this.age + '岁了');
}
People.prototype.sleep = function () {
console.log(this.name + '睡觉');
}
//寄生式组合继承
inheritPrototype(Student, People)
function Student(name, sex, age, school, sid) {
// 借助构造函数
People.call(this, name, sex, age)
this.school = school
this.sid = sid
}
Student.prototype.exam = function () {
console.log(this.name + '正在考试');
}
Student.prototype.sayHello = function () {
console.log('敬礼!你好我是' + this.name + '我今年' + this.age + '岁了,我是' + this.sex + '生,我的学校是' + this.school + '我的学号是' + this.sid);
}
var xiaoming = new Student('小明', '男', 12, 'pk学校', 10086)
xiaoming.sayHello()
xiaoming.sleep()
xiaoming.exam()
console.log(Student.prototype.__proto__ === People.prototype);//true
Object.create()方法
- 创建一个新的对象 可以将原有对象设置为新对象的原型
- 参数1 被设置为新对象原型的 原对象
- 参数2 设置新对象内的属性值 与原对象重复则会被新对象覆盖
var obj1 = {
a: 33,
b: 45,
c: 12,
test: function () {
console.log(this.a + this.b);
}
}
var obj2 = Object.create(obj1, {
d: {
value: 99
},
a: {
value: 10
}
})
console.log(obj2.__proto__ === obj1); //true
console.log(obj2.a); //10
console.log(obj2.b); //99
console.log(obj2.c); //12
console.log(obj2.d); //45
/*
原型式继承
*/
obj2.test()