JavaScript继承与原型链

  1. 继承和原型链是什么?
    1.1 在继承中,子类继承父类的特征和行为,使得子类对象具有父类的实例域和方法。这意味着子类可以使用父类的方法和属性,使用继承的目的是为了更好设置实例的公共属性和方法,如下例子:

      // 以类的形式说明继承,直观一点// 父类class Animal {constructor() {this.area = '广东'}helloMethod () {return `它是${this.area}的动物`}}// 子类,子类继承了父类的属性和方法class Dog extends Animal {constructor(name) {super() // 调用父类的构造函数this.name = name}introduce () {return `${this.name}是一只狗`}}const dog1 = new Dog('咕咕')console.log(dog1.introduce()); // 咕咕是一只狗--introduce是自身实例的方法console.log(dog1.name); //  咕咕--name是自身实例的属性console.log(dog1.area); //  广东--area是继承了父类的属性console.log(dog1.helloMethod()); //  它是广东的动物--helloMethod是继承了父类的方法
    

    1.2 原型链:是javascript中实现对象间继承和代码重用的一种机制。
    JavaScript 只有一种结构:对象(广义的对象,不单指object)。每个对象都有一个私有属性指向另一个名为原型(prototype)的对象。原型对象也有一个自己的原型,层层向上直到一个对象的原型为 null。根据定义,null 没有原型,并作为这个原型链(prototype chain)中的最后一个环节。

    当你试图访问一个对象的属性时,如果在该对象本身中找不到该属性,就会在其原型中搜索该属性,如果仍然找不到,那么就会搜索原型的原型,以此类推,直到找到一个名字匹配的属性或到达原型链的末尾(即原型为null的对象)。

  2. 使用不同的方法来创建对象和改变原型链
    2.1 使用语法结构创建对象

    const o = { a: 1 };
    // 新创建的对象 o 以 Object.prototype 作为它的 [[Prototype]]
    // Object.prototype 的原型为 null。
    // 其原型链如下所示:
    // o ---> Object.prototype ---> nullconst b = ["yo", "whadup", "?"];
    // 数组继承了 Array.prototype(具有 indexOf、forEach 等方法)
    // 其原型链如下所示:
    // b ---> Array.prototype ---> Object.prototype ---> nullfunction f() {return 2;
    }
    // 函数继承了 Function.prototype(具有 call、bind 等方法)
    // 其原型链如下所示:
    // f ---> Function.prototype ---> Object.prototype ---> nullconst p = { b: 2, __proto__: o };
    // 可以通过 __proto__ 字面量属性将新创建对象的
    // [[Prototype]] 指向另一个对象。
    // (不要与 Object.prototype.__proto__ 访问器混淆,Object.prototype.__proto__添加原型链方法已经不推荐使用)
    // 其原型链如下所示:
    // p ---> o ---> Object.prototype ---> null

    2.2 使用构造函数

    function Family (name) {this.nameOfFamily = `${name}的家庭成员`this.persons = []
    }
    // 在Family原型链上添加addPerson方法,供后续创建的实例访问此公共的方法
    Family.prototype.addPerson = function (name) {this.persons.push(name)
    }const family = new Family('李四')family.addPerson('李四')family.addPerson('李四的妹妹')console.log(family.nameOfFamily); // 李四的家庭成员console.log(family.persons); // ['李四', '李四的妹妹']const family1 = new Family('王五')family1.addPerson('王五')family1.addPerson('王五的弟弟')console.log(family1.nameOfFamily); // 王五的家庭成员console.log(family1.persons); // ['王五', '王五的弟弟']
    

    2.3 使用 Object.create()

    const a = { a: 1 };
    // a ---> Object.prototype ---> nullconst b = Object.create(a);
    // b ---> a ---> Object.prototype ---> null
    console.log(b.a); // 1 (inherited)const c = Object.create(b);
    // c ---> b ---> a ---> Object.prototype ---> nullconst d = Object.create(null);
    // d ---> null(d 是一个直接以 null 为原型的对象)
    console.log(d.hasOwnProperty);
    // undefined,因为 d 没有继承 Object.prototype

    2.4 使用类class

      class Polygon {constructor(height, width) {this.height = height;this.width = width;}}class Square extends Polygon {constructor(sideLength) {super(sideLength, sideLength);}get area() {return this.height * this.width;}set sideLength(newLength) {this.height = newLength;this.width = newLength;}}const square = new Square(2);// square ---> Square.prototype ---> Polygon.prototype ---> Object.prototype ---> nullconsole.log(square.area); // 4square.sideLength = 3console.log(square.area); // 9
    

    2.5 使用 Object.setPrototypeOf()

    const obj = { a: 1 };
    const anotherObj = { b: 2 };
    Object.setPrototypeOf(obj, anotherObj);
    // obj ---> anotherObj ---> Object.prototype ---> null

    2.6 使用 proto 访问器(性能不佳且已被弃用)

      const obj = {};// 请不要使用该方法:仅作为示例。obj.__proto__ = { barProp: "bar val" };obj.__proto__.__proto__ = { fooProp: "foo val" };console.log(obj.fooProp); // foo valconsole.log(obj.barProp); // bar val
    

除非是为了与新的 JavaScript 特性兼容,否则永远不应扩展原生原型。

参考mdn和阮一峰日志

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/647963.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue —— h函数的学习与使用

文章目录 一、h函数是什么?二、h函数格式说明及使用示例1:简单创建一个VNode(vue3)示例2:vue2中h函数用法示例3:vue3中h函数的用法vue2和vue3中h函数的区别? 三、h函数实现原理四、h函数常用场景…

深度学习 pytorch的使用(张量2)

深度学习 pytorch的使用(张量1) 五、张量索引操作 简单行、列索引、列表索引、范围索引、布尔索引、多维索引 import torch # 数据 data torch.randint(0,10,[4,5]) print(data) tensor([[7, 6, 9, 4, 6], [1, 9, 0, 9, 2], [5, 7, 1, …

800G光传输网络中的相干调制与PAM4技术

在800G光传输网络架构中,相干调制技术和PAM4(四电平脉冲幅度调制)技术各具优势,分别针对不同应用场景提供高效解决方案。 相干调制是高级光通信的核心技术之一,它通过精密操控光载波的频率、相位和振幅来编码信息&…

HMI-Board以太网数据监视器(二)MQTT和LVGL

E ∫ d E ∫ k d q r 2 k L ∫ d q r 2 E \int dE \int \frac{kdq}{r^2} \frac{k}{L} \int \frac{dq}{r^2} E∫dE∫r2kdq​Lk​∫r2dq​ E Q 2 π ϵ L 2 E \frac{Q}{2\pi\epsilon L^2} E2πϵL2Q​ Γ ( n ) ( n − 1 ) ! ∀ n ∈ N \Gamma(n) (n-1)!\quad\forall n…

JavaScript 学习笔记(WEB APIs Day4)

「写在前面」 本文为 b 站黑马程序员 pink 老师 JavaScript 教程的学习笔记。本着自己学习、分享他人的态度,分享学习笔记,希望能对大家有所帮助。推荐先按顺序阅读往期内容: 1. JavaScript 学习笔记(Day1) 2. JavaSc…

C#使用RabbitMQ-1_Docker部署并在c#中实现简单模式消息代理

介绍 RabbitMQ是一个开源的消息队列系统,实现了高级消息队列协议(AMQP)。 🍀RabbitMQ起源于金融系统,现在广泛应用于各种分布式系统中。它的主要功能是在应用程序之间提供异步消息传递,实现系统间的解耦和…

SpringBoot框架:入门指南(二)

一. RESTful API开发 1. 创建RESTful控制器 在企业级Java开发中,RESTful API扮演着至关重要的角色,为系统提供了灵活、可扩展的接口。下面将详细介绍如何创建高质量的RESTful控制器,充分利用Spring Boot注解。 1.1 RESTful设计原则 RESTf…

Ubuntu20.0.4下设置frpc开机自启动

目录 一、下载frp 二、解压 三、服务端部署 1.配置 2.运行 三、客户端部署 1、配置 2、后台运行 四、开机启动 1、拷贝frpc.service 2、修改配置 3、启用服务 五、ubuntu20.04使用 rc-local.service设置开机启动 1、建立开机服务添加 [Install] 段 2、授权rc-local.service 3、…

Anaconda常用命令、操作、镜像源

Anaconda常用操作 命令例子作用conda create -n 环境名 需要的库conda create -n pythonenv python3.8创建环境conda info --envsconda info --envs查看全部环境activate 环境名activate pythonenv激活环境conda deactivateconda deactivate退出环境conda remove -n 环境名 --a…

pytorch学习笔记(十一)

优化器学习 把搭建好的模型拿来训练,得到最优的参数。 import torch.optim import torchvision from torch import nn from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear from torch.utils.data import DataLoaderdataset torchvision.datas…

uniapp安卓android离线打包本地打包整理

离线打包准备 下载Android studio 1.准备资源hbuilder 2.准备离线SDK 最新android平台SDK下载最新android平台SDK下载 3.离线打包key申请 4.直接导入HBuilder-Integrate-AS工程,直接运行simpleDemo项目即可 5.安装java 1.8 jdk-8u151-windows-x64 6.遇到这个报错报错Caus…

在游戏里开公司!基于ERNIE SDK的多智能体游戏应用

在虚拟世界有一座神奇的办公室,当你输入你的创业方向,办公室的智慧打工人们将团结合作,为你的项目勤劳奔走,并在过程中,把日报周报都写好,让你随时掌握项目进度和最终成果!该项目基于ERNIE SDK开…

工厂方法模式-C#实现

该实例基于WPF实现,直接上代码,下面为三层架构的代码。 一 Model using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 设计模式练习.Model.工厂方法模式 {internal class…

MSG3D论文解读

论文在stgcn与sta-lstm基础上做的。下面讲一下里面的方法: 1.准备工作 符号。这里是对符号进行解释。 一个人体骨骼图被记为G(v,E) 图卷积: 图卷积定义 考虑一种常用于处理图像的标准卷积神经网络 (CNN)。输入是像素网格。每个像素都有一个数据值向…

趣学贝叶斯统计:量化

概率理论不仅仅是一个数学概念,更是一种对随机性和不确定性的理解方式。通过量化我们对事件发生的信念,我们能够更准确地预测和解释各种现象。在本章中,我们将探讨事件概率与信念概率,为我们的理论和分析工具箱增添新的维度。 事…

Angular封装HttpClient文件下载

Angular HttpClient 文件下载 前言HttpRequest.tsdemo后端接口koa2示例功能优化实现下载进度监控 前言 使用Angular框架开发工作中,实现文件下载业务时,我们可以使用Angular自带的HttpClient。下面我们就封装一下HttpClient实现文件下载,当接…

前端网络请求之JavaScript XHR、Fetch、Axios

一、JavaScript XHR、Fetch AJAX:一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。在不重新加载整个网页的情况下,对网页的某部分进行更新 Fetch&…

主流电商平台:item_get-通过商品ID取商品详情,主图,sku

随着全球化的加速和互联网技术的不断发展,跨境电商已经成为了全球商业的重要组成部分。在这个环境下,如何有效地获取商品详情成为了关键的问题。本文将探讨一种基于商品ID获取商品详情的跨境电商创新方式,即item_get接口,以及其潜…

Vue3-在HTML标签、组件标签上使用v-model

本篇为Vue3学习中遇到的v-model相关的记录&#xff0c;如有问题欢迎指正 一、在标签上使用v-model v-model通常在input、select等标签上来实现数据双向绑定 <input type"text" v-model"username"> 原理&#xff1a;v-model通过给标签value赋值来实…

Windows10上使Git Bash支持rsync命令操作步骤

rsync命令是linux上常用的工具之一&#xff0c;用于远程以及本地系统中拷贝/同步文件和文件夹。 Windows Git Bash默认并不支持rsync&#xff0c;如下图所示&#xff1a; 使Git Bash支持rsync命令操作步骤&#xff1a; 1.从https://repo.msys2.org/msys/x86_64/ 下…