本文详细解析 JavaScript 中两种常见的继承实现方式:原型继承与 call/apply 继承。通过代码示例对比发现,原型继承可完整继承父类属性和方法,但存在引用共享问题;而 call/apply 方式仅能借用构造函数实现属性继承,无法继承 prototype 上的方法。文章总结了各自的适用场景及局限性,帮助开发者根据实际需求选择合适的继承策略。
JavaScript 继承机制概述
本文通过具体实例深入解析 JavaScript 中实现继承的多种技术手段,旨在为开发者提供清晰的参考与指导。
var animal=function(name){ //构造函数
this.name=name;
this.sayhello=function(){
alert("hi我是"+this.name);
};
}
animal.prototype.shout=function(){ //prototype主要作用:给类增加一个新的属性或函数
alert(this.name+"正在叫!");
};
animal.prototype.game=function(){
alert(this.name+"正在玩耍!");
};
var dog=new animal("小黑"); //实例化
dog.sayhello();
dog.shout();
dog.game();
原型继承实现详解
一、原型继承机制
var animal=function(name){
this.name=name;
this.sayhello=function(){
alert("hi我是"+this.name);
};
}
animal.prototype.shout=function(){
alert(this.name+"正在叫!");
};
animal.prototype.game=function(){
alert(this.name+"正在玩耍!");
};
var Dog=function(name){
this.name=name;
this.shout=function(){ //重写父类的函数
alert(this.name+"汪汪叫!");
}
}
Dog.prototype=Cat.prototype=new animal();
var dog=new Dog("小黑");
dog.sayhello();
dog.shout();
dog.game();
var cat=new Cat("小白");
cat.sayhello();
cat.shout();
cat.game();
在原型继承模式中,animal 作为父类(或称为超类),子类通过关联该父类来实现继承关系。
为了优化代码结构,可以封装一个专用函数来统一处理继承逻辑。
var animal=function(name){
this.name=name;
this.sayhello=function(){
alert("hi我是"+this.name);
};
}
Function.prototype.extends=function(superclass){ //extends是保留关键字,不能拿出来单独使用,如var extends=function(){},而这里可以使用是因为他做为函数的属性添加上去
this.prototype=new superclass();
};
animal.prototype.shout=function(){
alert(this.name+"正在叫!");
};
animal.prototype.game=function(){
alert(this.name+"正在玩耍!");
};
var Dog=function(name){
this.name=name;
this.shout=function(){
alert(this.name+"汪汪叫!");
}
}
Dog.extends(animal);
var dog=new Dog("小黑");
dog.sayhello();
dog.shout();
dog.game();
var dog=new Dog("小白");
dog.sayhello();
dog.shout();
dog.game();
call 与 apply 继承方式分析
二、利用 call 和 apply 实现继承(局限性分析)
var animal=function(name){
this.name=name;
this.sayhello=function(){
alert("hi我是"+this.name);
};
}
animal.prototype.shout=function(){
alert(this.name+"正在叫!");
};
animal.prototype.game=function(){
alert(this.name+"正在玩耍!");
};
var Dog=function(name){
animal.call(this,name);
}
var dog=new Dog("小黑");
dog.sayhello();
dog.shout();
dog.game();
执行上述代码后,控制台输出结果为:hi我是小黑。
若尝试调用未正确继承的方法,系统将报错:TypeError: dog.shout is not a function。
使用 call 或 apply 方法仅能改变函数执行时的 this 指向,而无法直接继承通过 prototype 添加的方法。
总结而言,call 和 apply 继承方式适用于那些没有 prototype 属性,或者不需要继承 prototype 中定义的属性与函数的类。这是因为 call 和 apply 仅实现了方法的借用替换,并未执行对象属性和函数的深层复制操作。
相比之下,原型继承机制能够完整地继承父类的所有属性和函数。
需要注意的是,若子类中定义了与父类同名的属性,必须删除子类的原有属性,才能访问到继承自父类的属性值。
如需进一步了解 JavaScript 相关知识,可参考本站系列教程:《javascript面向对象入门教程》、《JavaScript中json操作技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》。
希望本文的阐述能对您的 JavaScript 程序设计工作提供实质性帮助。