你不知道的javascript之JS原型对象和原型链

2023-10-27

开篇

之前对js中的原型链和原型对象有所了解,每当别人问我什么是原型链和原型对象时,我总是用很官方(其实自己不懂)的解释去描述。有一句话说的好:如果你不能把一个很复杂的东西用最简单的话语描述出来,那就说明你没有真正的理解。最近正在读《Javascript高级程序设计》,书中对原型对象和原型链的描述让我受益匪浅,下面仅用一个对比性的例子来说明。

我们经常会这么写

    function Person () {
        this.name = 'John';
    }
    var person = new Person();
    Person.prototype.say = function() {
        console.log('Hello,' + this.name);
    };
    person.say();//Hello,John

上述代码非常简单,Person原型对象定义了公共的say方法,虽然此举在构造实例之后出现,但因为原型方法在调用之前已经声明,因此之后的每个实例将都拥有该方法。从这个简单的例子里,我们可以得出:
原型对象的用途是为每个实例对象存储共享的方法和属性,它仅仅是一个普通对象而已。并且所有的实例是共享同一个原型对象,因此有别于实例方法或属性,原型对象仅有一份。所有就会有如下等式成立:

 person.say == new Person().say

可能我们也会这么写

    function Person () {
        this.name = 'John';
    }
    var person = new Person();
    Person.prototype = {
        say: function() {
            console.log('Hello,' + this.name);
        }
    };
    person.say();//person.say is not a function

很不幸,person.say方法没有找到,所以报错了。其实这样写的初衷是好的:因为如果想在原型对象上添加更多的属性和方法,我们不得不每次都要写一行Person.prototype,还不如提炼成一个Object来的直接。但是此例子巧就巧在构造实例对象操作是在添加原型方法之前,这样就会造成一个问题:
当var person = new Person()时,Person.prototype为:Person {}(当然了,内部还有constructor属性),即Person.prototype指向一个空的对象{}。而对于实例person而言,其内部有一个原型链指针proto,该指针指向了Person.prototype指向的对象,即{}。接下来重置了Person的原型对象,使其指向了另外一个对象,即
Object {say: function},
这时person.proto的指向还是没有变,它指向的{}对象里面是没有say方法的,因为报错。
从这个现象我们可以得出:
在js中,对象在调用一个方法时会首先在自身里寻找是否有该方法,若没有,则去原型链上去寻找,依次层层递进,这里的原型链就是实例对象的_proto_属性。

若想让上述例子成功运行,最简单有效的方法就是交换构造对象和重置原型对象的顺序,即:

    function Person () {
        this.name = 'John';
    }
    Person.prototype = {
        say: function() {
            console.log('Hello,' + this.name);
        }
    };
    var person = new Person();
    person.say();//person.say is not a function

一张图让你秒懂原型链

这里写图片描述
其实,只需要明白原型对象的结构即可:

    Function.prototype = {
        constructor : Function,
        __proto__ : parent prototype,
        some prototype properties: ...
    };

总结:函数的原型对象constructor默认指向函数本身,原型对象除了有原型属性外,为了实现继承,还有一个原型链指针_proto_,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用_proto_一直指向Object的原型对象上,而Object的原型对象用Object._proto_ = null表示原型链的最顶端,如此变形成了javascript的原型链继承,同时也解释了为什么所有的javascript对象都具有Object的基本方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

你不知道的javascript之JS原型对象和原型链 的相关文章

随机推荐

  • vue3.0取消事件冒泡

    element plus取消事件冒泡造成的影响 代码示例为el dropdown标签 div span span div
  • Cuda实战-02 向量加法与内存分配

    概述 本节通过一个向量加法的实例程序探讨如何进行有效的内存分配 案例中定义了三个向量VectorA VectorB VectorC VectorA和VectorB为待计算的两个向量 VectorC为结果向量 VectorA初始值为 1 2
  • Java开发的打包和分发机制之jar包

    Welcome Huihui s Code World 接下来看看由辉辉所写的关于jar包的相关操作吧 一 什么是jar包 jar包 是Java Archive的缩写 它是一种用于打包Java类 资源文件 库等内容的文件格式 Jar包是一种
  • 服务器点播直播系统,服务器点播直播系统

    服务器点播直播系统 内容精选 换一换 在SAP系统中 除了SAP HANA节点使用裸金属服务器外 其他节点都使用弹性云服务器 Jump Host弹性云服务器 用户可通过访问该服务器后 再通过SSH协议跳转到SAP HANA及SAP应用节点
  • 程序员面试题精选100题(41)-把数组排成最小的数

    程序员面试题精选100题 41 把数组排成最小的数 题目 输入一个正整数数组 将它们连接起来排成一个数 输出能排出的所有数字中最小的一个 例如输入数组 32 321 则输出这两个能排成的最小数字32132 请给出解决问题的算法 并证明该算法
  • samba(SMB)的安装与使用(Ubuntu)

    samba用于Linux与Windows共享文件夹 包括虚拟机或云服务器等都可以使用 1 安装SMB sudo apt get install samba 2 创建共享目录 创建的目录即之后能够在Windows主机上直接访问的目录 例如 在
  • Java应用的GC优化

    最近看到这篇GC优化 自己标记一下 这里记录学习 Java应用的GC优化 当Java程序性能达不到既定目标 且其他优化手段都已经穷尽时 通常需要调整垃圾回收器来进一步提高性能 称为GC优化 但GC算法复杂 影响GC性能的参数众多 且参数调整
  • BeanUtils.copyProperties的使用(深拷贝,浅拷贝)

    文章目录 场景 BeanUtils是深拷贝 还是浅拷贝 什么情况适合用BeanUtils 有子对象就一定不能用BeanUtils么 代码例子 dest src 还是 src dest 这里说的是spring的BeanUtils copyPr
  • WPF中通过反射实现对象的复制粘贴

    WPF中通过反射实现对象的复制粘贴 1 前言 2 复制 3 粘贴 1 前言 在WPF项目开发过程中 需要实现一个功能 在当前界面的工程列表中 实现工程的复制粘贴功能 要求能够完整拷贝被复制的工程的各个参数 并生产一个跟被拷贝工程没有任何关联
  • 三菱PLC快速写入

    通常的写入过程是把整个PLC的程序内存进行写入 然而大多编写程序往往并不需要写入全部内存 所以我们需要通过调整PLC内存容量达成只写入适量的步数程序 来避免不必要的写入时间 调整程序容量 如图打开工程栏的参数 双击PLC参数来到FX参数设置
  • 安全测试-django防御安全策略

    django安全性 django针对安全方面有一些处理 学习如何进行处理设置 也有利于学习安全测试知识 CSRF 跨站点请求伪造 Cross Site Request Forgery CSRF 是一种网络攻击方式 攻击者欺骗用户在自己访问的
  • OpenCV-C++——基本操作总结

    文章目录 基本图像操作 1 创建空图像 2 获取图像尺寸 3 图像读取与显示 3 图像镜像 旋转 画线 遍历图像 基本图像操作 1 创建空图像 在OpenCV中 图像的类型是cv Mat 而cv Mat可作为任意维度的数组使用 0对应黑 2
  • Xenserver6.2设置VM开机自动启动

    XenServer 6 2中的虚拟机默认是不会自动启动的 据说是为了防止在HA环境中出现某些异常 所以如果母鸡 宿主机 异常断电恢复启动后 所有的虚拟机均为关机状态 但如果只是单台XenServer跑若干独立虚拟机 还是有必要让虚拟机开机自
  • WIFI版本云音响设置教程阿里云平台版本

    文章目录 WIFI本云音响设置教程介绍 一 申请设备三元素 1 登录阿里云物联网平台 2 创建产品 3 设置产品参数 4 添加设备 5 获取三元素 二 设置设备三元素 1 打开MQTTConfigTools 2 计算MQTT参数 3 使用w
  • 存储类型auto,static,extern,register的区别

    变量和函数的属性包括数据类型和数据的存储类别 存储类别指数据在内存中存储方式 静态和动态 包含auto static register extern四种 内存中 具体点来说内存分为三块 静态区 堆区 栈区 外部变量和全局变量存放在静态区 局
  • MySQL进阶语句

    目录 引言 一 常用查询 1 1 order by按关键字排序 升序排序 降序排序 结合where进行条件过滤在排序 多字段排序 1 2 and or判断 and or使用 1 3 distinct查询不重复记录 1 4 GROUP BY对
  • 使用IDEA进行git进行协同开发

    使用IDEA进行git进行协同开发 步入公司的第一步就是掌握版本控制工具的使用 常见的版本控制工具有两种方式 git常见于一些小的创业公司 项目小人员少 svn使用的公司规模较大 这里介绍git使用的一些场景 假设小组中有两个人 组长 组员
  • 期货模板实例

    以下是期货专用的API 1 get symbol 获得主力连续合约的映射合约 我们在进行生成信号时 可以使用助理合约时间序列 但在下单时要使用具体的合约 若想得到当天的主力合约映射的具体合约符号时 则可以使用context get symb
  • vs2013中配置多线程的使用环境

    提供vs2013的产品密钥供激活 BWG7X J98B3 W34RT 33B3R JVYW9 1 在Visual Studio 2013中配置 2 pthreads w32 下载地址 这里下载最新版本pthreads w32 2 9 1 f
  • 你不知道的javascript之JS原型对象和原型链

    开篇 之前对js中的原型链和原型对象有所了解 每当别人问我什么是原型链和原型对象时 我总是用很官方 其实自己不懂 的解释去描述 有一句话说的好 如果你不能把一个很复杂的东西用最简单的话语描述出来 那就说明你没有真正的理解 最近正在读 Jav