《你不知道的JavaScript》:拎清原型继承的原理

版权声明:本文为微信公众号前端小二版权所有,如需转载可私信或关注文末微信公众号留言。 https://blog.csdn.net/qq_34832846/article/details/86505917

虽然在js中没有类,构造函数本质上也只是一个普通函数,new关键字调用一个构造函数来创建一个新对象,也是js在努力模仿面向对象语言中类new对象的实现,这个模仿过程也对开发者造成很大误导,但不能否认的是也降低了理解的门槛,在初期快速上手阶段还是很有帮助的。

至少我刚开始不是很明白js的原型链时,就是按照面向对象的类思路来写的,并且在js中也都可以实现js版的类、实例对象、成员属性、成员方法、继承、多态和封装,所以其实就当个面向对象的语言来写,在初期也是没什么问题的。但是在慢慢理解js与面向对象语言的区别后,虽然还是正常使用这些面向对象的标准概念,但本质还是要分清的,这对于迈向js精通是绝对必要。

上篇讲的是js的构造函数,也涉及到js的原型,而要想原型发挥作用,就必须要有个原型继承来承接:

function Foo(name){
    this.name = name;
};
Foo.prototype.showName = function(){
    console.log(this.name)
}
var obj = new Foo("nitx");
obj.showName();     // nitx

对象obj就是通过原型继承来关联到Foo.prototype对象的。

那么上述实现过程用到原型继承,还有什么场景需要用到原型继承呢?

就是面向对象中的继承

js版的继承其实就是通过原型继承来关联到“父类”的,看下面代码示例:

function Foo(name){
    this.name = name;
}
Foo.prototype.showName = function(){
    console.log(this.name);
}
function Bar(name, age){
    Foo.call(this, name);
    this.age = age;
}
Bar.prototype = Object.create(Foo.prototype);   // 这行代码是实例子类继承父类的关键
Bar.prototype.showAge = function(){
    console.log(this.age);
}
var b = new Bar("nitx", 30);
b.showName();       // nitx
b.showAge();        // 30

上例用面向对象的概念解释就是子类Bar继承父类Foo,但js版的理解是这样子的:Foo函数的原型对象通过Object.create()方法创建一个新对象,这个新对象的[[Prototype]]属性指向Foo.prototype对象,并且通过赋值操作符来修改Bar.prototype这个标识符原本指向的对象,改为指向刚才新创建的对象。所以这个过程,就把Bar函数原有的Bar.prototype对象给抛弃掉了。

所以这步操作的作用就是原型继承。至于Bar函数中的Foo.call(this, name);,就是通过call关键字将Foo函数内的this对象绑定到Bar函数内的this对象上,从而借用Foo函数内作用域的执行代码为Bar函数执行时所用。这样就完成了一个模拟类继承的过程。不得不说,这是一个天才般的设计,再次为Brendan Eich点个赞,上柱香,拜一拜~~~~

所以ES6中的class继承,其核心实现原理就是这样差不多,只是通过语法糖,来使之写起来和java面向对象写法一样,唔,但自己心里也拎的清,这个class就是样子货罢了,不受你迷惑,不受你迷惑,不受你迷惑…

喜欢本文请扫下方二维码,关注微信公众号: 前端小二,查看更多我写的文章哦,多谢支持。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_34832846/article/details/86505917