美文网首页
(4)JavaScript继承模式二

(4)JavaScript继承模式二

作者: jaimor | 来源:发表于2019-04-22 12:57 被阅读0次

上一篇文章说了继承模式,其实上一章节的继承模式是有一点瑕疵的,这个瑕疵并不是由模式引起的,而是由JavaScript自身原型链引起的。比如我们来改一改上一章节(请先看上一篇文章,这里不做阐述)中的代码:

//父类
function Supper(msg) {
  this.msg = msg;
  this.supperVal = ["supper", "val"];      //只将此处修改为引用类型,其他不做修改
}
Supper.prototype.say = function () {
  console.log(this.msg);
}
Supper.prototype.getSupperVal = function () {
  return this.supperVal;
}
new Supper("i am supper").say();    // i am supper

//子类
function Sub(msg) {
  this.name = "sub";            //对父类的拓展,父类没有,而子类有的属性
  this.msg = msg;               //覆盖、修改父类的属性
}
Sub.prototype = new Supper("supper class");  //这里只是修改了父类的msg
//拓展了一个新的方法、功能
Sub.prototype.who = function () {
    console.log(this.name);
}
var sub = new Sub("i am sub");    //子类msg为 i am sub
sub.who();      // sub,这里是对父类的属性、方法进行的拓展
sub.say();      // i am sub,这里是对父类的属性进行覆盖
sub.getSupperVal();    //supperVal,这里是对父类的属性进行继承
sub实例对象

然后我们来创建一个sub2实例。

var sub2 = new Sub("i am sub2");
sub2实例对象

这样也没有问题。拥有了自己的属性name,也覆盖了父类属性msg,也继承了父类属性supperVal和方法。看似都很完美,接下来注意了。我们要来修改下sub2中冲父类继承过来的属性supperVal。

sub2.supperVal.push("sub2 modify");    //愿意只是向修改sub2中的supperVal的值,但结果却不是这样!!!
修改后的结果

可以看到的是,我仅仅只是使用sub2修改自己的supperVal的值,但是影响到了其他实例的属性,这在开发中可要造成严重的BUG,值得注意!!!当然,如果supperVal是非引用类型,是不会有这样的问题的,而为什么使用引用类型的时候,会出现这样的问题,这就是JavaScript自身原型链里的知识了,这里不做阐述。我们这里主要是要完善这种继承模式中可能会出现类似的问题。
出现这种问题的原因就是,子类继承的过来的属性在原型链上。所以如果我们将父类继承过来的属性嵌入到子类中,而不是原型链中,岂不是就可以了。

// 子类做一点小修改,规避这样的问题
//子类
function Sub(msg) {
  Supper.call(this, msg);      //这里就将父类中的属性全部在子类中执行一边(相当于拷贝了一份在子类中)
  this.name = "sub";            //对父类的拓展,父类没有,而子类有的属性
  //this.msg = msg;             //此处就不需要了
}
Sub.prototype = new Supper("supper class");  //这里的目的就只是拷贝父类原型链中的方法(因为属性已经通过Supper.call(this, msg)拷贝了)

完整代码如下:

//父类
function Supper(msg) {
  this.msg = msg;
  this.supperVal = ["supper", "val"];      //只将此处修改为引用类型,其他不做修改
}
Supper.prototype.say = function () {
  console.log(this.msg);
}
Supper.prototype.getSupperVal = function () {
  return this.supperVal;
}
new Supper("i am supper").say();    // i am supper

//子类
function Sub(msg) {
  Supper.call(this, msg);      //这里就将父类中的属性全部在子类中执行一边(相当于拷贝了一份在子类中)
  this.name = "sub";            //对父类的拓展,父类没有,而子类有的属性
  //this.msg = msg;             //此处就不需要了
}
Sub.prototype = new Supper("supper class");  //这里只是修改了父类的msg
//拓展了一个新的方法、功能
Sub.prototype.who = function () {
    console.log(this.name);
}
var sub = new Sub("i am sub");    //子类msg为 i am sub
var sub2 = new Sub("i am sub2");
sub2.supperVal.push("sub2 modify");
结果

相关文章

  • (4)JavaScript继承模式二

    上一篇文章说了继承模式,其实上一章节的继承模式是有一点瑕疵的,这个瑕疵并不是由模式引起的,而是由JavaScrip...

  • JavaScript继承模式

    1,原型链继承 步骤定义父类型构造函数给父类型的原型添加方法定义子类型的构造函数创建父类型的对象赋值给子类型的原型...

  • javascript代码积累

    一、javascript实现继承 1.基于原型链实现继承 2.基于属性和方法复制实现继承 二、javascript...

  • javascript----继承模式

    我是谁,我来自哪,我是谁的谁 想必大家一定在学习或者开发过程常常被JS独有的原型继承拨过不少脑弦吧,为何不迎问题而...

  • (九)

    寄生组合式继承前面说过,组合继承是JavaScript最常用的继承模式;不过,它也有自己的不足。组合继承最大的问题...

  • js 集成模式 07-24

    **原始继承模式--原型链 2:借用构造函数 3:共享构造原型 4:圣杯模式**一:原型链; 二:构造函数; 三:...

  • JavaScript 继承 4 原型式继承

    输出结果: 在没有必要兴师动众地创建构造函数,而只想让一个对象与另一个对象保持类似的情况下,原型式继承是完全可以胜任的。

  • JavaScript最全的继承模式

    //js各种继承的分析; function Parent(name,age){ this.name=name; ...

  • (3)JavaScript继承模式一

    继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。继承可以高效利用之前封装过的类,而不影响之前的...

  • JavaScript继承详解(Mixin)

    上一篇JavaScript继承详解(Klass)介绍了各种继承的模式。但究竟为何要继承?一个很重要的目的就是为了代...

网友评论

      本文标题:(4)JavaScript继承模式二

      本文链接:https://www.haomeiwen.com/subject/fdtzwqtx.html