您的位置:首页 > Web前端 > JavaScript

学习打卡 JavaScript面向对象-继承

2020-06-06 06:20 225 查看

        JS的继承也肝了 满打满算两三天了,虽然还是有很多地方没有弄懂,还是强行做个整理吧先。

1. 原型链继承

        这种方式的继承已经在之前一篇博文 学习打卡 JavaScript面向对象编程-原型链 写的相对详细了,不再赘述,直接上源码:

function Super(name){
this.name = name;
this.superValue = `SuperArea ${this.name}`;
}
Super.prototype.getSuperValue = function(){
return this.superValue;
}

function Sub(name,age){
this.name = name;
this.age = age;
this.subValue = `SubArea ${this.name + this.age}`;
}
Sub.prototype = new Super('xhy');
Sub.prototype.getSubValue = function(){
return this.subValue;
}

var el = new Sub('yhs', 26);
console.log(el.getSuperValue()); // SuperArea xhy

        原型链继承最大的问题除了繁琐以外,还在于会改变子类的constructor的指向。当然这也不是大事情,如果真的很需要子类原型对象 构造函数指向正确的话,重新定义一下即可;

        原型链继承最大的问题,仍然在于引用类型值的共享化:

function Super(){
this.arr = [1, 2, 3, 4, 5];
}

function Sub(){}
Sub.prototype = new Super();

var el = new Sub();
el.arr.push(6);
console.log(el.arr); //(6) [1, 2, 3, 4, 5, 6]

var el2 = new Sub();
console.log(el2.arr); //(6) [1, 2, 3, 4, 5, 6]

console.log(Sub.prototype.arr); //(6) [1, 2, 3, 4, 5, 6]

        当 Sub 通过原型链继承了 Super 后,sub.prototype 就变成了Super的一个实例,它也拥有了一个它自己的属性 arr ——就和专门创建了一个 Sub.prototype.arr 属性一样;so 当在任一一个Sub的实例上对引用数据类型的值进行修改后,所有的实例,包括子类的原型对象 中的值都会被强制同步

        笔者在b站发现了几种奇奇怪怪的 由原型链继承 衍化而来的继承方式,美其名曰…“改良”?
        什么 让子类跳过父类本身,直接继承父类的原型对象 以达到提高运行效率的目的…个人感觉没啥意义,既没有从根本上解决原型链继承的不足,还莫名其妙添加了不少的需要解决的bug…有兴趣的小伙伴可以去瞄一眼:B站 继承及原型链

2. 借用构造函数继承

        也被称为 伪造对象经典继承,在子类构造函数内部,通过使用apply() 或 call() 方法执行父类的构造函数,可以很好地解决原型链继承所带来的问题:

function Super(name){
this.name = name;
this.arr = [1, 2, 3, 4, 5];
}

function Sub(name, age){
Super.call(this,name);
this.age = age;
}

var el = new Sub('xhy', 21);
el.arr.push(6);
console.log(el.name + " " + el.arr); // xhy 1,2,3,4,5,6

var el2 = new Sub('yhs', 26);
console.log(el2.name + " " + el2.arr);// yhs 1,2,3,4,5 */

        并且相对于原型链而言,借用构造函数有一个很大的优势:可以在子类构造函数中向父类构造函数传递参数:

function Sub(){
Super.call(this,"pgOne");
this.age = age;
}

var el = new Sub();
console.log(el.name); // "pgOne"

3. 组合式继承

        也称伪经典继承,将原型链与借用构造函数的技术组合到一块,从而扬长避短的一种继承方式;
        思路:使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承:

function Super(name){
this.name = name;
this.arr = [1, 2, 3, 4, 5];
}
Super.prototype.greeting = function(){
return `Hi, I'm ${this.name}!`;
}

function Sub(name,age){
Super.call(this,name);
this.age = age;
}
Sub.prototype = new Super('xhy');
//Sub.prototype.constructor = Sub;
Sub.prototype.greetingD = function(){
return `Hi, I'm ${this.name}, I'm ${this.age} years old!`
}

var el = new Sub("aka", 13);
el.arr.push(6);
var el2 = new Sub("yhs", 26);
console.log(el2.constructor);//Super
console.log(el2.arr); // (5) [1, 2, 3, 4, 5]
console.log(el2.greeting()); // Hi, I'm yhs!!
console.log(el2.greetingD()); // Hi, I'm yhs, I'm 26 years old!

        如果进行子类构造函数的重定位后,这种组合式继承基本没有什么大毛病,也是现阶段JS最常用的继承模式。

4. 拷贝继承

function extend(Child, Parent){
var c = Child.prototype;
var p = Child.prototype;
for(var i in p){
c[i] = p[i];
}
}

        .我枯了 不禁怀疑自己这几天都学了啥…哪个大佬能告诉我这种土办法有什么缺陷嘛?!(这种方法下 它!连!构造函数的指向!都是正确的!)

5. 原型式继承

        .原型式继承 携带着 寄生式继承,笔者了解的不是那么OK,偷篇大佬照搬红宝书的博文,插个眼,过段时间再来瞄一眼就不信还啃不下来~ JS继承 原型式继承 —— weixin_34332905

6. 组合式继承+原型式继承

        .笔者也不确定用这种方式来称呼合不合适,如下的继承方式是我无意中发现国外的大佬写的,感觉意外的好用和舒爽:

function Super(name, age, sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Super.prototype.greeting = function(){
return `Hi, I'm ${this.sex == '男'? 'Mr':'Miss'} ${this.name}, I'm ${this.age} years old!`
}

function Sub(name, age, sex, msg){
Super.call(this, name, age, sex);
this.msg = msg;
}

Sub.prototype = Object.create(Super.prototype);
Sub.prototype.constructor = Sub;

var el = new Sub('xhy', 21, '男', 'nothing');
console.log(el);
console.log(el.greeting()); // Hi, I'm Mr xhy, I'm 21 years old!

7. ES6 继承

        .es6中提供了OOP类和继承
        .直接写class 无需花里胡哨的操作 —— 在原型里挣扎了数十个小时的笔者如沐春风~

class Super{
constructor(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
greeting(){
return `Hi, I'm ${this.sex == '男'? 'Mr':'Miss'} ${this.name}, I'm ${this.age} years old!`;
}
static show(){
return 'Here is SuperArea!';
}
}

class Sub extends Super {
constructor(name, age, sex, msg){
super(name, age, sex);
this.msg = msg;
}
}

var el = new Sub('xhy', 21, '男', 'nothing');
console.log(el);
console.log(el.greeting()); // Hi, I'm Mr xhy, I'm 21 years old! */

        有class ,有extends, 有super() ,甚至还有static…
        轻轻松松完成继承~ 啊这也太爽了吧~ 我不想搞前端了我想弄java去了(笑)

————————————————————————————————— END ————————————————————

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: