js继承

原型链继承

首先来看下原型和原型链的区别 原型(Prototype)

原型是JavaScript中实现对象继承的核心概念之一。每个JavaScript对象(除了null)都与一个原型对象相关联,这个原型对象通过内部属性[[Prototype]](在旧版JavaScript中可通过__proto__属性访问)与对象建立联系。原型对象本身也是普通的JavaScript对象,它可以有自己的属性和方法。

当试图访问一个对象的属性或方法时,JavaScript引擎首先在该对象自身的属性中查找。如果在当前对象上找不到该属性或方法,引擎会沿着[[Prototype]]链向上查找,直到找到该属性或方法,或者查找到null(即到达原型链的顶端)。这种基于原型的属性和方法查找机制就是所谓的"原型链"。

原型链(Prototype Chain)

原型链是通过对象的[[Prototype]]属性形成的对象间的连接链条。当一个对象的属性或方法在自身定义中未找到时,JavaScript引擎会自动到其原型对象中去查找。如果原型对象还有自己的原型(即[[Prototype]]),那么查找过程会进一步延续到原型的原型,直到找到所需的属性或方法,或者查找到原型链的尽头(null)。

原型与原型链的区别

原型和原型链虽然密切相关,但它们描述的是对象继承机制的不同方面:

  • 原型:特指一个对象直接关联的那个原型对象,它是对象继承属性和方法的直接来源。原型本身是一个普通的JavaScript对象,可以定义属性、方法,也可以有自己的原型(即形成原型链)。

  • 原型链 :是由一个对象与其原型、原型的原型、直至null形成的链式结构。原型链是实现对象属性和方法继承的查找路径,它体现了对象间继承关系的层级结构。

简单来说,原型 是个体对象,是原型链中的一个节点;原型链 则是由这些原型节点通过[[Prototype]]链接起来的整体结构。理解原型和原型链的区别有助于更好地掌握JavaScript的面向对象编程和继承机制。

上图来自[JS]深入理解原型和原型链以及区别(包含面试题详解) - 掘金 (juejin.cn)

javascript 复制代码
// 1. 定义父类(基类):首先创建一个基础构造函数,如Person,并在其原型(Person.prototype)上定义共享的方法和属性。
function Person(name, age) {
    this.name = name
    this.age = age
}

Person.prototype.sayHello = function () {
    console.log(`Hello, my name is ${this.name}, and I'm ${this.age} years old.`)
}
// 2. 创建子类:定义一个新的构造函数,如Student,并使其原型对象指向父类的一个实例。这样,子类实例就可以通过原型链访问到父类的属性和方法。
function Student(name, age, major) {
    Person.call(name, age)
    this.major = major
}

Student.prototype = Object.create(Person.prototype)
// 修复子类的constructor属性:由于我们直接将子类的原型设置为父类实例,子类的constructor属性不再指向Student,而是指向Person。为了修复这个问题,通常会手动设置回来:
Student.prototype.constructor = Student
// 添加子类特有的方法:在子类的原型上添加专属于子类的方法,这些方法不会影响到父类或其他继承自同一父类的子类。
Student.prototype.sayMajor = function () {
    console.log(`My major is ${this.major}.`)
}
// 使用示例
const student = new Student("Alice", 20, "Computer Science"); 
student.sayHello(); // 输出:Hello, my name is Alice, and I'm 20 years old. student.sayMajor(); // 输出:My major is Computer Science.

Class继承

在JavaScript中,从ES6(ECMAScript 6)开始引入了基于类(Class)的面向对象编程模型,使得创建和继承类变得更加直观和简洁。以下是如何使用class关键字实现类继承的示例:

javascript 复制代码
           // 定义父类(基类)
            class ParentClass {
                constructor(param1, param2) {
                    this.property1 = param1
                    this.property2 = param2
                }

                method1() {
                    console.log('ParentClass.method1 called')
                }
            }

            // 定义子类
            class ChildClass extends ParentClass {
                constructor(param1, param2, childParam) {
                    super(param1, param2) // 调用父类构造函数,传递必要的参数
                    this.childProperty = childParam
                }

                // 继承父类方法并进行覆盖(重写)
                method1() {
                    console.log('ChildClass.method1 called')
                    super.method1() // 调用父类的method1方法
                }

                // 定义子类特有的方法
                childMethod() {
                    console.log('ChildClass.childMethod called')
                }
            }

            // 使用子类
            const childInstance = new ChildClass('value1', 'value2', 'childValue')

            childInstance.method1() // 输出:ChildClass.method1 called
            //       ParentClass.method1 called

            childInstance.childMethod() // 输出:ChildClass.childMethod called
  • 使用class关键字定义类,如class ParentClassclass ChildClass
  • 在父类(ParentClass)中定义构造函数(constructor),用于初始化实例属性。同时,可以定义类的方法(如method1)。
  • 子类(ChildClass)通过extends关键字继承父类。在子类构造函数中,使用super关键字调用父类构造函数,以继承父类的属性。
  • 子类可以覆盖(重写)从父类继承的方法,如method1。在覆盖的方法内部,可以使用super.methodName()调用父类的同名方法。
  • 子类可以定义自己的特有方法,如childMethod
  • 通过new ChildClass(...)创建子类实例,并使用实例调用其方法。

通过这种方式,JavaScript的类继承机制实现了代码复用、层次化的对象结构以及多态等面向对象编程特性。需要注意的是,尽管JavaScript使用了class关键字,但其底层仍然是基于原型链的继承机制。类语法提供了一种更易于理解和使用的封装,简化了面向对象编程的实现。

相关推荐
zqx_722 分钟前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己39 分钟前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称1 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色1 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2342 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河2 小时前
CSS总结
前端·css
BigYe程普2 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
余生H2 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
程序员-珍2 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai2 小时前
网站开发的发展(后端路由/前后端分离/前端路由)
前端