草庐IT

原型和原型链的深入浅出

131362wsc 2023-03-28 原文

一.前言

假如我们创建了一个对象,只有一个成员变量name,

let ss = {
  name: 'shucheng',
 }
 console.log(ss);

结果如下:可以看出该对象有很多原型方法

  

通过上面的铺垫,我们知道::::::::::::::::::::::

JavaScript 的每个对象都继承另一个父级对象,父级对象称为原型 (prototype)对象。原型也是一个对象,原型对象上的所有属性和方法,都能被子对象 (派生对象) 共享。通过构造函数生成实例对象 时,会自动为实例对象分配原型对象

而每一个构造函数都有一个prototype属性,这个属性就是实例对象的原型对象。

 上图就可以明了的证明构造函数和原型对象之间的关系,那么我们再来看实例和原型对象的关系。依照上面的关系图,实例的内部指针 proto 指向原型对象,构造函数的原型也指向同一个原型对象。

对于原型的理解如下:

(1)所有的引用类型(包括数组,对象,函数)都有隐性原型属性(_proto_), 值也是一个普通的对象。(见上图,可以看出原型对象就是灰色的部分,其里面的属性值也是可以访问的。)

(2)所有的函数,都有一个 prototype 属性,值也是一个普通的对象。

(3)所有的引用类型的proto属性值都指向构造函数的 prototype 属性值。

要理解原型就要明白构造函数、实例对象、原型之间的关系,我用一张图来表示出他们之间的关系,如下图所示:

 

 构造函数new出来一个对象,而每个对象都有一个constructor属性,该属性指向创建该实例的构造函数,构造函数的prototype属性是这个new出来的实例化对象的原型,实例对象通过__proto__或者object.getPrototype的方法获取原型。转化关系实例如下图所示

2.1.原型链

那么明白了三者之间的关系我们就来说一下原型链,从一个实例对象向上找有一个构造实例的原型对象,这个原型对象又有构造它的上一级原型对象,如此一级一级的关系链,就构成了原型链。原型链的最顶端就是Object.prototype ;

原型链的形成就是对象的属性和方法,有可能是定义在自身内的,也有可能会定义他的原型对象上。由于原型本身也是对象,又有了自己的原型,所以就会形成。

总的来说它是实现继承的主要方法,基本思想就是利用原型让一个引用类型继承另一个引用类型的属性和方法。

 二.原型链的理解实例

function MyTest(name,age){
    this.name=name;
    this.age=age;}MyTest.prototype={
    "constructor":MyTest,
    "showName":function(){
        console.log(this.name);
    },
    "showAge":function(){
        console.log(this.age);
    }}
var newMyTest01=new MyTest('安静的木马',18);

代码中我们通过new构造器MyTest,生成实例化对象newMyTest01,那么newMyTest01就有一个隐形属性__proto__指向MyTest.prototype原型对象。
①现在访问newMyTest01.name,因为newMyTest01对象上有name属性,值为“安静的木马”,这个可以直接访问到
②现在我们访问newMyTest01.showName方法呢,newMyTest01对象上并没有直接定义showName方法,访问不到,然后newMyTest01就会通过__proto__属性找到MyTest.prototype,也就是MyTest的原型对象,看看能不能访问到showName方法,现在是可以访问到了。
③如果MyTest.prototype对象里面也没有showName方法呢?那就通过MyTest.prototype对象的__proto__继续找,在原型链查找中,一般到Object.prototype.__proto__还查找不到时,就会终止查找,因为ECMA规范里说明Object.prototype.__proto__是原型链终点,值为null,而这个时候那个没有访问到的属性值设置为undefined,并不爆出语法错误,这是原型链查找和作用域链查找的一个显著区别。

 

 

有关原型和原型链的深入浅出的更多相关文章

  1. jquery - 在 Rails 中从原型(prototype)切换到 jquery,助手呢? - 2

    我目前从prototype切换到jquery主要是为了支持简单的ajax文件上传。我使用:https://github.com/indirect/jquery-rails95%的javascript代码是由railshelper编写的,例如:-remote_function-render:updatedo|page|-page.replace_html'id',:partial=>'content'-page['form']['name']=something-page.visual_effect:highlight,'head_success'...我知道我必须为Jquery重写5%

  2. ruby - 如何检测 Ruby 中方法链的结束 - 2

    我有一个我不久前写的Flickr界面,其中一部分让我很困扰,我想让它变得更好。它的工作方式是我使用缺少的方法从调用flickr对象的方法构造flickr调用的url参数,例如。@flickr.groups.pools.getPhotos(:user_id=>"12656878@N06",:group_id=>"99404851@N00")这些“方法调用”构造了一个如下所示的api调用http://api.flickr.com/services/rest/?method=groups.pools.getPhotos&user_id=1848466274&group_id=99404851

  3. ChatGPT教程之深入了解魔术背后的技术 - 2

    解开谜团:深入探索ChatGPT的技术奇迹。ChatGpt无处不在,无论是在播客、博客、YouTube还是社交媒体上。当我注意到这项新技术如此受欢迎时,我决定试一试,我被震惊了!有很多关于ChatGpt及其魔力的博客,但在这篇博客中,我将深入探讨其内部技术及其工作原理!ChatGpt简介根据OpenAI,ChatGpt被描述为:“我们训练了一个名为ChatGpt的模型,它以对话方式进行交互。对话格式使ChatGpt可以回答后续问题、承认错误、挑战不正确的前提并拒绝不适当的请求。ChatGPT是InstructGPT的兄弟模型,它经过训练可以按照提示中的说明进行操作并提供详细的响应。”OpenA

  4. geth下载安装配置环境及联盟链的搭建 - 2

    以太坊概论考察课更具课堂教学讲解,参考开放资料。使用所学的知识,创建项目并完成要求的内容。包含的功能和要求具体如下:一:安装并运行geth客户端1、下载安装geth首先下载geth:https://geth.ethereum.org/downloads/​选择路径↓2、配置环境变量3、运行geth如下命令所示:查看geth命令。使用gethversion查看geth版本号,判断geth是否成功安装。如下命令所示:`gethversion`可以通过geth--help查看geth工具所支持的命令和相关参数,方便后期关于geth的操作。如下命令所示:geth--help运行结果如下:二:搭建get

  5. 科大讯飞刘聪:由ChatGPT浪潮引发的深入思考与落地展望 - 2

    近期,以“生成式人工智能”(GenerativeAI)为核心技术的聊天机器人ChatGPT火爆全球。百度、阿里巴巴、科大讯飞、360等国内企业纷纷抛出ChatGPT相关进展,打造中国版的ChatGPT。科大讯飞此前在投资者互动平台表示,ChatGPT主要涉及到自然语言处理相关技术,属于认知智能领域的应用之一,公司在该方向技术和应用具备长期深厚的积累。并称2022年12月已进一步启动生成式预训练大模型任务攻关,类ChatGPT技术将在今年5月率先落地科大讯飞AI学习机产品。近日,科大讯飞副总裁、研究院执行院长刘聪围绕什么是ChatGPT,它强在哪里?会对未来世界带来哪些颠覆性影响?进一步阐述Ch

  6. ruby-on-rails - 使用 rSpec 测试 delayed_job 链的最佳方法是什么? - 2

    目前,当我的代码中有一个延迟方法时,如下所示:CommentMailer.delay.deliver_comments(@comment,true)我在规范中写了这样的东西:dj=mock("DelayProxy")CommentMailer.should_receive(:delay).and_return(dj)dj.should_receive(:deliver_comments).with(comment,true)一般来说,有没有更好的方法来处理这个和/或类似rSpec中的链式方法? 最佳答案 我们可以在beforeblo

  7. 深入理解C++中的move和forward! - 2

    导语 |  在C++11标准之前,C++中默认的传值类型均为Copy语义,即:不论是指针类型还是值类型,都将会在进行函数调用时被完整的复制一份!对于非指针而言,开销及其巨大!因此在C++11以后,引入了右值和Move语义,极大地提高了效率。本文介绍了在此场景下两个常用的标准库函数:move和forward。一、特性背景(一)Copy语义简述C++中默认为Copy语义,因此存在大量开销。以下面的代码为例:0_copy_semantics.cc#include#includeclassObject{public:Object(){std::coutv;v.push_back(obj);}最终的输出

  8. 深入理解Linux文件系统与日志分析 - 2

    目录引言:一、inode和block1、inode和block概述2、inode的内容1.inode包含文件的元信息(文件属性)2.用stat命令可以查看某个文件的inode信息3.Linux系统文件三个主要的时间属性  4.目录文件的结构3、inode的号码​5、硬盘分区后的结构6、inode的大小7、inode的特殊作用 二、链接文件三、案例:恢复EXT类型的文件四、案例:恢复XFS类型的文件五、日志文件1.日志的功能2.日志文件的分类3.日志保存位置1.常见的一些日志文件:2.扩展:日志检查3.小结:​4.日志消息的级别5.用户日志分析六、总结引言:inode是一个重要概念,是理解Uni

  9. javascript - 使用原型(prototype) [javascript] 的未定义结果 - 2

    所以我正在使用javascript学习原型(prototype),并尝试了一些代码:functionEmployee(name){this.name=name;}varm=newEmployee("Bob");varworking={isWorking:true};Employee.prototype=working;alert(m.isWorking);不幸的是,我收到了未定义的消息,而不是真实值。这个结果有什么原因吗?我做了几个测试。我得出的结论是,重新分配原型(prototype)对象会导致任何先前创建的Employee类实例无法访问在新分配的原型(prototype)中找到的任

  10. Javascript函数和原型(prototype)——通过调用方法的基本路由问题 - 2

    我正在接近从Ruby背景学习JavaScript,所以我在理解(并用语言表达)为什么我的代码无法产生我需要的结果时遇到了一些困难。我在pythontutor.com上运行它以查看正在发生的事情的分步演练,它证实了我的怀疑。但是,我不确定为什么会这样。我正在构建一个恒温器,一旦温度低于18dC,它应该会返回“绿色”。在倒数第二行,console.log是17,这是正确的,但是当我在最后一行调用thermostat.displayColor时,它仍然显示黄色。代码在那里终止,并且不会通过我期望的this.displayColor=this.currentColor()返回(因为它在第一次运

随机推荐