当前位置: 首页 > news >正文

【个人笔记js的原型理解】

在 JavaScript 中,最常见的新建一个对象的方式就是使用花括号的方式。然后使用’ . '的方式往里面添加属性和方法。可见以下代码:

let animal = {};
animal.name = 'Leo';
animal.energe = 10;animal.eat = function (amount) {console.log(`${this.name} is eating.`)this.energe += amount
}animal.sleep = function (length) {console.log(`${this.name} is sleeping.`)this.energe += length
}animal.play = function (length) {console.log(`${this.name} is playing.`)this.energe -= length
}

但通常的应用场景下,你会需要生成多种动物。这则需要把以上的逻辑抽象成一个函数。可见以下代码,生成了 leo 和 snoop 两个动物。

function Animal(name, energy){let animal = {};animal.name = name;animal.energy = energy;animal.eat = function (amount) {console.log(`${this.name} is eating.`)this.energy += amount}animal.sleep = function (length) {console.log(`${this.name} is sleeping.`)this.energy += length}animal.play = function (length) {console.log(`${this.name} is playing.`)this.energy -= length}return animal;
}const leo = Animal('Leo', 7);
const snoop = Animal('Snoop', 10)

但是按照上面代码,每次新创建一个animal,就需要把里面的eat、sleep、play方法都会被重新创建一遍。

因为eat、sleep、play方法都很相似,所以我们可以把他们放在一个animalMethods里面,这样只需要在内存里面创建一次。然后每次我们需要创建一个新动物,我们只是指向了animalMethods里面的方法,而不是重新创造这些方法。

const animalMethods = {eat(amount) {console.log(`${this.name} is eating.`)this.energy += amount},sleep(length) {console.log(`${this.name} is sleeping.`)this.energy += length},play(length) {console.log(`${this.name} is playing.`)this.energy -= length}
}
function Animal(name, energy){let animal = {};animal.name = name;animal.energy = energy;animal.eat = animalMethods.eat;animal.sleep = animalMethods.sleep;animal.play = animalMethods.play;return animal;
}

以上代码中,比如animal增加一个方法poop,就需要到Animal函数 里面增加 animal.poop = animalMethods.poop 。 如果想要Animal总能指向 animalMethods里面的任何一个方法,可以使用Object.create()传入animalMethods,使得在Animal里面找不到对应属性或方法时,就会去animalMethods查找,并调用对应方法。

const animalMethods = {eat(amount) {console.log(`${this.name} is eating.`)this.energy += amount},sleep(length) {console.log(`${this.name} is sleeping.`)this.energy += length},play(length) {console.log(`${this.name} is playing.`)this.energy -= length}
}
function Animal(name, energy) {let animal = Object.create(animalMethods)animal.name = name;animal.energy = energy;return animal;
}
const leo = Animal('Leo', 7);
console.log(leo.play(7)) //Leo is playing.

以上的用法就是JavaScript 原型(prototype)的由来。

那么什么原型?它就是函数上的一个属性,指向一个对象。

既然原型是每个函数都有的属性,那么与其单独管理 animalMethods ,为什么我们不把 animalMethods 放到函数的原型上呢?

function Animal(name, energy) {let animal = Object.create(Animal.prototype)animal.name = name;animal.energy = energy;return animal;
}Animal.prototype.eat = function (amount) {console.log(`${this.name} is eating.`)this.energy += amount
}
Animal.prototype.sleep = function (length) {console.log(`${this.name} is sleeping.`)this.energy += length
}
Animal.prototype.play = function (length) {console.log(`${this.name} is playing.`)this.energy -= length
}const leo = Animal('Leo', 7);
console.log(leo.eat(5)) //Leo is eating.

以上代码告诉了我们三点:

如何创建一个构造函数(构造函数就是构造一个对象)
如何将方法添加到构造函数的原型上(eg:Animal.prototype.eat()={…})
如何使用Object.create()指向函数原型。
这三点的目的就是为了构造函数的所有实例都能共享实例上的方法。

接下来会引入关键词 new 来对上面代码再进行进一步优化。使用new关键词,js会自动做Object.create()和return的动作,并且需要使用this对象来替换原本的animal对象。

function Animal(name, energy) {// let this = Object.create(Animal.prototype) //这一步的作用:1、创建对象 2、指向Animal.prototypethis.name = name;this.energy = energy;// return this; //输出创建的对象
}Animal.prototype.eat = function (amount) {console.log(`${this.name} is eating.`)this.energy += amount
}
Animal.prototype.sleep = function (length) {console.log(`${this.name} is sleeping.`)this.energy += length
}
Animal.prototype.play = function (length) {console.log(`${this.name} is playing.`)this.energy -= length
}const leo = new Animal('Leo', 7);
const snoop = new Animal('Snoop', 10)
console.log(leo.sleep(15)) //Leo is sleeping.

以上这些操作,就是基本上创建了一个class。在es6,JavaScript有了class关键词。接下来就用class来重构以上的代码。

class Animal {constructor(name, energy) {this.name = namethis.energy = energy}eat(amount) {console.log(`${this.name} is eating.`)this.energy += amount}sleep(length) {console.log(`${this.name} is sleeping.`)this.energy += length}play(length) {console.log(`${this.name} is playing.`)this.energy -= length}
}const leo = new Animal('Leo', 7);
const snoop = new Animal('Snoop', 10)
console.log(leo) //Animal { name: 'Leo', energy: 7 }
console.log(leo.sleep(1)) //Leo is sleeping.

既然可以用js建造class,那么为什么还需要花这么多时间了解上面的prototype,this,new?原因是class是function的语法糖,提供了更便捷的方式创建对象。class最终会被编译为function,其中的方法会成为prototype上面的共享方法。

相关文章:

【个人笔记js的原型理解】

在 JavaScript 中,最常见的新建一个对象的方式就是使用花括号的方式。然后使用’ . 的方式往里面添加属性和方法。可见以下代码: let animal {}; animal.name Leo; animal.energe 10;animal.eat function (amount) {console.log(${this.name} is ea…...

Liunx系统编程:信号量

一. 信号量概述 1.1 信号量的概念 在多线程场景下,我们经常会提到临界区和临界资源的概念,如果临界区资源同时有多个执行流进入,那么在多线程下就容易引发线程安全问题。 为了保证线程安全,互斥被引入,互斥可以保证…...

大集合按照指定长度进行分割成多个小集合,用于批量多次处理数据

📚目录 拆分案例拆分的核心代码 通常我们对集合的更新或者保存都需要用集合来承载通过插入的效率,但是这个会遇到一个问题就是你不知道那天那个集合的数量可能就超了,虽然我们连接数据库进行批量提交会在配置上配置allowMultiQueriestrue,但是…...

ELK日志收集系统集群实验(5.5.0版)

目录 前言 一、概述 二、组件介绍 1、elasticsearch 2、logstash 3、kibana 三、架构类型 四、ELK日志收集集群实验 1、实验拓扑 2、在node1和node2节点安装elasticsearch 3、启动elasticsearch服务 4、在node1安装elasticsearch-head插件 5、测试输入 6、node1服…...

基于java swing和mysql实现的电影票购票管理系统(源码+数据库+运行指导视频)

一、项目简介 本项目是一套基于java swing和mysql实现的电影票购票管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、项目文档、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都…...

数据结构--6.0最短路径

目录 一、迪杰斯特拉算法(Dijkstra) 二、弗洛伊德算法(Floyd) 在网图和非网图中,最短路径的含义是不同的。 ——网图是两顶点经过的边上的权值之和最少的路径。 …...

Docker进阶:mysql 主从复制、redis集群3主3从【扩缩容案例】

Docker进阶:mysql 主从复制、redis集群3主3从【扩缩容案例】 一、Docker常规软件安装1.1 docker 安装 tomcat(默认最新版)1.2 docker 指定安装 tomcat8.01.3 docker 安装 mysql 5.7(数据卷配置)1.4 演示--删除mysql容器…...

遗传算法决策变量降维的matlab实现

1.案例背景 1.1遗传算法概述 遗传算法是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。它最初由美国Michigan大学的J. Holland教授提出,1967年, Holland 教授的学生 Bagley在其博士论文中首次提出了“遗传…...

基于Open3D和PyTorch3D读取三维数据格式OBJ

本节将讨论另一种广泛使用的3D数据文件格式,即OBJ文件格式。OBJ文件格式最初由Wavefront Technologies Inc.开发。与PLY文件格式类似,OBJ格式也有ASCII版本和二进制版本。二进制版本是专有的且未记录文档。本章主要讨论ASCII版本。 与之前类似,将通过示例来学习文件格式。第…...

带纽扣电池产品出口澳洲安全标准,纽扣电池IEC 60086认证

澳大利亚政府公布了《消费品(纽扣/硬币电池)安全标准》和《消费品(纽扣/硬币电池)信息标准》。届时出口纽扣/硬币电池以及含有纽扣/硬币电池产品到澳大利亚的供应商,必须遵守这些标准中的要求。 一、 安全标准及信息标…...

spring高级源码50讲-37-42(springBoot)

Boot 37) Boot 骨架项目 如果是 linux 环境,用以下命令即可获取 spring boot 的骨架 pom.xml curl -G https://start.spring.io/pom.xml -d dependenciesweb,mysql,mybatis -o pom.xml也可以使用 Postman 等工具实现 若想获取更多用法,请参考 curl …...

腾讯云、阿里云、华为云便宜云服务器活动整理汇总

云服务器的选择是一个很重要的事情,避免产生不必要的麻烦,建议选择互联网大厂提供的云计算服务,腾讯云、阿里云、华为云就是一个很不错的选择,云服务器稳定性、安全性以及售后各方面都更受用户认可,下面小编给大家整理…...

L1-055 谁是赢家(Python实现) 测试点全过

前言: {\color{Blue}前言:} 前言: 本系列题使用的是,“PTA中的团体程序设计天梯赛——练习集”的题库,难度有L1、L2、L3三个等级,分别对应团体程序设计天梯赛的三个难度。更新取决于题目的难度,…...

开发一个npm包

1 注册一个npm账号 npm https://www.npmjs.com/ 2 初始化一个npm 项目 npm init -y3编写一段代码 function fn(){return 12 }exports.hellofn;4发布到全局node_module npm install . -g5测试代码 创建一个text文件 npm link heath_apisnode index.js6登录(我默认的 https…...

介绍几种使用工具

FileWatch,观测文件变化,源码地址:https://github.com/ThomasMonkman/filewatch nlohmann::json,json封装解析,源码地址:https://github.com/nlohmann/json optionparser,解析选项,源…...

Vue:关于声明式导航中的 跳转、高亮、以及两个类名的定制

声明式导航-导航链接 文章目录 声明式导航-导航链接router-link的两大特点(能跳转、能高亮)声明式导航-两个类名定制两个高亮类名 实现导航高亮,实现方式其实,css,JavaScript , Vue ,都可以实现。其实关于路由导航&…...

Sharding-JDBC分库分表-自动配置与分片规则加载原理-3

Sharding JDBC自动配置的原理 与所有starter一样,shardingsphere-jdbc-core-spring-boot-starter也是通过SPI自动配置的原理实现分库分表配置加载,spring.factories文件中的自动配置类shardingsphere-jdbc-core-spring-boot-starter功不可没&#xff0c…...

E8267D 是德科技矢量信号发生器

描述 最先进的微波信号发生器 安捷伦E8267D PSG矢量信号发生器是业界首款集成式微波矢量信号发生器,I/Q调制最高可达44 GHz,典型输出功率为23 dBm,最高可达20 GHz,对于10 GHz信号,10 kHz偏移时的相位噪声为-120 dBc/…...

Git git fetch 和 git pull 区别

git pull和git fetch的作用都是用于从远程仓库获取最新代码,但它们之间有一些区别。 git pull会自动执行两个操作:git fetch和git merge。它从远程仓库获取最新代码,并将其合并到当前分支中。 示例:运行git pull origin master会从…...

软件UI工程师工作的岗位职责(合集)

软件UI工程师工作的岗位职责1 职责: 1.负责产品的UI视觉设计(手机软件界面 网站界面 图标设计产品广告及 企业文化的创意设计等); 2.负责公司各种客户端软件客户端的UE/UI界面及相关图标制作; 3.设定产品界面的整体视觉风格; 4.参与产品规划构思和创意过程&…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

GitHub 趋势日报 (2025年06月08日)

📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM&#xff09…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...

Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解

文章目录 一、开启慢查询日志,定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...

基于单片机的宠物屋智能系统设计与实现(论文+源码)

本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...