1.原型链继承(最简单)
核心 (实现思路):用父类的实例充当子类原型对象
<code class=\"language-JavaScript\">function Person(name) { this.name = name; this.fav = [\'basketball\', \'football\']; this.detAIl = {country : \'中国\', city : \'江苏\'} } function Man(name) { this.say = function(){console.log(\'I am man\')}; } Man.prototype = new Person(); //核心 var sam = new Man(\'sam\'); console.log(sam.fav); //\'basketball\', \'football\'
优点
1.简单,容易理解,容易实现
缺点:
1.创建子类实例时无法向父类传参(创建Man时无法传递name信息)
2.引用类型的属性(数组和对象),被所有实例共享,接着上面的代码举个例子
var tyler = new Man(\'tyler\');
tyler.fav.push(\'badminton\');
tyler.rela.area = \'建业区\'
//修改tyler实例的信息,间接地修改了sam实例的属性
console.log(sam.fav) // \"basketball\", \"football\", \"badminton\"
console.log(sam.rela) // {country:\'中国\',city:\'江苏\',area:\'建邺区\'}
2.借用构造函数(经典继承)
为了解决原型链继承的两个问题,所以就有了借用构造函数的继承方法。
核心 (实现思路):借父类的构造函数,补充子类的构造函数,相当于把父类的实例属性拷贝一份给子类的实例
function Person(name) {
this.name = name;
this.fav = [\'basketball\', \'football\'];
this.say = function(){console.log(\'I love china\')}
}
function Man(name) {
Person.call(this, name); //核心
}
var sam = new Man(\'sam\');
var tyler = new Man(\'tyler\');
tyler.fav.push(\'badminton\');
console.log(sam.name); //sam
console.log(tyler.name); //tyler
console.log(sam.fav); //\'basketball\', \'football\'
console.log(tyler.fav); //\'basketball\', \'football\', \'badminton\'
console.log(sam.say == tyler.say) //false
优点:
1.解决了原型链继承中 实例共享引用类型属性的问题
2.修改了原型链继承中 子类构建无法向父类传递参数的问题
缺点:
1.代码的最后一行显示两个子类实例中的方法并非同一个,即无法实现函数复用,如果实例多的情况下影响性能
3.组合继承(常用)
原型链继承和借用构造函数继承的组合
核心 (实现思路):把实例函数都放在父类的原型对象上面,实现函数复用,同时保留借用构造函数的实现思路。
function Person(name) {
this.name = name;
this.fav = [\'basketball\', \'football\'];
}
Person.prototype.say = function(){console.log(\'I love china\')}
function Man(name) {
Person.call(this, name); //核心
}
Man.prototype = new Person();
var sam = new Man(\'sam\');
var tyler = new Man(\'tyler\');
tyler.fav.push(\'badminton\');
console.log(sam.name); //sam
console.log(sam.fav); //\'basketball\', \'football\'
console.log(sam.say == tyler.say) //true
优点:
1.没有实例共享引用类型的属性的问题
2.子类构造实例时可以通过父类传递参数
3.实现了函数复用
缺点:
1.唯一缺点就是创建一个子类实例时,会调用两次父构造函数,从上面的代码中sam 和Man.prototype 中都包含 fav属性
4.寄生组合式继承(最佳)
为了解决组合继承中的不足,计生组合式继承应运而出了
核心 (实现思路):使用壳函数切掉了原型对象上多余的父类属性
//代码1
function Person(name) {
this.name = name;
this.fav = [\'basketball\', \'football\'];
}
Person.prototype.say = function(){console.log(\'I love china\')}
function Man(name) {
Person.call(this, name);
}
//关键三步代码
var F = function () {};
F.prototype = Person.prototype;
Man.prototype = new F();
var sam = new Man(\'sam\');
console.log(sam.name);
//代码2 :对继承的关键三部进行封装
function Person(name) {
this.name = name;
this.fav = [\'basketball\', \'football\'];
}
Person.prototype.say = function(){console.log(\'I love china\')}
function Man(name) {
Person.call(this, name);
}
function create(o) {
function F(){};
F.prototype = o;
return new F();
}
function inheritFunc(child, parent) {
var newPrototype = create(parent.prototype);
//如果没有下面一行代码,sam.constructor会变称Person 而不是Man
newPrototype.constructor = child;
child.prototype = newPrototype;
}
var sam = new Man(\'sam\');
console.log(sam.name);
优点:
没有任何缺点就是优点(如果使用麻烦不算缺点的话)
缺点:
理解起来比较绕,使用比较麻烦
© 版权声明
THE END
暂无评论内容