手机版

Javascript继承机制的实现

时间:2021-11-24 来源:互联网 编辑:宝哥软件园 浏览:

选择基类后,您可以创建它的子类。是否使用基类完全由您决定。有时,您可能想创建一个不能直接使用的基类,但它仅用于为子类提供通用功能。在这种情况下,基类被视为抽象类。尽管ECMAScript没有像其他语言那样严格地定义抽象类,但有时它确实会创建不允许使用的类。通常,我们称这种类为抽象类。创建的子类将继承超类的所有属性和方法,包括构造函数和方法的实现。请记住,所有的属性和方法都是通用的,因此子类可以直接访问这些方法。子类还可以添加超类中没有的新属性和方法,或者覆盖超类中的属性和方法。4.2.1继承方式与其他函数相同。ECMAScript中实现继承的方式不止一种。这是因为JavaScript中的继承机制没有明确定义,而是通过模仿实现的。这意味着所有的继承细节都不是由解释器处理的。作为开发人员,您有权决定最合适的继承方法。1.当对象模拟构思最初的ECMAScript时,并没有设计对象模拟的意图。它是在开发人员开始了解函数是如何工作的,尤其是如何在函数环境中使用这个关键字之后开发的。原理如下:构造函数使用这个关键字给所有属性和方法赋值(即采用类声明的构造函数)。因为构造函数只是一个函数,所以可以把ClassA的构造函数变成ClassB的方法,然后调用它。ClassB接收在ClassA的构造函数中定义的属性和方法.例如,以下列方式定义类别a和类别B:(9500 . 163.com)。

还记得吗?关键字这是指当前由构造函数创建的对象。但是,在此方法中,这是指它所属的对象。原则是使用ClassA作为常规函数来建立继承机制,而不是作为构造函数。下面的构造函数ClassB可以用来实现继承机制:

在这段代码中,ClassA被赋予了方法newMethod(记住,函数名只是指向它的指针)。然后调用该方法,并将其传递给ClassB构造函数的参数sColor。最后一行代码删除了对ClassA的引用,以便以后不再调用它。的所有新属性和方法都必须在删除新方法的代码行后定义。否则,超类的相关属性和方法可能会被覆盖:

为了证明前面代码的有效性,您可以运行以下示例:

有趣的是,对象模拟可以支持多重继承。也就是说,一个类可以继承多个超类。UML表示的多继承机制如图4-2所示。

图4-2例如,如果有两个类,ClassX和Class,ClassZ想要继承这两个类,他可以使用下面的代码:

这里有一个缺点。如果ClassX和Class具有相同名称的属性或方法,则Class具有高优先级,因为它继承了最后一个类。除了这个小问题,用对象模拟实现多继承机制也很容易。由于这种继承方法的流行,ECMAScript的第三版向Function对象添加了两种新方法,即call()和apply()。2.call()方法call()方法是与经典对象模拟方法最相似的方法。它的第一个参数用作此的对象。其他参数直接传递给函数本身。例如:

在本例中,函数sayColor()是在对象外部定义的,即使它不属于任何对象,也可以引用关键字this。对象obj的颜色属性等于“红色”。调用call()方法时,第一个参数是obj,表示这个关键字在sayColor()函数中的值应该是obj。第二个和第三个参数是字符串。它们与sayColor()函数中的参数前缀和后缀相匹配,将显示消息“颜色是红色,一种非常好的索引颜色”。要将此方法与继承机制的对象模拟方法一起使用,只需替换前三行中的赋值、调用和删除代码:

这里,我们希望ClassA中的关键字this等于新创建的ClassB对象,所以这是第一个参数。第二个参数sColor是这两个类的唯一参数。3.apply()方法apply()方法有两个参数,用作此的对象,以及要传递给函数的参数数组。例如:

除了现在调用apply()方法之外,此示例与上一示例相同。调用apply()方法时,第一个参数仍然是obj,表示sayColor()中这个关键字的值应该是obj。第二个参数是由两个字符串组成的数组,它匹配sayColor()的参数前缀和后缀。生成的消息仍然是“颜色是红色,一个非常好的颜色索引”,并将被显示。此方法也用于替换前三行中分配、调用和删除新方法的代码:

同样,第一个参数仍然是这个。第二个参数是一个只有一个值颜色的数组。您可以将ClassB的整个参数对象作为第二个参数传递给apply()方法:

当然,参数对象只有在超类中的参数顺序与子类中的完全一致时才能传递。如果没有,您必须创建一个单独的数组,并按照正确的顺序放置参数。此外,还可以使用call()方法。4.原型链继承最初用于ECMAScript中的原型链。在前一章中,我们介绍了如何定义类的原型。原型链以这种方式扩展,并以一种有趣的方式实现继承机制。正如您在上一章中了解到的,原型对象是一个模板,所有要实例化的对象都基于这个模板。总之,原型对象的任何属性和方法都会传递给该类的所有实例。原型链使用这个函数来实现继承机制。如果前一个例子中的类被prototype重新定义,它们的形式如下:

原型链的魔力在于突出的代码行。这里,将ClassB的prototype属性设置为ClassA的一个实例。这很有意义,因为我想要ClassA的所有属性和方法,但我不想将它们逐个分配给ClassB的原型属性。有没有比给原型属性分配一个ClassA实例更好的方法?请注意,当调用ClassA的构造函数时,没有参数传递给它。这是原型链中的标准做法。确保构造函数没有参数。类似于对象模拟,子类的所有属性和方法都必须在原型属性被分配后出现,因为在它之前分配的所有方法都将被删除。为什么呢?因为原型属性被新对象替换,所以添加了新方法的原始对象将被销毁。因此,将name属性和sayName()方法添加到ClassB类的代码如下:

您可以通过运行以下示例来测试这段代码:

此外,在原型链中,instanceof运算符以一种独特的方式运行。对于ClassB的所有实例,instanceof为ClassA,ClassB都返回true。例如:

在弱类型的ECMAScript世界中,这是一个非常有用的工具,但是在使用对象模拟时不能使用它。原型链的缺点是不支持多重继承。记住,原型链用另一种类型的对象重写类的原型属性。5.混合模式这种继承模式使用构造函数来定义类,而不使用任何原型。模拟的主要问题是必须使用构造函数方法(如前一章所学),这不是最佳选择。但是,如果使用原型链,则不能使用带参数的构造函数。开发者应该如何选择?答案很简单,两者并用。在前一章中,您了解到创建类的最佳方式是通过构造函数定义属性,通过原型定义方法。这种方法也适用于继承机制,即对象假装继承构造函数的属性,原型链继承原型对象。用这两种方法重写前面的例子。代码如下:

在本例中,继承机制由两行突出显示的代码实现。在第一行突出显示的代码中,在ClassB构造函数中,使用一个对象来假装继承ClassA类的sColor属性。在第二行突出显示的代码中,原型链用于继承ClassA类的方法。由于这种混合方法使用原型链,instanceof运算符仍然可以正确运行。以下示例测试此代码:

版权声明:Javascript继承机制的实现是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。