继承 就是 类与类之间的关系 基类 父类 子类
创建对象(实例)的几种方式 :字面量 工厂函数 构造函数 原型对象 组合创建 class
一.构造继承
通过使用call、apply方法可以在新创建的对象上执行构造函数,用父类的构造函数来增加子类的实例
call继承
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
console.log(this.name,this.age);
}
}
function Male(name, age) {
/* this.name = name;
this.age = age;
this.sayHello = function(){
console.log(this.name);
} */
//继承父类Person
Person.call(this, name, age);//将父类函数中的this,强行绑定为子类的this
}
var male = new Male("wahaha", 20);
male.sayHello();
apply继承
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
console.log(this.name,this.age);
}
}
function Female(name, age) {
//继承父类Person
Person.apply(this, [name,age]);
}
var black = new Female("haha", 20);
black.sayHello();
call与aplly的异同:
1,第一个参数this都一样,指当前对象
2,第二个参数不一样:call的是一个个的参数列表;apply的是一个数组(arguments也可以)
优点: 简单明了,直接继承超类构造函数的属性和方法
缺点: 无法继承原型链上的属性和方法
二.原型链继承
利用原型链来实现继承,超类的一个实例作为子类的原型
//每一个构造函数都有一个原型对象,每一个原型对象都有一个指针constructor指向构造函数
//每一个实例都有一个内部指针(__ proto__),指向原型对象,原型对象上的属性和方法能被实例所访问
//当我们访问一个对象的某个属性时,如果该对象自身不存在该属性, 就从它的__proto__属性上继续查找,以此类推,直到找到,若找到最后还是没有找到,则结果为undefined
function Person(){
}
Person.prototype.name = "wahaha";
Person.prototype.age = 20;
Person.prototype.sayHello = function(){
console.log(this.name,this.age);
}
function Male(){
}
Male.prototype = new Person();//Male.prototype.__proto__ -> Person.prototype
var male = new Male();
male.sayHello();
//原型链 原型链上的属性和方法能被实例所访问
//console.log(male.__proto__ == Male.prototype);
//console.log(Male.prototype.__proto__ == Person.prototype);
//console.log(Object.prototype,Object.prototype.__proto__);
三.组合继承
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function(){
console.log(this.name,this.age)
}
function Male(name,age){
Person.call(this,name,age)
}
//Male.prototype = new Person();
//Male.prototype = Person.prototype;//会出现地址拷贝,为避免父类继承子类这种情况所以用下面for in的方式
for(var i in Person.prototype){
Male.prototype[i] = Person.prototype[i];
}
//子类自己的方法
Male.prototype.sayHi = function(){
console.log("aa");
}
var male = new Male("jie",20);
male.sayHello();
male.sayHi();
var person = new Person("john", 22);
person.sayHello();
四. Es6继承
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
sayHello(){
console.log(this.name);
}
}
class Male extends Person{
constructor(name,age){
super(name,age);//super指向父类的构造函数
}
}
var male = new Male("john","20");
male.sayHello();