对Javascript 类、原型链、继承的理解 (2)


我们注意到上图中Pproto的__proto__指向了Object,这是因为每一个通过字面量的方式创建出来的对象它们都默认是Object类的对象,所以它们的__proto__自然指向Object.prototype。


4.利用prototype实现静态【属性/方法】

// 代码3.4 function Human(name) { this.name = name } Human.prototype.eat = function () { console.log('I eat!') } var person_1 = new Human('Jack') var person_2 = new Human('Rose') person_1.eat() // I eat! person_2.eat() // I eat! console.log(person_1.eat === person_2.eat) // true

这里我们在构造函数外多写了一句:Human.prototype.eat = function() {...} 这样以后每个通过Human实例化的对象的__proto__都会指向Human.prototype,并且根据上述原型链知识,我们可以知道只要构造函数中没有定义同名的非静态【属性/方法】,那么每个对象访问say方法时,访问的其实都是Human.prototype.say方法,这样我们就利用prototype实现了类的静态【属性/方法】,所有的对象实现了共有的特性,那就是eat

四、继承的实现

1.我对继承的理解

  假如有n(n>=2)个类,他们的一些【属性/方法】不一样,但是也有一些【属性/方法】是相同的,所以我们每次定义它们的时候都要重复的去定义这些相同的【属性/方法】,那样岂不是很烦?所以一些牛逼的程序员想到,能不能像儿子继承父亲的基因一样,让这些类也像“儿子们”一样去“继承”他们的“父亲”(而这里的父亲就是包含他们所具有的相同的【属性/方法】)。这样我们就可以多定义一个类,把它叫做父类,在它的里面包含所有的这些子类所具有的相同的【属性/方法】,然后通过继承的方式,让所有的子类都可以访问这些【属性/方法】,而不用每次都在子类的定义中去定义这些【属性/方法】了。

2.原型链实现继承(让子类继承了父类的静态【属性/方法】)

  

// 代码4.1 function Father() { } Father.prototype.say = function() { console.log('I am talking...') } function Son() { } var sonObj_1 = new Son() console.log(sonObj_1.say) // undefined // 原型链实现继承的关键代码 Son.prototype = new Father() var sonObj_2 = new Son() console.log(sonObj_2.say) // function() {...}

看到这句Son.prototype = new Father()你可能有点蒙圈,没关系,我先上个原型链的图,你分分钟就能明白了

对Javascript 类、原型链、继承的理解

对着图我们想一想,首先,一开始Son、Father两个类没有什么关系,所以在访问say的时候肯定是undefined,但是当我们使用了Son.prototype = new Father()后,我们知道通过new Son()生成的对象都会有__proto__属性,而这个属性指向Son.prototype,而这里我们又让它等于了一个Father的对象,而Father类又定义了静态方法say,所以这里我们的sonObj_2通过沿着原型链寻找,寻找到了say方法,于是就可以访问到Father类的静态方法say了。这样就实现了子类继承了父类的静态【属性/方法】,那么如何让子类继承父类的非静态【属性/方法】呢?

3.构造函数实现继承(让子类继承了父类的非静态【属性/方法】)

// 代码4.3 function Father(name) { this.name = name } function Son() { Father.apply(this, arguments) this.sing = function() { console.log(this.name + ' is singing...') } } var sonObj_1 = new Son('jack') var sonObj_2 = new Son('rose') sonObj_1.sing() // jack is singing... sonObj_2.sing() // rose is singing...

在这个例子中,通过在Son的构造函数中利用apply函数,执行了Father的构造函数,所以每一个Son对象实例化的过程中都会执行Father的构造函数,从而得到name属性,这样,每一个Son实例化的Son对象都会有不同的name属性值,于是就实现了子类继承了父类的非静态【属性/方法】

4.组合方式实现继承(组合 原型链继承 + 构造函数继承)

  大家可以先自己思考思考哦,待续。。。

5.寄生组合方式实现继承

  大家可以先自己思考思考哦,待续。。。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyypxx.html