JavaScript 原型链解析,宏任务和微任务
目录
什么是原型链?
原型与构造函数
原型链的工作原理
实例:理解原型链
宏任务(Macro Task)
微任务(Micro Task)
什么是原型链?
JavaScript 是一门基于原型的语言,而原型链是 JavaScript 中实现继承的一种机制。它允许对象通过从其他对象继承属性和方法,形成一个链式结构。当访问一个对象的属性或方法时,如果当前对象没有找到,JavaScript 就会在原型链中继续查找。
原型与构造函数
在 JavaScript 中,每个对象都有一个称为原型的隐藏属性。原型可以是一个普通对象或 null。每个构造函数都有一个 prototype 属性,它是一个指向原型对象的引用。当我们使用构造函数创建一个新对象时,新对象的原型会指向构造函数的 prototype。
function Person(name) {this.name = name;
}Person.prototype.sayHello = function() {console.log(`Hello, my name is ${this.name}.`);
};const john = new Person('lisi');
在上面的例子中,我们创建了一个构造函数 Person,并给它的 prototype 添加了一个 sayHello 方法。当我们使用 new Person('lisi') 创建 lisi 对象时,lisi对象的原型就会指Person.prototype。
原型链的工作原理
当我们访问一个对象的属性或方法时,JavaScript 引擎首先会在对象本身中查找。如果找不到,它会继续在原型链中向上查找,直到找到该属性或方法或者到达原型链的末尾(即原型为 null)。
让我们看一个示例:
function Animal(species) {this.species = species;
}Animal.prototype.getSpecies = function() {return this.species;
};function Dog(name, breed) {this.name = name;this.breed = breed;
}Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;const fluffy = new Dog('Fluffy', 'Golden Retriever');
console.log(fluffy.getSpecies()); // Output: "Golden Retriever"
在上面的例子中,我们创建了两个构造函数 Animal 和 Dog。我们让 Dog 的原型指向 Animal 的实例,从而形成了一个原型链。当我们通过 fluffy 对象调用 getSpecies 方法时,由于 fluffy 对象本身没有 getSpecies 方法,JavaScript 引擎会沿着原型链向上查找,找到了 Animal.prototype 上的 getSpecies 方法并调用它。
实例:理解原型链
// 构造函数 Person
function Person(name, age) {this.name = name;this.age = age;
}// 在 Person 的原型上添加一个 sayHello 方法
Person.prototype.sayHello = function() {console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
};// 创建一个 Person 对象
const john = new Person('John', 30);// 调用 sayHello 方法
john.sayHello(); // Output: "Hello, my name is John and I'm 30 years old."
在这个简单的实例中,我们定义了一个构造函数 Person,它有两个属性 name 和 age。然后,我们通过给 Person.prototype 添加 sayHello 方法,使得所有通过 Person 构造函数创建的对象都可以调用 sayHello 方法。
当我们通过 new Person('John', 30) 创建了 john 对象后,john 对象的原型链上就可以找到 sayHello 方法。因此,当我们调用 john.sayHello() 时,JavaScript 引擎会在 john 对象中查找是否有 sayHello 方法,由于没有找到,它会继续向上查找,最终在 Person.prototype 上找到了 sayHello 方法并调用它。
结论:
原型链是 JavaScript 中实现继承的关键机制。它允许对象在运行时从其他对象继承属性和方法,并形成一个链式结构。通过深入理解原型链,我们可以更好地理解 JavaScript 中对象和继承的工作原理。
宏任务(Macro Task)
宏任务代表一组相互独立的、按顺序执行的任务。它们通常代表一些较为耗时的操作,例如 I/O 操作、定时器回调、DOM 事件等。宏任务的执行顺序是先进先出的。
在浏览器中,宏任务队列包含了一些异步任务,当主线程执行完同步代码后,会从宏任务队列中选择一个任务执行,执行完成后再次回到主线程执行同步代码,如此循环。
微任务(Micro Task)
微任务是宏任务中的一种更小的任务单元。它们具有高优先级,并且在当前宏任务执行完成后立即执行。常见的微任务包括 Promise 的回调、MutationObserver 的回调以及 process.nextTick 等。
在浏览器中,当一个宏任务执行完毕后,会检查当前宏任务是否产生了微任务,如果有,则会依次将微任务队列中的任务全部执行完毕,然后再执行下一个宏任务。这保证了微任务在宏任务之间执行,优先级比宏任务高。
实例:
console.log('Start'); // 同步任务,属于宏任务setTimeout(() => {console.log('Timeout'); // 异步任务,属于宏任务
}, 0);Promise.resolve().then(() => {console.log('Promise'); // 异步任务,属于微任务
});console.log('End'); // 同步任务,属于宏任务
执行上述代码,输出结果:
Start
End
Promise
Timeout
执行过程:
- 同步任务
console.log('Start')和console.log('End')首先进入宏任务队列,并立即执行。 setTimeout定时器会被放入宏任务队列,但由于时间设置为 0,它的回调函数会稍后执行。Promise.resolve().then的回调函数进入微任务队列,并立即执行。- 主线程执行完当前宏任务后,会检查微任务队列并执行其中的任务,执行结果为
Promise。 - 微任务执行完毕后,再从宏任务队列中选择一个任务执行,输出
Timeout。
相关文章:
JavaScript 原型链解析,宏任务和微任务
目录 什么是原型链? 原型与构造函数 原型链的工作原理 实例:理解原型链 宏任务(Macro Task) 微任务(Micro Task) 什么是原型链? JavaScript 是一门基于原型的语言,而原型链是…...
05|Oracle学习(UNIQUE约束)
1. UNIQUE约束介绍 也叫:唯一键约束,用于限定数据表中字段值的唯一性。 1.1 UNIQUE和primary key区别: 主键/联合主键每张表中只有一个。UNIQUE约束可以在一张表中,多个字段中存在。例如:学生的电话、身份证号都是…...
glide加载content://com.android.contacts图片源码粗略梳理
获取链路是这样的; UriLoader类里定义了协议头: 里面有个内部类StreamFactory: 通过StreamLocalUriFetcher类的loadResource方法获取InputStream然后把流转换成为图片; 在这里作个草稿笔记给自己看...
【机器学习】Feature Engineering and Polynomial Regression
Feature Engineering and Polynomial Regression 1. 多项式特征2. 选择特征3. 缩放特征4. 复杂函数附录 首先,导入所需的库: import numpy as np import matplotlib.pyplot as plt from lab_utils_multi import zscore_normalize_features, run_gradien…...
Rust- 变量绑定
In Rust, you bind values to a variable name using the let keyword. This is often referred to as “variable binding” because it’s like binding a name to a value. Here’s a simple example: let x 5;In this example, x is bound to the value 5. By default, …...
向“数”而“深”,联想凌拓的“破局求变”底气何来?
前言:要赢得更多机遇,“破局求变”尤为重要。 【全球存储观察 | 热点关注】2019年2月25日,承袭联想集团与NetApp的“双基因”,联想凌拓正式成立。历经四年多的发展,联想凌拓已成为中国企业级数据管理领域的…...
pytorch实战-图像分类(二)(模型训练及验证)(基于迁移学习(理解+代码))
目录 1.迁移学习概念 2.数据预处理 3.训练模型(基于迁移学习) 3.1选择网络,这里用resnet 3.2如果用GPU训练,需要加入以下代码 3.3卷积层冻结模块 3.4加载resnet152模 3.5解释initialize_model函数 3.6迁移学习网络搭建 3.…...
b 树和 b+树的理解
项目场景: 图灵奖获得者(Niklaus Wirth )说过: 程序 数据结构 算法, 也就说我们无时无刻 都在和数据结构打交道。 只是作为 Java 开发,由于技术体系的成熟度较高,使得大部分人认为࿱…...
正则表达式 —— Awk
Awk awk:文本三剑客之一,是功能最强大的文本工具 awk也是按行来进行操作,对行操作完之后,可以根据指定命令来对行取列 awk的分隔符,默认分隔符是空格或tab键,多个空格会压缩成一个 awk的用法 awk的格式…...
国芯新作 | 四核Cortex-A53@1.4GHz,仅168元起?含税?哇!!!
创龙科技SOM-TLT507是一款基于全志科技T507-H处理器设计的4核ARM Cortex-A53全国产工业核心板,主频高达1.416GHz。核心板CPU、ROM、RAM、电源、晶振等所有元器件均采用国产工业级方案,国产化率100%。 核心板通过邮票孔连接方式引出MIPI CSI、HDMI OUT、…...
【MyBatis】 框架原理
目录 10.3【MyBatis】 框架原理 10.3.1 【MyBatis】 整体架构 10.3.2 【MyBatis】 运行原理 10.4 【MyBatis】 核心组件的生命周期 10.4.1 SqlSessionFactoryBuilder 10.4.2 SqlSessionFactory 10.4.3 SqlSession 10.4.4 Mapper Instances 与 Hibernate 框架相比&#…...
三、线性工作流
再生产的各个环节,正确使用gamma编码及gamma解码,使得最终得到的颜色数据与最初输入的物理数据一致。如果使用gamma空间的贴图,在传给着色器前需要从gamma空间转到线性空间。 如果不在线性空间下进行渲染,会产生的问题:…...
2023华数杯数学建模A题思路 - 隔热材料的结构优化控制研究
# 1 赛题 A 题 隔热材料的结构优化控制研究 新型隔热材料 A 具有优良的隔热特性,在航天、军工、石化、建筑、交通等 高科技领域中有着广泛的应用。 目前,由单根隔热材料 A 纤维编织成的织物,其热导率可以直接测出;但是 单根隔热…...
Zabbix分布式监控Web监控
目录 1 概述2 配置 Web 场景2.1 配置步骤2.2 显示 3 Web 场景步骤3.1 创建新的 Web 场景。3.2 定义场景的步骤3.3 保存配置完成的Web 监控场景。 4 Zabbix-Get的使用 1 概述 您可以使用 Zabbix 对多个网站进行可用性方面监控: 要使用 Web 监控,您需要定…...
PHP从入门到精通—PHP开发入门-PHP概述、PHP开发环境搭建、PHP开发环境搭建、第一个PHP程序、PHP开发流程
每开始学习一门语言,都要了解这门语言和进行开发环境的搭建。同样,学生开始PHP学习之前,首先要了解这门语言的历史、语言优势等内容以及了解开发环境的搭建。 PHP概述 认识PHP PHP最初是由Rasmus Lerdorf于1994年为了维护个人网页而编写的一…...
【LeetCode-中等】722. 删除注释
题目链接 722. 删除注释 标签 字符串 步骤 Step1. 先将source合并为一个字符串进行处理,中间补上’\n’,方便后续确定注释开始、结束位置。 string combined; for (auto str : source) {combined str "\n"; }Step2. 定义数组 toDel&am…...
rust里如何判断字符串是否相等呢?
在 Rust 中,有几种方法可以判断字符串是否相等。下面是其中几种常见的方法: 使用 运算符:可以直接使用 运算符比较两个字符串是否相等。例如: fn main() {let str1 "hello";let str2 "world";if str1 …...
python基本知识学习
一、输出语句 在控制台输出Hello,World! print("Hello,World!") 二、注释 单行注释:以#开头 # print("你好") 多行注释: 选中要注释的代码Ctrl/三单引号三双引号 # print("你好") # a1 # a2 print("Hello,World!&…...
vue3和typescript_组件
1 components下新建myComponent.vue 2 页面中引入组件,传入值,并且绑定事件函数。 3...
Qt+联想电脑管家
1.自定义按钮类 效果: (1)仅当未选中,未悬浮时 (2)其他三种情况,均如图 #ifndef BTN_H #define BTN_H#include <QPushButton> class btn : public QPushButton {Q_OBJECT public:btn(QWidget * parent nullptr);void set_normal_icon(…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版
1.题目描述 2.思路 当前的元素可以重复使用。 (1)确定回溯算法函数的参数和返回值(一般是void类型) (2)因为是用递归实现的,所以我们要确定终止条件 (3)单层搜索逻辑 二…...
第22节 Node.js JXcore 打包
Node.js是一个开放源代码、跨平台的、用于服务器端和网络应用的运行环境。 JXcore是一个支持多线程的 Node.js 发行版本,基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行。 本文主要介绍JXcore的打包功能。 JXcore 安装 下载JXcore安装包&a…...
