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

news2024/12/23 20:33:22

来讲一讲原型链

原型链只存在于函数之中

四个规则

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);

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

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

相关文章

Windows安装Odoo结合内网穿透实现公网访问本地企业管理系统

文章目录 前言1. 下载安装Odoo:2. 实现公网访问Odoo本地系统:3. 固定域名访问Odoo本地系统 前言 Odoo是全球流行的开源企业管理套件,是一个一站式全功能ERP及电商平台。 开源性质:Odoo是一个开源的ERP软件,这意味着企…

python、execl数据分析(数据描述)

一 python 1.各函数 1.1python库的安装与导入 #pip install os#pip install matplotlib#pip install seaborn#pip install scikit-learn#pip install scipy#修 改 工 作 目 录import osos.getcwd () # 查看当前工作环境os.chdir( F :\my course\database ) # 修改工作环境o…

网络稳定性(蓝桥省赛)

0网络稳定性 - 蓝桥云课 (lanqiao.cn) 知识点&#xff1a;克鲁斯卡尔生成树&#xff0c;lca&#xff0c;倍增 最小生成树的模板&#xff1a;最小生成树【模板】-CSDN博客 题解代码如下&#xff1a; #include<bits/stdc.h> using namespace std; const int N3e5100; co…

智慧光伏:企业无纸化办公

随着科技的快速发展&#xff0c;光伏技术不仅成为推动绿色能源革命的重要力量&#xff0c;更在企业办公环境中扮演起引领无纸化办公的重要角色。智慧光伏不仅为企业提供了清洁、可持续的能源&#xff0c;更通过智能化的管理方式&#xff0c;推动企业向无纸化办公转型&#xff0…

CBO VS ABO,哪种策略才更能优化FB广告?

海外创业时&#xff0c;FB广告无疑是吸引目标受众、推动业务增长的重要渠道之一&#xff01;然而令大家头疼的却是在CBO与ABO的选择上&#xff0c;今天就带大家一起解读这两种常见的广告策略。了解两者之间的区别、优缺点及适用场景。 CBO 和 ABO 分别是什么&#xff1f; CBO&a…

网络面试——浏览器输入url到显示主页的过程

浏览器输入URL到显示主页的过程通常可以分为以下步骤&#xff1a; 1. **URL解析**&#xff1a; - 当用户在浏览器的地址栏中输入URL时&#xff0c;浏览器会首先对该URL进行解析。 - 解析URL包括识别协议&#xff08;例如HTTP、HTTPS&#xff09;、主机名&#xff08;例如…

Redis项目实战

本文用用代码演示Redis实现分布式缓存、分布式锁、接口幂等性、接口防刷的功能。 课程地址&#xff1a;Redis实战系列-课程大纲_哔哩哔哩_bilibili 目录 一. 新建springBoot项目整合Redis 二. Redis实现分布式缓存 2.1 原理及好处 2.2 数据准备 2.3 Redis实现分布式缓存…

9.HelloWorld案例常见问题

文章目录 一、BUG二、BUG的解决三、HelloWorld常见问题 一、BUG BUG&#xff08;小甲虫&#xff09;。计算机刚开始出现的时候&#xff0c;因为体积比较大&#xff0c;一些小虫子很容易转进去。有一天有一只蟑螂钻到了计算机当中&#xff0c;从而导致计算机不能正常运行&#…

揭秘!抖音严打AI网红骗局,维护虚拟世界秩序!

近年来&#xff0c;AI网红在社交媒体平台上的兴起引发了不少争议。为了规范虚拟人物的内容创作&#xff0c;抖音平台决定对AI网红乱象进行严厉打击&#xff0c;并推出了一系列措施。 AI-321 | 专注于AI工具分享的网站 AI工具集 | 人工智能工具箱 | 全球顶尖AI工具软件推荐与分…

Java的字符串的基础知识(必看)

目录 Java的字符串的基础知识(必看) String API的使用 String概述 创建String对象的两种方式 号比的是什么? 难点 经典String案例 易错点 StringBuilder 疑难点: StringJoiner 字符串相关类的底层原理 中文的存储原理 String的常见的构造方法 Java的字符串的基础…

Avue-crud表格操作栏不显示修改、删除按钮

2024-03-28 奇了怪了&#xff0c;CSDN自动把我之前的文章设置为VIP了&#xff0c;怪不得有时候搜东西看着看着要收费&#xff0c;现在找东西都不好找&#xff0c;我已经反馈不同意了&#xff0c;看看能不能给我取消吧 今天用Avue的时候发现操作栏的按钮没了&#xff0c;按照文…

网络专有名词

网络专有名词 一、子网掩码 IP地址是以网络号和主机号来标示网络上的主机的&#xff0c;我们把网络号相同的主机称之为本地网络&#xff0c;网络号不相同的主机称之为远程网络主机&#xff0c;本地网络中的主机可以直接相互通信&#xff1b;远程网络中的主机要相互通信必须通过…

从零开始学起!全方位解析App压力测试的关键要点!

简介 Monkey 是 Google 提供的一个用于稳定性与压力测试的命令行工具 可以运行在模拟器或者实际设备中 它向系统发送伪随机的用户事件对软件进行稳定性与压力测试 为什么要用 Monkey Monkey 就是像猴子一样上蹿下跳地乱点 为了测试软件的稳定性&#xff0c;健壮性 随机点…

如何使用群晖WebDAV实现固定公网地址同步Zotero文献管理器

文章目录 前言1. Docker 部署 Trfɪk2. 本地访问traefik测试3. Linux 安装cpolar4. 配置Traefik公网访问地址5. 公网远程访问Traefik6. 固定Traefik公网地址 前言 Trfɪk 是一个云原生的新型的 HTTP 反向代理、负载均衡软件&#xff0c;能轻易的部署微服务。它支持多种后端 (D…

Automatic Prompt Engineering

让大模型自己生成prompt&#xff0c;生成提示&#xff08;prompt&#xff09;存在两种不同的操作方式。第一种方式是在文本空间中进行&#xff0c;这种提示以离散的文本形式存在。第二种方式是将提示抽象成一个向量&#xff0c;在特征空间中进行操作&#xff0c;这种提示是抽象…

android安卓看点新闻课设

一、系统需求分析 1.1 引言 1.1.1 开发目的 看点新闻App的开发是为了实时查看最新消息以了解社会动态&#xff0c;增长知识&#xff0c;增广见闻&#xff0c;顺便娱乐一下内心世界来放松自己。 1.1.2 开发背景 随着新媒体的崛起&#xff0c;纸媒遭受到重大打击&#xff0c…

vscode安装vue3+elment-plus

1.用vscode打开打算创建项目的目录 2.命令行中运行以下命令 npm create vuelatest3.设置好项目名称 4.执行以下命令 cd <your-project-name>5.执行以下命令 cnpm install6.执行以下命令安装elment-plus cnpm install element-plus --save7.执行以下命令 npm run dev…

Vuepress 2从0-1保姆级进阶教程——美化与模板

Vuepress 2 专栏目录 1. 入门阶段 Vuepress 2从0-1保姆级入门教程——环境配置篇Vuepress 2从0-1保姆级入门教程——安装流程篇Vuepress 2从0-1保姆级入门教程——文档配置篇Vuepress 2从0-1保姆级入门教程——范例与部署 2.进阶阶段 Vuepress 2从0-1保姆级进阶教程——全文搜索…

使用unplugin-auto-import页面不引入api飘红

解决方案&#xff1a;. tsconfig.json文件夹加上 {"compilerOptions": {"target": "ES2020","useDefineForClassFields": true,"module": "ESNext","lib": ["ES2020", "DOM", &q…

Python程序设计 循环结构(二)

1.斐波那契数列 编写一个能计算斐波那契数列中第x个数的小程序。斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列、 因数学家莱昂纳多斐波那契&#xff08;Leonardoda Fibonacci&#xff09;以兔子繁殖为例子而引入&#xff0c;故又称为…