原型继承
// 创建父类
function Super() {
this.name = '小明';
}
Super.prototype.sayName = function () {
console.log("我叫:" + this.name);
}
function Sub() {
this.name = '张三';
}
//原型继承 可以将super的实例所有的属性和方法都能继承到sub的原型中
// Sub.prototype=Super.prototype;
Sub.prototype = new Super();
var sub = new Sub();
console.log(sub);
sub.sayName();
重点:子类的原型=父类的原型Sub.prototype=Super.prototype;
或者子类的实例原型=父类的实例Sub.prototype = new Super();
缺点:
1、所有的新实例都会共享父类实例属性(原型上的属性是共享的,一个实例修改了原型属性。另一个实例的原型属性也会被修改)
2、新实例无法向父类构造函数传递参数
拷贝继承+构造函数继承
//1.创建一个普通人类
function CreatePerson(name, sex) {
this.name = name;
this.sex = sex;
this.fun = function () {
console.log(123);
}
}
CreatePerson.prototype.show = function () {
console.log('我是:' + this.name);
}
var zhangsan = new CreatePerson('zhangsan', '男');
zhangsan.fun();
//2.创建一个明星类
function CreateSuper(name, sex) {
//构造继承 只能继承类的属性和方法 不能继承原型
CreatePerson.call(this, name, sex);
}
extend(CreateSuper.prototype, CreatePerson.prototype);
var zhaosi = new CreateSuper('赵四', '男');
console.log(zhaosi.name);
zhaosi.show();
//3.创建一个学生类
function CreateStudent(name, sex) {
CreatePerson.call(this, name, sex);
}
extend(CreateStudent.prototype, CreatePerson.prototype);
var xiaoming = new CreateStudent('小明', '男');
xiaoming.show();
//浅拷贝继承 继承引用类型
function extend(obj1, obj2) {
for (attr in obj2) {
obj1[attr] = obj2[attr];
}
}
重点:使用call
和apply
将父类构造函数引入子类函数
缺点:
1、只能继承父类构造函数的属性
2、每次使用都要重新调用
3、每个新实例都有父类构造函数的副本
组合继承
//组合继承 原型继承和拷贝继承一起组合使用
function PerSon(name, age, sex, weight) {
this.name = name;
this.age = age;
this.sex = sex;
this.weight = weight;
}
PerSon.prototype.sayHi = function () {
console.log('你好');
}
function Students(name, age, sex, weight, score, xinxi) {
PerSon.call(this, name, age, sex, weight);
this.score = score;
this.xinxi = xinxi;
}
var xiaowang = new Students('小王', 30, '男', '180', 80, '三好学生');
console.log(xiaowang);
重点:传递参数(构造函数)和复用(原型链)
特点:每个新实例引入的构造函数属性都是私有的