• javascript原型式继承


    之前的文章里有提到过javascript类式继承,那种继承方式极大的方便了其他语言(非javascript)程序员使用javascript来实现继承,但是有缺点,就是建立了一个非必要的构造函数,那这篇文章我们来谈一谈具有javascript自身特色的原型式继承。

    我们先来看一看下面的代码:

    var Car = {
        color: 'red',
        size: 'big',
        getAttr: function() {
            return this.color
        }
    }
    
    var car1 = Object.create(Car)
    car1.color = 'blue'
    car1.brand = 'BYD'
    console.log(car1.color) //blue
    console.log(car1.brand) //BYD
    console.log(Car.color) //red
    console.log(Car.brand) //undefined
    
    var car2 = Object.create(Car)
    car2.getAttr = function() {
        return this.size
    }
    console.log(car2.getAttr()) //big
    console.log(Car.getAttr()) //red
    console.log(car1.getAttr()) //blue

    上面的代码就是原型式继承最简单的方式,“子类”继承了“父类”的属性,修改“子类”的属性也没有影响到“父类”,“子类”之间也是相安无事互不干扰,完美实现了继承。这样继承的好处就是比类式继承少了一层构造函数

    当然create这个方法是es5中出现的,ie6 7 8是不支持的哦,下面是一个兼容的方法,让低版本ie也来实现create。

    if (!Object.create) {
        Object.create = function(o) {
            function F() {}
            F.prototype = o
            return new F()
        }
    }

    上述代码的意思就是,首先声明一个构造函数,该构造函数的原型指向需要继承的对象,最后返回实例化后的构造函数,其实这个函数也很好的诠释了原型式继承的原理,“父类”的属性存在于“子类”的原型上,如果“子类”自己重写了属性或者方法,那就直接用“子类”自身的属性或者方法,并且不会影响到“父类”,如果调用了“子类”没有的属性或者方法,那么由于原型链,我们顺藤摸瓜就找到了“父类”的属性或方法,如果再没有就game over了。

    其实两种继承方式大同小异,玩的都是原型链,只是原型式继承更符合javascript的语言特点,类式继承更偏向于“类”的概念。

    2017.12.1更新
    之前理解有点偏差,也很久没有看以前写的博客了,发现不是很对,这里需要修改下,Object.create就是使用指定的原型对象及其属性去创建一个新的对象。
    完整的原型继承应该是:

    //
    var Foo = function () {
      this.x = 1
      this.y = 2
    }
    Foo.prototype.add = function ()  {
      return this.x + this.y
    }
    //
    var Bar = function () {
      // 调用父类的构造函数,this指向自己
      Foo.call(this)  
    }
    Bar.prototype = Object.create(Foo.prototype)
    // 原型构造函数在上一步被干掉了,再搞回来
    Bar.prototype.constructor = Bar

    这样bar就拥有了foo的一切,并可以在foo的基础上进行扩展且不会影响到foo。

    那为什么使用Object.create把foo的原型复制给bar呢,不能使用new Foo()或者Foo.prototype的形式吗?

    答案当然是否定的,如果使用new Foo(),表面上看上去没有问题,但是此时foo函数会被调用,如果foo的构造函数中不只是定义数据还有实际操作,比如alert,那就出现问题了。

    使用Foo.prototype就更不可以了,这样就会变成了bar的原型就直接引用了foo的原型,如果这时候修改bar的原型就相当于修改了foo的原型。

  • 相关阅读:
    python学习笔记(十五)-异常处理
    python学习笔记(十四)python实现发邮件
    python学习笔记(十三)-python对Excel进行读写修改操作
    python学习笔记(十二)-网络编程
    python学习笔记(十一)-python程序目录工程化
    python学习笔记(九)-函数2
    python学习笔记(八)-模块
    勿忘初心,勇往前行
    【tp6】解决Driver [Think] not supported.
    【Linux】LNMP1.6 环境报500错误解决方法
  • 原文地址:https://www.cnblogs.com/junhua/p/4389091.html
Copyright © 2020-2023  润新知