原型和继承
- 原型的作用:
- 数据共享,节省内存空间
- 实现继承
- 继承的实现方式:
- 借用构造函数
- 原型
- 最终指向:继承最终指向为
null
实现继承的方式
原型继承
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function() {
console.log('hello ' + this.name);
};
function Student(score){
this.score = score;
}
// 改变原型指向即可 => 学生和人已经发生关系
Student.prototype = new Person("小明", 10);
Student.prototype.study = function (){
console.log("学习");
};
- 注意:如果父对象的方法要继承到子对象,此方法必须写在原型中而不是写在构造函数中,因为只有这样才能实现方法的共享。而属性则不必写在原型、直接写在构造函数即可共享。
- 缺点:因为改变原型指向的同时实现继承,直接初始化了属性,继承过来的属性的值都是一样的了。这就是问题,只能重新调用对象的属性进行重新赋值。
借用构造函数
-
背景:继承的时候,不用改变原型的指向,直接调用父级的构造函数来为属性赋值就可以了
-
语法:
构造函数名字.call(当前对象, 属性....);
-
例子:
function Person(name) { this.name = name; } Person.prototype.sayHi = function(){ console.log("您好"); }; function Student(name, score) { // 传入this对象和父类属性 Person.call(this, name); this.score = score; } const stu = new Student("小明",100); console.log(stu1.name, stu1.score); // 只能继承属性 // stu.sayHi(); // 【报错,不能继承】
-
优点:解决了属性继承,并且值不重复的问题
-
缺点:父类中的【方法不能继承】
组合继承
原型继承 + 借用构造函数继承,即解决属性重复问题,又能继承方法
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function(){
console.log("阿涅哈斯诶呦");
};
function Student(name,score) {
// 借用构造函数:属性值重复的问题
Person.call(this,name);
this.score = score;
}
// 改变原型指向----继承
Student.prototype = new Person();//不传值
Student.prototype.eat = function() {
console.log("吃东西");
};
var stu = new Student("小黑", "100分");
console.log(stu.name, stu.score);
stu.sayHi();
stu.eat();
拷贝继承
把一个对象中的属性或方法直接复制到另一个对象中
var obj1 = {
age: 20,
sleep: function () {
console.log("睡觉了");
}
};
// 改变了地址的指向
var obj2 = obj1;
console.log(obj2.age);
obj2.sleep();
/****************************/
var obj1 = {
age: 20,
sleep: function () {
console.log("睡觉了");
}
};
var obj2 = {};
for(var key in obj1){
obj2[key] = obj1[key];
}
console.log(obj2.age);
/****************************/
function Person() {
}
Person.prototype.age = 10;
Person.prototype.play = function() {
console.log("玩的好开心");
};
var obj2 = {};
for(var key in Person.prototype){
obj2[key] = Person.prototype[key];
}
console.dir(obj2);
/****************************/
function Person(name, age) {
this.type = 'human'
this.name = name
this.age = age
}
Person.prototype.sayName = function () {
console.log('hello ' + this.name);
}
function Student (name, age) {
Person.call(this, name, age);
}
for(var key in Person.prototype) {
// 原型对象拷贝继承原型对象成员
Student.prototype[key] = Person.prototype[key];
}
const stu = Student('张三', 18)
stu.sayName() // hello 张三