javascript的继承原理有八种数据,其中没有function,因为function是object这个大类包含的。也就是说,所有的函数都是对象。当我们自己声明一个类时,得到的引用是一个函数引用,默认继承自内置的Object对象,但是由于javascript的顶层父类(Object和Function)设计的有点乱,而且它不是通用性,这里我们用两个通用类来演示继承的实现。将子类声明的引用原型的[[Prototype]]指向父类声明的引用原型,属于继承实现的一部分。另一部分是指向父类声明引用的子类声明引用的[[Prototype]]。完整代码如下:classA{}classB{}//B的实例继承了A的实例//第一部分:转换B.Prototype的[[Prototype]]指向A.prototypeObject.setPrototypeOf(B.prototype,A.prototype);//B继承了A的静态属性//第二部分:将B的[[Prototype]]指向AObject.setPrototypeOf(B,A);常量b=新B();下面的讨论忽略顶层父类Object和Function,只讨论普通继承类之间的关系。刚才说了,继承只需要实现两部分,如下图:如果你想知道为什么这个方法需要执行两步,添加两个[[Prototype]]引用,那么你需要知道如何构造函数提供了我们所看到的。”类别。首先,在声明构造函数时,引擎会创建两个对象:一个是构造函数本身的函数对象,另一个是构造函数的原型对象——object类型的对象,由类的prototype属性指定构造函数。引用。构造函数上的属性一般可以理解为静态属性,可以直接调用,不需要生成实例(这样想,构造函数本身也是一个函数对象,声明的时候就存在,它的属性可以被使用,和我们新手时才能使用的Instances本质上是一样的);原型对象的属性只能被实例调用,所有实例共享。然后,当调用new时,新创建的对象在执行构造函数之前将其[[Prototype]]属性设置为构造函数的原型对象。借用上图,效果应该是这样的:所以这体现了我们右边部分的重要性:Son.prototype.[[Prototype]]=Father.prototype。根据js原型链规则,在查找一个属性时,如果在当前对象上没有找到,就会顺着它的原型链,也就是[[Prototype]]属性,依次查找上面的对象一。所以在我给出的例子中,搜索顺序是这样的:从Son.prototype到Father.prototype的那一行是通过我们的实现继承连接起来的。所以在做了这一步之后,在Son类的实例中找不到的属性,都可以在Father.prototype上找到,甚至可以在这条链上找到更远的原型对象。继承的实现应该到此结束。和其他语言一样,类实例已经可以访问父类的所有属性,但并不完美:类的静态属性和方法也需要继承。在es5中,静态属性和方法直接写在构造函数的函数对象的属性中;在es6中,类声明中使用了static关键字。所以我们在构造函数对象(理论上是父子关系)中加入[[Prototype]],将它们组织成一个原型链,这样在寻找Son的静态方法时,我们会按照如下顺序寻找:This完了,es6类继承解决方案。实现:我这里贴出两个实现,一个是es5的寄生组合继承,一个是es6的extends继承和原理。ES5催生了很多继承方式,主要有原型链继承、借用构造函数、组合继承、寄生继承和寄生组合继承。其中寄生组合继承效果最好,代码如下:(来源:https://segmentfault.com/a/11...)//父类函数SuperType(name){//父类实例属性this.name=名称;this.colors=["red","blue","green"];}//父类原型方法SuperType.prototype.sayName=function(){alert(this.name);};//子类函数SubType(姓名,年龄){SuperType.call(this,姓名);//1.借用构造函数:继承父类的实例属性;this.age=age;}//2.寄生继承:继承父类原型的副本,强行赋值给子类原型,实现继承父类原型的方法。inheritPrototype(SubType,SuperType);SubType.prototype.sayAge=function(){alert(this.age);};functioninheritPrototype(subType,superType){varprototype=object(superType.prototype);//创建父类原型prototype.constructor=subType;的副本//将copy的constructor属性指向子类subType.prototype=prototype;//将子类的prototype属性指向副本}因为es5条件有限,不支持直接操作[[Prototype]],所以只能通过创建原型对象的副本来比较笨拙的实现。而且最终没有实现静态属性的继承。以下是es6代码:(来源:类的继承——ECMAScript6入门(ruanyifeng.com))}我的方法(味精){控制台。日志(“实例”,味精);}}classChildextendsParent{staticmyMethod(msg){super.myMethod(msg);//super稍后会讨论}myMethod(msg){super.myMethod(msg);}}Child.myMethod(1);//static1varchild=newChild();child.myMethod(2);//实例2es6的代码非常简洁。最后提一下super关键字。在es6中,如果子类有构造函数,必须调用super的构造函数,调用后才能使用this。super关键字在声明时保留其类引用,实际调用时指向其当前父类。super关键字是我目前知道的,以后可能会看ECMA规范等更权威更深入的文档来了解。
