脚本宝典收集整理的这篇文章主要介绍了js实例教程-JavaScript实现继承方式的整理,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。
JavaScript是作为面向对象的弱类型语言,继承是其非常强大的特性。许多OO语言都支持两种继承方式,就是接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。因为函数没有签名,所以在ECMAScript中无法实现接口继承,只支持实现继承,而实现继承又主要依靠原型链来实现。
为了实现继承,我们先定义一个父类:
function PErson(){ this.name = name || "person"; this.sayName = function (){ alert(this.name); } } Person.PRototype.greet = function(){ alert("Hi,i'm " + this.name + "!"); }
重点:将父类的实例作为子类的原型
function Boy(){ } Boy.prototype = new Person(); Boy.prototype.name = "Mike"; VAR person1 = new Boy(); console.LOG(person1.name); //Mike person1.sayName(); //Mike person1.greet(); //Hi,i'm Mike! console.log(person1 instanceof Boy); //true console.log(person1 instanceof Person); //true
特点:
这是一个很简单纯粹的继承关系,实例是子类的实例,同时也是父类的实例; 当父类添加原型方法或属性的时候,子类能够及时地访问到。
缺点:
原型对象中的引用属性是共享的; 无法实现多继承; 在创建子类实例时,无法向父类的构造函数传递参数; 为子类新增属性和方法时,必须先用实例替换原型后,再定义方法。
注意:在通过原型链实现继承时,不能使用对象字面量创建原型的方法,否则会重写原型链,导致错误。
alert(Object.prototype.isPrototypeOf(person1)); //true alert(Boy.prototype.isPrototypeOf(person1)); //true alert(Person.prototype.isPrototypeOf(person1)); //true
使用isPrototypeOf()方法可以测试,上面三个输出表示只要是原型链中出现过的原型,都可以说是该原型链所派生的实例的原型。
重点:使用父类的构造函数来增强子类实例,通过使用call()和apply()方法在新创建的对象上执行构造函数,等于是复制父类的实例属性给子类(并没有用到原型)。
function Boy(name){ Person.call(this); this.name = name || "boy"; } var person1 = new Boy(); console.log(person1.name); //boy person1.sayName(); //boy console.log(person1 instanceof Boy); //true console.log(person1 instanceof Person); //false
特点:
解决了子类实例共享父类引用属性的问题; 子类实例创建的时候可以传参;
可同时call多个父类对象实现多继承。
缺陷:
子类只能继承父类的实例属性和方法,不能继承原型属性和方法;
实例是子类实例,不是父类实例; 无法实现函数复用,影响性能。
重点:将原型链和借用构造函数的技术组合到一块,使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。
function Boy(){ Person.call(this); this.name = name || "boy"; } Boy.prototype = new Person(); Boy.prototype.constructor = Person; //显式调整constructor属性的指向 var person1 = new Boy(); console.log(person1.name); //boy person1.sayName(); //boy console.log(person1 instanceof Boy); //true console.log(person1 instanceof Person); //true
特点:
既可以继承实例属性和方法,也可以继承原型属性和方法; 既是子类实例,又是父类; 子类实例创建的时候可以传参; 可以实现函数复用。
重点:借助原型可以基于已有的对象创建新对象,同时不必创建自定义类型,并没有使用到严格意义上的构造函数。其思想可以用下面的函数来说明:
function object(o) { function F(){} F.prototype = o; return new F(); }
下面是一个实例:
var person = { name:"Mike", friends:["Shelby","Court","Van"] }; var anotherPerson =new Object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson =new Object(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); alert(person.friends); //"Shelby","Court","Van","Rob","Barbie"
原型式继承的本质就是浅复制,以一个对象为模板来复制出新的对象。
重点:创建一个仅用于封装继承过程的函数,该函数在内部以某种形式来增强对象,最后再像真正是它做了所有工作一样返回对象。
function createAnother(original) { var clone =new Object(original); clone.sayHi = function () { alert("Hi"); }; return clone; } var person = { name:"Mike", friends:["Shelby","Court","Van"] }; var anotherPerson = createAnother(person); anotherPerson.sayHi(); //"Hi"
寄生式继承就是把原型式继承再次封装,然后在对象上扩展新的方法,再把新对象返回。它不能做到函数复用。
组合继承最大的问题在于无论什么情况,都会调用两次超类型构造函数:一次在创建子类型原型的时候,一次在子类型构造函数内部。寄生组合式继承解决了这个问题。
function Boy(name){ Person.call(this); this.name = name || "boy"; } (function(){ // 创建一个没有实例方法的类 var Super = function(){}; Super.prototype = Person.prototype; //将实例作为子类的原型 Boy.prototype = new Super(); Boy.prototype.constructor = Boy; })(); var person1 = new Boy(); console.log(person1.name); //boy person1.sayName(); //boy console.log(person1 instanceof Boy); //true console.log(person1 instanceof Person); //true
寄生组合式继承是最理想的一种继承方式,但是实现比较复杂。
JavaScript是作为面向对象的弱类型语言,继承是其非常强大的特性。许多OO语言都支持两种继承方式,就是接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。因为函数没有签名,所以在ecmascript中无法实现接口继承,只支持实现继承,而实现继承又主要依靠原型链来实现。
为了实现继承,我们先定义一个父类:
function Person(){ this.name = name || "person"; this.sayName = function (){ alert(this.name); } } Person.prototype.greet = function(){ alert("Hi,i'm " + this.name + "!"); }
重点:将父类的实例作为子类的原型
function Boy(){ } Boy.prototype = new Person(); Boy.prototype.name = "Mike"; var person1 = new Boy(); console.log(person1.name); //Mike person1.sayName(); //Mike person1.greet(); //Hi,i'm Mike! console.log(person1 instanceof Boy); //true console.log(person1 instanceof Person); //true
特点:
这是一个很简单纯粹的继承关系,实例是子类的实例,同时也是父类的实例; 当父类添加原型方法或属性的时候,子类能够及时地访问到。
缺点:
原型对象中的引用属性是共享的; 无法实现多继承; 在创建子类实例时,无法向父类的构造函数传递参数; 为子类新增属性和方法时,必须先用实例替换原型后,再定义方法。
注意:在通过原型链实现继承时,不能使用对象字面量创建原型的方法,否则会重写原型链,导致错误。
alert(Object.prototype.isPrototypeOf(person1)); //true alert(Boy.prototype.isPrototypeOf(person1)); //true alert(Person.prototype.isPrototypeOf(person1)); //true
使用isPrototypeOf()方法可以测试,上面三个输出表示只要是原型链中出现过的原型,都可以说是该原型链所派生的实例的原型。
重点:使用父类的构造函数来增强子类实例,通过使用call()和apply()方法在新创建的对象上执行构造函数,等于是复制父类的实例属性给子类(并没有用到原型)。
function Boy(name){ Person.call(this); this.name = name || "boy"; } var person1 = new Boy(); console.log(person1.name); //boy person1.sayName(); //boy console.log(person1 instanceof Boy); //true console.log(person1 instanceof Person); //false
特点:
解决了子类实例共享父类引用属性的问题; 子类实例创建的时候可以传参;
可同时call多个父类对象实现多继承。
缺陷:
子类只能继承父类的实例属性和方法,不能继承原型属性和方法;
实例是子类实例,不是父类实例; 无法实现函数复用,影响性能。
重点:将原型链和借用构造函数的技术组合到一块,使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。
function Boy(){ Person.call(this); this.name = name || "boy"; } Boy.prototype = new Person(); Boy.prototype.constructor = Person; //显式调整constructor属性的指向 var person1 = new Boy(); console.log(person1.name); //boy person1.sayName(); //boy console.log(person1 instanceof Boy); //true console.log(person1 instanceof Person); //true
特点:
既可以继承实例属性和方法,也可以继承原型属性和方法; 既是子类实例,又是父类; 子类实例创建的时候可以传参; 可以实现函数复用。
重点:借助原型可以基于已有的对象创建新对象,同时不必创建自定义类型,并没有使用到严格意义上的构造函数。其思想可以用下面的函数来说明:
function object(o) { function F(){} F.prototype = o; return new F(); }
下面是一个实例:
var person = { name:"Mike", friends:["Shelby","Court","Van"] }; var anotherPerson =new Object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson =new Object(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); alert(person.friends); //"Shelby","Court","Van","Rob","Barbie"
原型式继承的本质就是浅复制,以一个对象为模板来复制出新的对象。
重点:创建一个仅用于封装继承过程的函数,该函数在内部以某种形式来增强对象,最后再像真正是它做了所有工作一样返回对象。
function createAnother(original) { var clone =new Object(original); clone.sayHi = function () { alert("Hi"); }; return clone; } var person = { name:"Mike", friends:["Shelby","Court","Van"] }; var anotherPerson = createAnother(person); anotherPerson.sayHi(); //"Hi"
寄生式继承就是把原型式继承再次封装,然后在对象上扩展新的方法,再把新对象返回。它不能做到函数复用。
组合继承最大的问题在于无论什么情况,都会调用两次超类型构造函数:一次在创建子类型原型的时候,一次在子类型构造函数内部。寄生组合式继承解决了这个问题。
function Boy(name){ Person.call(this); this.name = name || "boy"; } (function(){ // 创建一个没有实例方法的类 var Super = function(){}; Super.prototype = Person.prototype; //将实例作为子类的原型 Boy.prototype = new Super(); Boy.prototype.constructor = Boy; })(); var person1 = new Boy(); console.log(person1.name); //boy person1.sayName(); //boy console.log(person1 instanceof Boy); //true console.log(person1 instanceof Person); //true
寄生组合式继承是最理想的一种继承方式,但是实现比较复杂。
总结:这里整理了JavaScript实现继承的几种方法,各有优缺点,在学习过程中一定要理解透彻。
觉得可用,就经常来吧!Javascript技巧 脚本宝典 欢迎评论哦! js技巧,巧夺天工,精雕玉琢。小宝典献丑了!
以上是脚本宝典为你收集整理的js实例教程-JavaScript实现继承方式的整理全部内容,希望文章能够帮你解决js实例教程-JavaScript实现继承方式的整理所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。