JavaScript 的继承通过原型链和构造函数实现、可以采用多种方式如原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承及寄生组合式继承。 其中,最常用的继承方式是组合继承,因为它结合了原型链和构造函数的优点,避免了各自的缺点。通过构造函数继承属性,通过原型链继承共享的方法和属性,这样即避免了原型链中子类型实例共享父类引用属性的问题,又实现了方法复用。
本文将通过各种常见的继承方式的详细实现来深入探讨JavaScript的继承机制。
原型链继承是最基本的JavaScript继承方法,它利用原型让一个引用类型继承另一个引用类型的属性和方法。
function Parent(){
this.parentProperty = true;
}
Parent.prototype.getParentProperty = function() {
return this.parentProperty;
};
function Child(){
this.childProperty = false;
}
// 继承Parent
Child.prototype = new Parent();
var instance = new Child();
alert(instance.getParentProperty()); // true
这种方法的主要缺点是包含引用类型值的原型属性会被所有实例共享,此外,创建子类型实例时,不能向超类型的构造函数中传递参数。
构造函数继承使用父类的构造函数来增强子类实例,等同于复制父类的实例属性给子类,没有使用原型。
function Parent(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
function Child(name){
// 继承自Parent
Parent.call(this, name);
}
var instance1 = new Child("instance1");
var instance2 = new Child("instance2");
instance1.colors.push("black");
alert(instance1.colors); // "red,blue,green,black"
alert(instance2.colors); // "red,blue,green"
这种方法的优点是可以在子类型构造函数中向超类型构造函数传递参数。但这种方法的缺点是方法都在构造函数中定义,因此函数复用无从谈起。
组合继承(伪经典继承)结合了原型链和构造函数的技术,从而发挥二者之长。用构造函数继承属性,用原型链的方式继承方法。
function Parent(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
Parent.prototype.sayName = function() {
return this.name;
};
function Child(name, age){
// 继承属性
Parent.call(this, name);
this.age = age;
}
// 继承方法
Child.prototype = new Parent();
Child.prototype.constructor = Child;
Child.prototype.sayAge = function() {
return this.age;
};
var instance = new Child("Nicholas", 29);
alert(instance.sayName()); // "Nicholas"
alert(instance.sayAge()); // 29
这是JavaScript中最常用的继承模式。不过,它也有自己的不足:使用Child的实例时,其原型上会存在两份相同的属性/方法。
原型式继承基于已有的对象创建新对象,同时还不必因此创建自定义类型。
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
alert(person.friends); // "Shelby,Court,Van,Rob,Barbie"
Object.create()是ECMAScript 5中的一个新方法,直接指定原型。原型式继承的问题同原型链继承一样,包含引用类型值的属性始终都会共享相应的值,这点对于特定的应用场景是一种缺陷。
寄生式继承是在原型式继承的基础上增强对象,返回构造函数。
function createAnother(original){
var clone = Object.create(original); // 通过调用函数创建一个新对象
clone.sayHi = function() { // 以某种方式来增强这个对象
alert("hi");
};
return clone; // 返回这个对象
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); // "hi"
这种方式同原型式继承几乎是一模一样的,只不过增强的是对象,而不是自定义类型的实例。
寄生组合式继承是对组合继承的进一步优化,通过寄生方式来继承超类的原型,然后再将结果指定给子类的原型。
function inheritPrototype(subType, superType){
var prototype = Object.create(superType.prototype); // 创建对象
prototype.constructor = subType; // 增强对象
subType.prototype = prototype; // 指定对象
}
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function(){
alert(this.age);
};
var instance = new SubType("Nicholas", 29);
instance.sayName(); // "Nicholas"
instance.sayAge(); // "29"
此方式核心代码段为 inheritPrototype
函数中,创建超类原型的一个副本,然后将其赋值给子类的原型,并且将构造器指向子类,目的是为了防止创建子类实例时超类的构造器被重写。寄生组合式继承被认为是引用类型继承的最理想方式。
如何使用JavaScript实现继承?
继承是面向对象编程中的一个重要概念,它允许一个对象(称为子类)继承另一个对象(称为父类)的属性和方法。在JavaScript中,有几种方式可以实现继承。
1. 原型链继承
原型链继承是JavaScript最基本的继承方式。它通过将子类的原型对象指向父类的实例来实现继承。这意味着子类将继承父类的属性和方法,包括原型链上的属性和方法。
2. 构造函数继承
构造函数继承是通过在子类的构造函数中调用父类的构造函数来实现继承。这样子类将获得父类的属性,并且每个实例都有自己的属性的副本。
3. 组合继承
组合继承是将原型链继承和构造函数继承结合起来使用的一种方式。它通过在子类的构造函数中调用父类的构造函数来继承属性,并且将其原型对象指向父类的实例来继承方法。
除了这些方式,还有其他的继承方式,如原型式继承、寄生式继承和寄生组合式继承。根据具体的需求和场景,选择适合的继承方式,可以让我们更好地利用JavaScript的面向对象特性。
最后建议,企业在引入信息化系统初期,切记要合理有效地运用好工具,这样一来不仅可以让公司业务高效地运行,还能最大程度保证团队目标的达成。同时还能大幅缩短系统开发和部署的时间成本。特别是有特定需求功能需要定制化的企业,可以采用我们公司自研的企业级低代码平台:织信Informat。 织信平台基于数据模型优先的设计理念,提供大量标准化的组件,内置AI助手、组件设计器、自动化(图形化编程)、脚本、工作流引擎(BPMN2.0)、自定义API、表单设计器、权限、仪表盘等功能,能帮助企业构建高度复杂核心的数字化系统。如ERP、MES、CRM、PLM、SCM、WMS、项目管理、流程管理等多个应用场景,全面助力企业落地国产化/信息化/数字化转型战略目标。 版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们微信:Informat_5 处理,核实后本网站将在24小时内删除。版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系邮箱:hopper@cornerstone365.cn 处理,核实后本网站将在24小时内删除。