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

原型链-(前端面试 2024 版)

来讲一讲原型链

原型链只存在于函数之中

四个规则

1、引用类型,都具有对象特性,即可自由扩展属性。

2、引用类型,都有一个隐式原型 __proto__ 属性,属性值是一个普通的对象。

3、引用类型,隐式原型 __proto__ 的属性值指向它的构造函数的显式原型 prototype 属性值

4、当你试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型 __proto__(也就是它的构造函数的显式原型 prototype)中寻找

四个知识点

  • Object 是所有对象的爸爸,所有对象都可以通过 __proto__ 找到它
  • Function 是所有函数的爸爸,所有函数都可以通过 __proto__ 找到它
  • 函数的 prototype 是一个对象
  • 对象的 __proto__ 属性指向原型, __proto__ 将对象和原型连接起来组成了原型链

const obj = {};
const arr = [];
const fn = function() {}obj.__proto__ == Object.prototype // true
arr.__proto__ === Array.prototype // true
fn.__proto__ == Function.prototype // true

new 做了什么

var obj = new F();
//  做了什么
var obj  = {};
obj.__proto__ = F.prototype;
F.call(obj);

第一行,我们创建了一个空对象obj;

第二行,我们将这个空对象的__proto__成员指向了F函数对象prototype成员对象;

第三行,我们将F函数对象的this指针替换成obj,然后再调用F函数.

我们可以这么理解: 以 new 操作符调用构造函数的时候,函数内部实际上发生以下变化:

1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。

2、属性和方法被加入到 this 引用的对象中。

3、新创建的对象由 this 所引用,并且最后隐式的返回 this.

prototype和__proto__

1. __proto__是每个对象都有的一个属性,而prototype是函数才会有的属性。

2. __proto__指向的是当前对象原型对象,而prototype指向的,是以当前函数作为构造函数构造出来的对象原型对象
你的__proto__来自你构造函数的prototype;所有对象字面量都是通过Object()构造出来的,换言之,对象字面量__proto__ 属性都指向Object.prototype

  • prototype: 显式原型

每一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象。

通过Function.prototype.bind方法构造出来的函数是个例外,它没有prototype属性
JavaScript中任意对象都有一个内置属性[[prototype]],在ES5之前没有标准的方法访问这个内置属性,但是大多数浏览器都支持通过__proto__来访问。ES5中有了对于这个内置属性标准的Get方法Object.getPrototypeOf().

Object.prototype 这个对象是个例外,它的__proto__值为null

隐式原型指向创建这个对象的函数(constructor)的prototype

作用是什么:显式原型的作用:用来实现基于原型的继承与属性的共享。
 


 

  • __ proto__: 隐式原型

隐式原型的作用:构成原型链,同样用于实现基于原型的继承。举个例子,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着__proto__依次查找。

__proto__的指向:__proto__的指向到底如何判断呢?根据ECMA定义 'to the value of its constructor’s "prototype" ' ----指向创建这个对象的函数的显式原型。所以关键的点在于找到创建这个对象的构造函数,接下来就来看一下JS中对象被创建的方式,一眼看过去似乎有三种方式:(1)对象字面量的方式 (2)new 的方式 (3)ES5中的Object.create() 但是我认为本质上只有一种方式,也就是通过new来创建。为什么这么说呢,首先字面量的方式是一种为了开发人员更方便创建对象的一个语法糖,本质就是 var o = new Object(); o.xx = xx;o.yy=yy; 再来看看Object.create(),这是ES5中新增的方法,在这之前这被称为原型式继承,

构造函数的prototype和其实例的__proto__是指向同一个地方的,这个地方就叫做原型对象

Function和Object

构造函数的prototype和其实例的__proto__是指向同一个地方的,咱们可以来验证一下

  • 函数是Function构造函数的实例
  • 对象是Object构造函数的实例

那Function构造函数和Object构造函数他们两个又是谁的实例呢?

  • function Object()其实也是个函数,所以他是Function构造函数的实例
  • function Function()其实也是个函数,所以他也是Function构造函数的实例,没错,他是他自己本身的实例


 

console.log(Function.prototype === Object.__proto__) // true
console.log(Function.prototype === Function.__proto__) // true

constructor和prototype是成对的,你指向我,我指向你

function fn() {}console.log(fn.prototype) // {constructor: fn}
console.log(fn.prototype.constructor === fn) // true

原型链

什么是原型链呢?其实俗话说就是:__proto__的路径就叫原型链

原型继承


说到原型,就不得不说补充一下原型继承这个知识点了,原型继承就是,实例可以使用构造函数上的prototype中的方法

instanceof

作用:判断B的prototype是否在A的原型链上


A instanceof B

【JS】图解原型链相关练习题,带你彻底搞懂原型链!!!(这可能是掘金画原型链画的最正的😃) - 掘金

第一题

主要坑是 f的构造函数是 F F的构造函数是Obj,

f的所有方法从以下找

f.__proto__ === F.protyotype F.__proto__ === obj.protyotype obj.proto=== null

F的所有方法从以下找

F.__proto__ === Function.protyotype Function.__proto__ === obj.protyotype obj.proto=== null

var F = function() {};Object.prototype.a = function() {console.log('a');
};Function.prototype.b = function() {console.log('b');
}var f = new F();f.a();
f.b();F.a();
F.b();

第二题

b的所有方法从以下找

b.__proto__ === A.protyotype A.proto=== obj.protyotype obj.proto=== null

c的所有方法从以下找

b.__proto__ === A.protyotype A.proto=== obj.protyotype obj.proto=== null

本体核心是每次new时使用的都是构造函数最新的prototype ,老的构造函数引用老的prototype 并不会被覆盖

var A = function() {};
A.prototype.n = 1;
var b = new A();
A.prototype = {n: 2,m: 3
}
var c = new A();console.log(b.n);
console.log(b.m);console.log(c.n);
console.log(c.m);

第三题

函数的构造函数一定是Function 对象的构造函数 可能是obj 也可能是new Function

var foo = {},F = function(){};
Object.prototype.a = 'value a';
Function.prototype.b = 'value b';console.log(foo.a);
console.log(foo.b);console.log(F.a);
console.log(F.b);

第四题

new 的时候会函数内this会重新赋值进行覆盖

function A() {}
function B(a) {this.a = a;
}
function C(a) {if (a) {this.a = a;}
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;console.log(new A().a); 
console.log(new B().a);
console.log(new C(2).a);

相关文章:

原型链-(前端面试 2024 版)

来讲一讲原型链 原型链只存在于函数之中 四个规则 1、引用类型,都具有对象特性,即可自由扩展属性。 2、引用类型,都有一个隐式原型 __proto__ 属性,属性值是一个普通的对象。 3、引用类型,隐式原型 __proto__ 的属…...

网络套接字补充——UDP网络编程

五、UDP网络编程 ​ 1.对于服务器使用智能指针维护生命周期;2.创建UDP套接字;3.绑定端口号,包括设置服务器端口号和IP地址,端口号一般是2字节使用uint16_t,而IP地址用户习惯使用点分十进制格式所以传入的是string类型…...

自动化测试 —— Pytest fixture及conftest详解

前言 fixture是在测试函数运行前后,由pytest执行的外壳函数。fixture中的代码可以定制,满足多变的测试需求,包括定义传入测试中的数据集、配置测试前系统的初始状态、为批量测试提供数据源等等。fixture是pytest的精髓所在,类似u…...

Scala第十四章节(隐式转换、隐式参数以及获取列表元素平均值的案例)

章节目标 掌握隐式转换相关内容掌握隐式参数相关内容掌握获取列表元素平均值的案例 1.隐式转换和隐式参数介绍 隐式转换和隐式参数是Scala中非常有特色的功能,也是Java等其他编程语言没有的功能。我们可以很方便地利用 隐式转换来丰富现有类的功能。在后续编写Ak…...

VsCode的json文件不允许注释的解决办法

右下角找到注释点进去 输入Files: Associations搜索出此项 改为项为*.json值为jsonc保存即可 然后会发现VsCode的json文件就允许注释了...

利用图像识别进行疾病诊断

利用图像识别进行疾病诊断是人工智能和机器学习技术在医疗领域的一个重要应用。图像识别技术可以通过分析医学影像(如X光片、CT扫描、MRI、超声波图像等)来辅助医生诊断疾病。以下是图像识别在疾病诊断中的关键步骤和挑战: 数据收集与预处理…...

大数据学习-2024/3/28-excel文件的读写操作

借助第三方模块:inxlrd,xlwt pip 第三方模块包管理工具 –> winr --> cmd --> 打开操作系统 –> python --> 查看默认的解释器版本 --> exit() –> pip list --> 查看第三方模块的列表 pip36 list --> 查看3.6版本安装的第三方模块列表 –> pip[…...

k8s 如何获取加入节点命名

当k8s集群初始化成功的时候&#xff0c;就会出现 加入节点 的命令如下&#xff1a; 但是如果忘记了就需要找回这条命令了。 kubeadm join 的命令格式如下&#xff1a;kubeadm join --token <token> --discovery-token-ca-cert-hash sha256:<hash>--token 令牌--…...

黑群晖基于docker配置frp内网穿透

前言 我的黑群晖需要设置一下内网穿透来外地访问&#xff0c;虽然zerotier的p2p组网已经很不错了&#xff0c;但是这个毕竟有一定的局限性&#xff0c;比如我是ios的国区id就下载不了zerotier的app&#xff0c;组网不了 1.下载镜像 选择第一个镜像 2.映射文件 配置frpc.ini&a…...

多线程基础:线程通信内容补充

多线程基础&#xff1a;线程通信内容补充 文章目录 多线程基础&#xff1a;线程通信内容补充前言一、wait(), notify(), notifyAll()二、join()三、Lock 和 Condition四、并发集合和原子变量1、并发集合2、原子变量 总结 前言 前文内容中讲了线程通信的内容&#xff0c;但是不…...

使用Jenkins打包时执行失败,但手动执行没有问题如ERR_ELECTRON_BUILDER_CANNOT_EXECUTE

具体错误信息如&#xff1a; Error output: Plugin not found, cannot call UAC::_ Error in macro _UAC_MakeLL_Cmp on macroline 2 Error in macro _UAC_IsInnerInstance on macroline 1 Error in macro _If on macroline 9 Error in macro FUNCTION_INSTALL_MODE_PAGE_FUNC…...

OpenCV图像滤波、边缘检测

OpenCV图像滤波 一、引言 在数字图像处理中&#xff0c;滤波是一种重要的技术&#xff0c;用于消除图像中的噪声、改善图像质量或提取特定信息。OpenCV&#xff08;开源计算机视觉库&#xff09;提供了丰富的滤波函数&#xff0c;可以方便地对图像进行各种滤波操作。本文将介…...

前端项目在本地localhost可以调取到拍照或麦克风等设备,但是在局域网内IP+端口号访问项目时访问不到设备

前端项目在本地localhost可以调取到拍照或麦克风等设备&#xff0c;但是在局域网内IP端口号访问项目时访问不到设备&#xff0c;调取navigation.mediaDevices时本科可以获取到mediaDevices列表&#xff0c;局域网内ip端口访问时获取不到mediaDevices。 原因&#xff1a; 存在…...

flutter生成二维码并截图保存到图库

引入库&#xff1a;flutter_screenutil、image_gallery_saver、qr_flutter弹窗布局 import dart:async; import dart:typed_data; import package/generated/l10n.dart; import package:jade/configs/PathConfig.dart; import package:jade/utils/ImageWaterMarkUtil.dart; im…...

EasyExcel Converter实现java对象和excel单元格转换

在EasyExcel中&#xff0c;Converter接口用于定义如何在Java对象和Excel单元格之间进行转换。 也就是说EasyExcel可以根据数据库中的值来填充Excel中对应的文本内容。 比如数据库1,2,3可以填充到excel中&#xff1a;男&#xff0c;女&#xff0c;其他 使用easyExcel的之前&a…...

stamac Ethernet DTS配置

目录 Demo 配置 compatible reg interrupts & interrupt-names phy-mode phy-handle Snps,reset-gpio...

Svg Flow Editor 原生svg流程图编辑器(四)

系列文章 Svg Flow Editor 原生svg流程图编辑器&#xff08;一&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;二&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;三&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;四&#xf…...

Verilog语法之assign语句学习

assign语法主要是对组合逻辑的变量进行赋值的&#xff0c;就是把一个变量赋值给另一个变量&#xff0c;被复制的变量必须是wire类型的参数。 从仿真结果可以看出&#xff0c;data_in变量的值赋值给了data_out,assign语法就是赋值没有任何延迟&#xff0c;data_in是什么值&#…...

Cocos2dx-lua ScrollView[三]高级篇

一.概述 本文缩写说明&#xff1a;sv ScrollView, cell代表ScrollView的一个子节点 本文介绍sv的一种封装类库&#xff0c;来实现快速创建sv&#xff0c;有如下几个优点&#xff1a; 1.item的位置通过参数控制&#xff0c;提高开发效率 2.免去了调用sv的API&#xff0c;提…...

后端之卡尔曼滤波

后端之卡尔曼滤波 前言 在很久之前&#xff0c;人们刚结束信息传递只能靠信件的时代&#xff0c;通信技术蓬勃发展&#xff0c;无线通信和有线通信走进家家户户&#xff0c;而著名的贝尔实验室就在这个过程做了很多影响深远的研究。为了满足不同电路和系统对信号的需求&#…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...

C# winform教程(二)----checkbox

一、作用 提供一个用户选择或者不选的状态&#xff0c;这是一个可以多选的控件。 二、属性 其实功能大差不差&#xff0c;除了特殊的几个外&#xff0c;与button基本相同&#xff0c;所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...

写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里

写一个shell脚本&#xff0c;把局域网内&#xff0c;把能ping通的IP和不能ping通的IP分类&#xff0c;并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...