深入javascript计划五:深入浅出原型

vue.js——学习计划表 id:'1',subject:'Vue.js前端实战开发',content:'学习指令,例如v-if、v-for、v-model等',place:'自习室',},])</script>上述代码中,list数组表示渲染表格区域所需的数据,id属性表示序号,subject属性表示学习科目,content属性表示学习内容,place属性表示学习地点,status属性表示学习计划的完成状态,若属性值为false,表示“未完成”,若属性值为true表示“已完成”。 阅读详情

看例子:

函数:

function test() {}
console.dir(test)

对象:

let test = {}
console.dir(test)

 从上面例子可以看得出,只有函数才有原型(prototype)属性,它们都有__proto__属性(下文会讲解)。

prototype

只有函数才会产生prototype,但是也有一个例外:

let fun = Function.prototype.bind()

这个创建函数是没有prototype属性的(下文会讲解)。

prototype是如何产生的?

当我们声明一个函数时,这个属性就自动创建了

function Person() {}

并且prototype属性的值是一个对象(也就是原型),只有一个属性constructor。

constructor对应着构造函数(也就是Person函数)。

constructor

constructor 是一个公有且不可枚举的属性。一旦我们改变了函数的 prototype ,新对象就没有这个属性了(当然可以通过原型链取到 constructor)。

function Person() {}
console.log(Person.prototype)
Person.prototype = { a: 1}
console.log(Person.prototype)

那么你肯定也有一个疑问,这个属性到底有什么用呢?其实这个属性可以说是一个历史遗留问题,在大部分情况下是没用的,在我的理解里,我认为他有两个作用:

1.让实例对象知道是什么函数构造了它

2.如果想给某些类库中的构造函数增加一些自定义的方法,就可以通过 xx.constructor.method 来扩展

__proto__

这是每个对象都有的隐式原型属性,指向了创建该对象的构造函数的原型。

其实这个属性指向了 [[prototype]],但是 [[prototype]] 是内部属性,我们并不能访问到,所以使用__proto__来访问。

因为在 JS 中是没有类的概念的,为了实现类似继承的方式,通过 __proto__ 将对象和原型联系起来组成原型链,得以让对象可以访问到不属于自己的属性。

实例对象__proto__是如何产生的?

当我们使用 new 操作符时,生成的实例对象拥有了__proto__属性。

function Person() {}
// 这个函数是 Function 的实例对象
// function 就是一个语法糖
// 内部调用了 new Function(...)

所以可以说,在 new 的过程中,新对象被添加了 __proto__ 并且链接到构造函数的原型上。

new过程:

  1. 新生成一个新对象
  2. 链接到原型
  3. 绑定this
  4. 返回新对象

自己实现一个 new,看起来会更加直观

function create() {
	// 创建一个空的对象
	let obj = new Object()
	// 获得构造函数
	let Con = [].shift.call(arguments)
	// 链接到原型
	obj.__proto__ = Con.prototype
	// 绑定 this,执行构造函数
	let result = Con.apply(obj, arguments)
	// 确保 new 出来的是个对象
	return typeof result === 'object' ? result : obj
}

对于实例对象来说,都是通过 new 产生的,无论是

function Person() {}
// function是语法糖
// 内部等同于 new Function()

还是(字面量)

let a = { b : 1 }
// 内部使用了new Object()

对于创建一个对象来说,更推荐使用字面量的方式创建对象。

因为你使用 new Object() 的方式创建对象需要通过作用域链一层层找到 Object,但是你使用字面量的方式就没这个问题。

Function.__proto__ === Function.prototype

大图:

对于对象来说,xx.__proto__.contrcutor 是该对象的构造函数,但是在大图中我们可以发现 Function.__proto__ === Function.prototype,难道这代表着 Function 自己产生了自己?

答案:肯定是否认的,要说明这个问题我们先从 Object 说起。

Object

console.dir(Object)

展开prototype

 

从大图中我们可以发现,所有对象都可以通过原型链最终找到 Object.prototype,

虽然 Object.prototype 也是一个对象,但是这个对象却不是 Object 创造的,而是引擎自己创建了 Object.prototype 。

所以可以这样说,所有实例都是对象,但是对象不一定都是实例。

Function

console.dir(Function)

 

 我们知道函数都是通过 new Function() 生成的,难道 Function.prototype 也是通过 new Function() 产生的吗?

答案:也是否定的,这个函数也是引擎自己创建的。

首先引擎创建了 Object.prototype ,然后创建了 Function.prototype ,并且通过 __proto__ 将两者联系了起来。

 

这里也很好的解释了上面的一个问题(为什么 let fun = Function.prototype.bind() 没有 prototype 属性)。

因为 Function.prototype 是引擎创建出来的对象,引擎认为不需要给这个对象添加 prototype 属性。

 

所以我们又可以得出一个结论,不是所有函数都是 new Function() 产生的。

有了 Function.prototype 以后才有了 function Function() ,然后其他的构造函数都是 function Function() 生成的。

 

现在可以来解释 Function.__proto__ === Function.prototype 这个问题了

因为先有的 Function.prototype 以后才有的 function Function() ,所以也就不存在鸡生蛋蛋生鸡的悖论问题了。

 

对于为什么 Function.__proto__ 会等于 Function.prototype ?

个人的理解是:其他所有的构造函数都可以通过原型链找到 Function.prototype ,并且 function Function() 本质也是一个函数,为了不产生混乱就将 function Function() 的 __proto__ 联系到了 Function.prototype 上。

总结

  1. Object 是所有对象的爸爸,所有对象都可以通过 __proto__ 找到它
  2. Function 是所有函数的爸爸,所有函数都可以通过 __proto__ 找到它
  3. Function.prototype 和 Object.prototype 是两个特殊的对象,他们由引擎来创建
  4. 除了以上两个特殊对象,其他对象都是通过构造器 new 出来的
  5. 函数的 prototype 是一个对象,也就是原型
  6. 对象的 __proto__ 指向原型, __proto__ 将对象和原型连接起来组成了原型链

 

还不懂的话看下面

 

var a = {};
console.log(a.prototype); //undefined
console.log(a.__proto__);  //Object {}

var b = function(){}
console.log(b.prototype); //b {}
console.log(b.__proto__);  //function() {}

/*1、字面量方式*/
var a = {};
console.log(a.constructor); //function Object() { [native code] } (即构造器Object)
console.log(a.__proto__ === a.constructor.prototype); //true

/*2、构造器方式*/
var A = function (){}; var a = new A();
console.log(a.constructor); // function(){}(即构造器function A)
console.log(a.__proto__ === a.constructor.prototype); //true

/*3、Object.create()方式*/
var a1 = {a:1} 
var a2 = Object.create(a1);
console.log(a2.constructor); //function Object() { [native code] } (即构造器Object)
console.log(a2.__proto__ === a1);// true 
console.log(a2.__proto__ === a2.constructor.prototype); //false(此处即为图1中的例外情况)

var A = function(){};
var a = new A();
console.log(a.__proto__); //Object {}(即构造器function A 的原型对象)
console.log(a.__proto__.__proto__); //Object {}(即构造器function Object 的原型对象)
console.log(a.__proto__.__proto__.__proto__); //null

抄袭:

https://juejin.im/post/5835853f570c35005e413b19

https://github.com/KieSun/Dream/issues/2

vue.js制作学习计划表案例 通俗易懂,完成“学习计划表”用于对学习计划进行管理,包括对学习计划进行添加、删除、修改等操作。 阅读详情

相关推荐

实战指南:基于华为Ascend NPU的大模型W8A8量化调优与精度提升

本文提供了一份基于华为Ascend NPU进行大模型W8A8量化的实战调优指南。详细介绍了从环境搭建、使用msmodelslim框架进行基础量化,到通过离群值抑制、校准集优化和量化回退等关键技术提升精度的全流程。旨在帮助开发者在华为NPU硬件上实现模型推理的显著加速,同时有效控制精度损失。

weixin_29227425的博客 271

JavaScript 中的原型

1.函数定义时,就存在一个属性prototype,它的值是一个普通的Object对象,这就是原型; 2.对象都是由构造函数new出来的,构造函数是由Function() new出来的,Function是浏览器创建js引擎时就已经存在; 3.constructor,获取对象的构造函数(obj.constructor),这个属性存储在构造函数的原型中,对象会继承原型中的方法和属性 4.对象的隐式原型(obj.__proto__)指向创建该对象的构造函数的原型(),指向同一空间 ...

m0_58510118的博客 2300

深入解析STM32定时器中央对齐模式3的双中断机制

本文深入解析了STM32定时器中央对齐模式3的双中断机制。该模式在一个PWM周期内,会在计数器到达ARR(上溢)和0(下溢)时各触发一次更新中断,实现更精细的实时控制。文章详细阐述了其工作原理、配置方法,并指导如何在中断服务函数中通过DIR位区分中断来源,同时探讨了其在电机控制、数字电源等场景下的应用优势与CPU负载挑战。

weixin_29164185的博客 493

JavaScript中的原型与原型链

原型 原型是一个对象,通过原型可以实现对象的属性继承。 JavaScript中,只有函数才有prototype属性。_proto_是每个对象都拥有的属性。 这两个属性就是new的过程实现的关键。 当一个函数被用作构造函数来创建实例时,这个函数的prototype属性值会被作为原型赋值给对象实例,也就是会被赋给实例对象的_proto_属性。 new的过程: 1.创建一个空对象var obj={};...

Carol的小星球 226

缠论 公式 自动画线 画笔 中枢 买卖点 源代码

【代码】缠论 公式 自动画线 画笔 中枢 买卖点 源代码。

weixin_40835859的博客 2万+

微信小程序实现锚点效果 scroll-view的scroll-into-view属性

小程序中实现锚点效果,可以直接使用scroll-view的scroll-into-view属性就可以实现锚点效果,比较方便简单。那么需要用到scroll-view那些参数呢,下面具体讲讲:效果展示: wxml **注意:**viewid值是动态的,通过setData设置即可。js wxss......

FaxMiao的博客 5449

是否所有函数都有prototype

是否所有函数都有prototype 使用Function.prototype.bind创建的函数对象 function abc(){console.log('abc')} var binded = abc.bind(null) binded() //abc console.log(binded.prototype) //undefined 箭头函数也没有 var abc = ()=>{console.log('abc')} abc() //abc console.log(abc.prototype)

追随大神的脚步 1706

基于BenchmarkSQL的达梦数据库TPCC性能测试

中的用户和密码在达梦数据库中创建测试用户,并保证其表空间足够容纳生成的测试数据。如果开启了归档,还要考虑归档日志占用的空间。BenchmarkSQL默认不支持达梦数据库。这里我们让BenchmarkSQL把达梦数据库当作Oracle即可。Oracle数据库对应的测试配置文件为。是使用BenchmarkSQL进行性能测试的主要配置文件。是生成的测试报告,png文件是报告中包含的图片。拷贝达梦数据库驱动到BenchmarkSQL的。测试结束后,会在当前路径下生成一个以。规则命名的结果目录。

Sebastien23的博客 2634

IC领域常见职位简称AE、FAE、PE、SE、VE、ME、TE、PTE、PL、PM、Sales

这些职业在集成电路产业链的不同环节发挥着重要作用,共同推动着IC技术的发展和创新。

嵌入式Stark 2万+

别再被 SerialPort 坑了!C# 串口通信的 3 大隐形陷阱与工业级解决方案

NET的SerialPort类更适合实验室调试,而非工业现场——它的设计目标是“能用”,而非“稳定”。工业级串口通信的核心,是在SerialPort基础上构建一层“防护壳”,用主动轮询对抗事件失效,用硬件级操作解决缓冲区谎言,用原子性流程避免关闭死锁。本文提供的类已在30+工业项目中验证(包括汽车生产线、智能仓储、环境监测),可直接替换原生SerialPort,解决90%以上的“玄学问题”。记住:工业场景的“稳定”,从来都不是靠运气,而是靠对每个细节的偏执把控。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 743

Python爬虫实战:如何抓取POI信息(公共场所)位置信息

获取公共场所的信息:如餐厅、商店、医院、景点等。抓取POI的基本信息:如名称、类别、地址、评分等。获取POI的地理坐标:经度和纬度信息。存储POI数据:将抓取到的POI信息存储到本地数据库中。通过本篇文章,我们详细介绍了如何使用Python爬虫抓取POI信息。通过Google Maps API和OpenStreetMap(Overpass API),我们展示了如何获取餐厅、商店、医院等公共场所的位置信息,并进一步探讨了如何处理分页、存储数据以及反爬虫策略。

2201_76125261的博客 378

js构造函数constructor和原型prototype

所有引用类型(函数,数组,对象)都拥有__proto__属性(隐式原型) 所有函数拥有prototype属性(显式原型)(仅限函数)  原型对象:拥有prototype属性的对象,在定义函数时就被创建   __proto__, prototype和constructor 下面这三个属性的定义非常重要,始终贯穿在原型中。 prototype:此属性只有构造函数才有,它指向的是当前构造函数的...

xiasohuai的博客 1357

Synthesia技术浅析(四):自然语言处理

Synthesia 的自然语言处理(NLP)模块是其核心技术之一,涵盖了文本转语音(TTS)、情感分析以及多语言支持等多个方面。

m0_75253143的博客 1166

原型链:JavaScript 对象继承的底层脉络

JavaScript原型链深度解析 本文系统梳理了JavaScript原型链的核心机制与应用场景。原型链通过[[Prototype]]内部属性实现对象间的继承关系,每个对象关联一个原型对象,形成链式结构。关键点包括: 三要素:对象的__proto__属性、构造函数的prototype属性、以及终点的Object.prototype; 查找机制:属性访问沿原型链递归查找,自身属性优先; 继承实现:通过Object.create()建立原型链连接,结合构造函数调用完成完整继承; 局限性:引用类型共享问题,ES6

你若盛开,清风自来 1284

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

视频教程-Javascript深入浅出-JavaScript

Javascript深入浅出 江湖花名"King"全栈工程师,开发工程师。曾...

weixin_30048515的博客 247

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

技术分享:JavaScript之深入原型与原型链

一、前言 计划写一套JavaScript的深入系列,主要用于JavaScript相关知识点和难点梳理,也是对原有知识的review。 本文主要讲解构造函数、原型、原型链的定义,以及他们之间的关系。如何通过原型对象的内部指针的形成原型链?如何检测原型,原型链等。 二、原型 1、构造函数 在讲解原型前,首先需要知道什么是构造函数,先看一个例子: function Person() {} const p = new Person(); 复制代码 ...

mashibing_web的博客 217

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

原型链底层原理:JavaScript对象系统的隐形脉络

原型链的核心机制与JavaScript继承模式 本文深入剖析了JavaScript中原型链的本质、工作原理及应用场景。原型链本质上是一种对象间的隐式委托机制,通过[[Prototype]]内部槽实现属性查找的链式结构。文章详细解析了原型链的三个核心组件:对象的[[Prototype]]、函数的prototype属性以及Object.prototype根节点,并阐述了V8引擎在属性访问时的三步查找流程。 在内存结构方面,原型链以指针形式实现单向链接,与垃圾回收机制协同工作。文章还介绍了原型链在继承模式中的经典

你若盛开,清风自来 978

深入javascript计划四:深入浅出this

这篇我们来深入了解this,this关键字是javascript中最复杂的机制之一,它是一个很特别的关键字,被自动定义在所有函数的作用域中(网上翻到几位大佬写的文章,写得很完善我就直接抄过来整合一下~)。 什么是this? 1.this是javascript中的关键字。它是对象自动生成的一个内部对象,只能在对象内部使用。随着函数使用场合不同,this的值会发生变化。 2.this指向什么?完全取决于什么地方以什么方式调用,而不是创建时(this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能

echo_Ae的博客 390

V少JS基础班之第七弹:原型链

原型链

优快云_Xying的博客 902

JavaScript全面知识总结:JS正则表达式+markdown语法+前端大厂面试题+项目实例

秋招时节,又有无数投向大厂的简历石沉大海,想进面大厂,到底差在哪里?总结一些前端工程师的学习忠告给大家。 学习前端不要总停留在框架的使用上。唯有系统性地掌握编程思想、设计理念,以及具体的实现方式,方可在面试和工作时做到游刃有余,以免进退失据。 而JavaScript的掌握程度直接影响了我们对于框架的理解程度。 个人认为JS就是一门语言,如果把前端比作一个人的身体,那么HTML就是一个人的结构,CSS就是这个人长的样子,那么JS就是一个人的行为,不是说HTML和CSS不重要,只是JS相比较而言更难一点..

优快云能力认证官方博客 5906

深入解析JavaScript原型继承的底层原理

本文深入探讨JavaScript原型继承机制,从底层原理剖析对象与原型的关系。通过分析[[Prototype]]内部属性、原型链机制、对象创建方式(Object.create、构造函数、ES6类)以及属性查找过程,系统阐述了原型继承的工作原理。文章重点解析了构造函数与prototype属性的关系、Object.prototype的特殊地位,并探讨了原型继承在内存管理方面的优势与注意事项,包括共享方法的优化和避免内存泄漏的方法。通过具体代码示例,展示了如何利用原型实现高效继承,为理解JavaScript面向对

你若盛开,清风自来 661

深入javascript计划七:深入浅出Event loop

为什么javascript是单线程? 因为最初javascript就是为了和浏览器交互而诞生的,如果 JS 是门多线程的语言话,我们在多个线程中处理 DOM 就可能会发生问题(一个线程中新加节点,另一个线程中删除节点),当然可以引入读写锁解决这个问题,为了避免复杂性,设计者还是把它设计成单线程模式。 后来,HTML5提出Web Worker标准, 允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM,所以这个新标准并没有改变JavaScript单线程本质。 Event

echo_Ae的博客 340

JavaScript之彻底理解原型与原型链_js contructor

知识的海洋往往比想象中还要辽阔,原型与原型链这边也反复的学过多次,我认为应该学的比较全面,比较完善了。但遇到这个面试题后,我才发现我所学的只不过是一根枝干,JS里面真的有很多深层次的宝藏等待挖掘。学海无涯,与君共勉。学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

2401_84538135的博客 471

js高级 原型与原型链和闭包问题

至此原型链闭合完毕,而原型链的尽头就是。

2302_80391964的博客 692

JS总结(JS世界构造顺序、学习计划)

1.JS唯一公式 对象.__proto__ === 其构造函数.prototype 2.根公理 (公理是人为规定的,是不容置疑的) Object.prototype是所有对象的(直接或间接)原型 3.函数公理 所有函数都是由Function构造的 任何函数.__proto__ === Function.prototype 任何函数包括:Object、Array(数组)、Function 4.难点 [的原型] 等价于 .__proto__ 只不过.__proto__正好是某个函数的prototy

前端知识库 361

深入理解JavaScript原型继承:原理、应用与最佳实践

本文深入解析JavaScript原型继承机制,包括其底层原理、应用场景和常见问题。原型继承基于对象委托机制,通过原型链实现属性和方法的共享。文章详细介绍了使用Object.create、构造函数和ES6类创建原型对象的方法,并探讨了原型继承在方法共享、实现继承和扩展内置对象中的应用。针对原型链污染、属性继承和性能问题,提出了相应的解决方案和最佳实践,如谨慎扩展内置对象、优化原型链查找等。掌握这些知识有助于开发者更高效地利用原型继承,提升代码质量和性能。

你若盛开,清风自来 892
上一篇: 深入javascript计划四:深入浅出this
下一篇: 深入javascript计划六:深入浅出异步
An_s
博客等级 码龄10年 665粉丝 363原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

An_s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值