JavaScript面向对象(二)——构造函数的继承方法
一、构造函数绑定
第一种最简单的方法使用JavaScript中的自带方法,call()和apply()
function animal(){
this.total = "动物";
}
function dogFn(name,age){
this.name = name;
this.age = age;
animal.apply(this, arguments)
}
var dog1 = new dogFn("柴犬","3");
console.log(dog1.total) // 动物
二、prototype模式
这是一个最常用的方法
function animal(){
this.total = "动物";
}
function dogFn(name,age){
this.name = name;
this.age = age;
}
dogFn.prototype = new animal();
dogFn.prototype.constructor = dogFn;
var dog1 = new dogFn("柴犬","3");
console.log(dog1.total) // 动物
coonsole.log(dog1)
// 打印出是下图,因为是dogFn.prototype实例了animal对象,所以total属性在prototype下
而dogFn.prototypt.constructor = dogFn;
// 因为constructor最初是指向自己本身的函数,因为上一行代码用prototype实例了animal,所以改变了constructor的最初指向,所以要用这行代码重新吗constructor构造函数的指向更正回来
// 图左为有dogFn.prototypt.constructor = dogFn;图有则没有
三、直接继承prototype
由于第二种方法多添加了一个animal实例,会造成浪费内存
function animal(){ }
animal.prototype.total = "动物";
function dogFn(name,age){
this.name = name;
this.age = age;
}
dogFn.prototype = animal.prototype;
dogFn.prototype.constructor = dogFn;
var dog1 = new dogFn("柴犬","3");
console.log(dog1.total) // 动物
console.log(animal.prototype) // dogFn
这种方式还是有一个缺陷,会将animal.prototype的指向变为dogFn,所以需要改进
function animal(){}
animal.prototype.total = "动物";
function dogFn(name,age){
this.name = name;
this.age = age;
}
// 这里直接封装了一个函数,
function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
extend(dogFn,animal);
var dog1 = new dogFn("柴犬","3");
console.log(dog1)
四、拷贝继承
将父级的属性拷贝到子级中
function animal(){}
animal.prototype.total = "动物";
function dogFn(name,age){
this.name = name;
this.age = age;
}
function extend(Child, Parent) {
var p = Parent.prototype;
var c = Child.prototype;
for(var i in p){
c[i] = p[i];
}
c.uber = p;
}
extend(dogFn,animal);
var dog1 = new dogFn("柴犬","3");
console.log(dog1)