无锡网站设计服务,免费网站app,做seo网站优化多少钱,企业采购简单总结继承的几种方式 JavaScript作为一门弱类型的语言#xff0c;本着精简的原则#xff0c;它取消了类的概念#xff0c;只有对象的概念#xff0c; 更是有万物皆对象的说法。在基于类的面向对象方式中#xff0c;对象#xff08;object#xff09;依靠类#xff0…简单总结继承的几种方式 JavaScript作为一门弱类型的语言本着精简的原则它取消了类的概念只有对象的概念 更是有万物皆对象的说法。在基于类的面向对象方式中对象object依靠类class来产生。 而在基于原型的面向对象方式中对象object则是依靠构造器constructor 利用 原型prototype 构造出来的。而JavaScript语言正是如此它是通过一种叫做原型prototype的方式来实现面向对象编程的。 它和其他的面向对象类编程语言一样只是它的实现方式不同而已或者说他们采用了不同的面向对象设计哲学。 那么下面就让我们来简单总结一下继承的几种方式 扩展原型对象实现继承构造函数有一个 prototype 属性指向的就是原型对象通过给原型对象添加属性和方法让构造函数的实例 都可以访问到从而实现继承 function Animal(name,color,say){this.name name;this.color color;this.say function(){console.log(喵喵喵);}
}var cat new Animal(cat,white);
// 如果给Animal的prototype属性上添加个 cry 方法 那么实例对象 cat将也会有 cry方法
Animal.prototype.cry function(){console.log(呜呜呜);
} 替换原型对象实现继承 (常用类型)为什么会有该方式呢 其实上面扩展原型对象的方法已经很方便了但是为什么我们还需要使用该方式呢试想一下 当我们需要给构造函数的原型对象添加许多属性和方法的时候岂不是要写很多冗余重复的代码。例如上面的例子 看下面代码 // 我们要给 构造函数Animal 添加很多的方法 即Animal.prototype.aaa function(){};Animal.prototype.bbb function(){};Animal.prototype.ccc function(){};Animal.prototype.ddd function(){};Animal.prototype.eee function(){};...... // 诸如这样的话代码就显得不那么优雅高效了吧。实现方式 重新给构造函数的prototype属性原型对象赋值指向一个全新的对象在这个对象中添加属性和方法注 一定要添加一个constructor属性并且指向构造函数本身 具体看代码 Animal.prototype {// 一定要指明constructor属性不然的话会根据原型链查找一直到Object.prototypeconstructor : Animal; saying : function(){},crying : function(){},doing : function(){}......}混入继承混入继承的使用场景已知对象 o1, o2, 需要把 o1中的功能属性方法拷贝到 o2 中去实现方式 用 for...in... 对 o 进行遍历(可以将混入继承的模式封装成函数)如下所示 // target : 目标对象接收数据的对象// source : 接收对象 数据从哪个对象中来function mixin(target,source){for(var key in source){target[key] source[key];}return target;}原理其实很简单jQuery中的$.extend 方法利用的就是混入继承的原理原型 混入继承本质上就是对混入继承的一次运用只不过目标对象为原型对象而已 // 运用上面封装的混入继承的函数 将对象{a:10,b:20,c:function(){}}的功能考本到Animal原型对象上去mixin(Animal.prototype, {a:10,b:20,c:function(){}} ); // 还可以 这样操作 给Animal构造函数 的原型对象添加一个extend方法在该方法中调用mixin函数这样的话也可以实现Animal.prototype.extend function(){mixin(Animal.prototype, source);}// 不过两种方法没有本质之差看大家易于接受哪个了经典继承 — 道格拉斯《JavaScript语言精粹》中提到的一种继承模型实现的功能已知一个对象 o1 需要创建一个新的对象 o2 这个新的对象需要继承自对象 o1代码如下 // 可以将经典继承 封装成一个函数function create(o){function F(){}; // 创建一个构造函数F.prototype o; // 将F 的原型指向 对象 o;return new F(); // 将 构造函数的实例 返回出去这样的话 F的实例对象就会继承自 o}var o2 create(o1); // 即o2 继承于 o1 ; o2.__proto__ o1;使用场景 要创建一个对象不需要关心构造函数,新对象需要继承自另一个指定的对象ES5中 Object.create( ) 的实现原理就源自于经典继承借用构造函数 实现继承先看一下代码 再解释 // 需要两个构造函数function Person(name,agegender){ this.name name;this.age age;this.gender gender;}// function Student(name,age,){// this.name name;// this.age age;// this.gender gender;// }// 这样的话 nameage 属性都一样就会产生重复的代码 我们可以巧妙的利用call 来简单的实现function Student(name,age){Person.call(this,name,age); // 其实就是用 call的方法call借用Person的功能this.gender gender;} 借用Person中的构造函数的功能this表示构造函数的实例即Student的实例对象可以继承name,age属性借用构造函数实现继承子构造函数借用父构造函数来完成给子类Student的实例添加属性注意由于要借用父类构造函数所以父类构造函数的功能对子类对象要适用例如下面情况就最好不用call // 需要两个构造函数
function Person(name,agegender){ this.name name;this.age age;this.gender gender;
}
// function Student(name,age,){
// this.name name;
// this.age age;
// }
function Student(name,age){Person.call(this,name,age);
}上述情况就最好不要使用call来借用父类构造函数Person的功能了因为gender属性是Student子类构造函数 并不需要的这样的话就会在Student中产生不必要的属性和方法如果子类函数还要有gender方法的话那么就会和之前的产生冲突交叉污染其他情况遇到需要实现功能该对象上没有这个功能可以适当地去寻找已经有功能的对象转载于:https://www.cnblogs.com/guoqi77/p/Q_Inherit.html