js原型和原型链你只要看这一篇

2023-11-14

一、原型概述

    任何对象都有一个原型对象,这个原型对象由对象的内置属性_proto_指向它的构造函数的prototyoe指向的对象,即任何对象都是由一个构造函数创建的,被创建的对象都可以获得构造函数的prototype属性,注意:对象是没有prototype属性,只有方法才有prototype属性。

    任何对象都有一个constructor属性,指向创建此对象的构造函数,比如说{}对象,它的构造函数是function Object(){}。

 

	function Person() {
	}
	var p = new Person();
	//方法才有prototype,普通对象无prototype
	console.log(Person.prototype); // Object{} 
	console.log(p.prototype); // undifined
	
	//任何对象都是有构造函数constructor,由构造函数创建的对象也可以获得构造函数的引用
	//此处只是打印下列对象的构造函数是什么。
	console.log(p.constructor); //function Person(){}  
	console.log(Person.constructor); //function Function(){} 
	console.log({}.constructor); // function Object(){}
	console.log(Object.constructor); // function Function() {}
	console.log([].constructor);  //function Array(){} 

    那什么是构造函数呢?

    用function声明的都是函数,而如果直接调用的话,那么Person()就是一个普通函数,只有用函数new产生对象时,这个函数才是new出来对象的构造函数

二、创建对象的过程

    2.1 、声明方法的过程

    首先,当我们声明一个function关键字的方法时,会为这个方法添加一个prototype属性,指向默认的原型对象,并且此prototype的constructor属性就是此方法。此二个属性会在创建对象时被对象的属性引用。

	function Hello() {
	}
	console.log(Hello.prototype); // Object {} -- > 内部的constructor 指向Hello方法
	console.log(Hello.prototype.constructor); // function Hello(){}

  2.2、创建一个对象,从构造函数继承了什么属性?

    console.log(h.constructor); // function Hello(){}
    console.log(Object.getPrototypeOf(h)==Hello.prototype); // true  备注:getPrototypeOf是获取_proto_

  我们惊喜的发现,new出来的对象,它的constructor指向了方法对象,它的_proto_和prototype相等。

  即new一个对象,它的_proto_属性指向了方法的prototype属性,并且constructor指向了prototype的constructor属性。

  由构造函数创建一个对象,此对象多了一个_proto_属性指向构造函数的prototype,一个constructor属性指向构造函数的prototype的constructor属性。

  2.3 、创建一个对象的过程

	function Hehe(name) {
		this.name = name;
	}
	var h = new Hehe("笑你妹");
	//伪代码:
	function newObj(name){
		 var obj = {};
		 obj.__proto__ = Hehe.prototype; 
		 obj.constructor = Hehe.prototype.constructor;
		 var result = Hehe.call(obj, name);
		 return typeof result==='object'&& result!=null ? result : obj;  //当无返回对象或默认时返回obj。
	}
	var hh = newObj("笑你妹");
	console.log(hh);
	console.log(h);
	//虽然hh!=h,但是可以看到这个hh就和h的结构一样了。

    过程:先创建一个空对象,设置一个_proto_指向方法的原型,设置constructor,用新对象做this指向方法,返回新对象。

2.4、总结

    从上面说明的过程中,我们发现只要是对象就是有构造函数来创建的,并且内部二个属性是从构造函数的prototype衍生的一个指向,而构造函数的prototype也是一个对象,那么它应该肯定也有一个构造函数,首先它是一个Object {} 对象,那么它的构造函数肯定是Object,所以就会有一个指针_proto_指向Object.prototype。最后Object.prototype因为没有_proto_,指向null,这样就构成了一个原型链。

    三、原型链分析

    什么是原型链?

    原型链的核心就是依赖对象的_proto_的指向,当自身不存在的属性时,就一层层的扒出创建对象的构造函数,直至到Object时,就没有_proto_指向了。

    如何分析原型链?

    因为_proto_实质找的是prototype,所以我们只要找这个链条上的构造函数的prototype。其中Object.prototype是没有_proto_属性的,等于null。

    3.1、最简单的原型链分析

    function Person(name){
            this.name = name;
     }
     var p = new Person();
     //p ---> Person.prototype --->Object.prototype---->null

     上面原型链的分析:p的构造函数是Person创建的,那么Person.prototype就是继承的第一个原型,而Person.prototype没有自定义设置,默认就是一个Object对象,即是Object构造函数创建的,那么就是继承了Object.prototype,而Object.prototype再往上就没有_proto_指向了,等于null

    属性搜索原则:
     1.当访问一个对象的成员的时候,会现在自身找有没有,如果找到直接使用。
     2.如果没有找到,则去原型链指向的对象的构造函数的prototype中找,找到直接使用,没找到就返回undifined或报错。

     3.2、原型继承

//原型继承的基本案例
function Person(name, age) {
	this.name = name;
	this.age = age;
}
//1.直接替换原型对象 
var parent = {
	sayHello : function() {
		console.log("方式1:替换原型对象");
	}
}
Person.prototype = parent;
var p = new Person("张三", 50);
p.sayHello();
//2.混入式原型继承
console.log(".............混入式原型继承..............");
function Student(name, age) {
	this.name = name;
	this.age = age;
}
var parent2 = {
	sayHello : function() {
		console.log("方式2:原型继承之混入式加载成员");
	}
}
for ( var k in parent2) {
	Student.prototype[k] = parent2[k];
}
var p = new Student("张三", 50);
p.sayHello();

    3.3 原型链案例

// 查询原型链上的对象的方法
function findProtoType(obj) {
  var arr = [];
  while (obj != null) {
    obj = Object.getPrototypeOf(obj);
    arr.push(obj);
  }
  return arr;
};

function Root() {}

function Child() {}

Child.prototype = new Root();
Child.prototype.constructor = Child; // 这个步骤是为了让原型对象打印显示成自身(继承prototype同时也继承了constructor,因此替换成自身)

function Item() {}

Item.prototype = new Child();
Item.prototype.constructor = Item;

var result = findProtoType(new Item());
console.log(result);
//  [ Item { constructor: [Function: Item] },Child { constructor: [Function: Child] }, Root {}, {}, null ]

谢谢观看!

end!

 

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

js原型和原型链你只要看这一篇 的相关文章

  • 如何在input标签中写入提示信息

    在input中写入提示信息 需要用到HTML5中的placeholder属性
  • JavaScript读取json文件

  • JavaScript函数七重关之函数定义

    JavaScript函数七重关的第一关是函数定义 函数定义需要用到function关键字 function myFunction 函数体 document write hello javascrept br 这是函数定义的第一种方法 也可以
  • 学习CSSGrid布局

    一 重要术语 CSS Grid 网格 布局 又称为 Grid 网格 是一个二维的基于网格的布局系统 它的目标是完全改变我们基于网格的用户界面的布局方式 FlexBox 一维布局 Grid 二维布局 Flexbox 和 Grid 能协同工作
  • Bootstrap4 模态对话框示例

  • 2023年前端面试题集锦

    2023年又是行情惨淡的一年 为此我从 枇杷村IT面试宝典 小程序里收集了一些题目 更多题目可以扫下方二维码查看 现做个总结如下 1 在JavaScript中 0 0的结果是什么 结果为true 严格等于比较的是值和类型 对象除外 只要值和
  • css3颜色渐变:css3如何实现背景颜色渐变?

    为了开发网页的美观 css3背景颜色渐变是经常会用到的 那么 css3背景颜色渐变如何设置呢 本篇文章我们就来介绍关于css颜色渐变背景的设置方法 我们要知道的是css3渐变有两种类型 css3线性渐变和css3径向渐变 下面我们就来看一下
  • WAMP环境隐藏PHP文件实际路径和后缀名

    有时候做客户端开发阶段得测试 需要一个模拟服务器的环境 我使用得最顺手得还是WAMP环境 后台给出的api接口的路径千奇百怪 在WAMP环境中如何模拟这些路径呢 如何将某个路径下的PHP文件映射到另一个URL路径下并隐藏PHP文件后缀呢 在
  • React-Router实战:NavLink

    基础 1 引入使用 import NavLink from react router dom
  • VUE element-ui之el-popover弹出框在局部全屏下不显示问题及弹框、小箭头背景修改

    问题 局部全屏后el popover弹出框失效 解决方法
  • input标签是什么?input标签属性有哪些

    input标签属于什么标签 input标签属性有哪些 相信刚接触的表单的小白应该很陌生 那么接下来我们就来讲一下input标签属性有哪些 首先小编在这里谢谢大家一直的支持 每天都会更新十个web前端基础内容 需要的可以关注我 另外也可以进我
  • 前端js和jq中select下拉框

    获取select选中的option的值 ddlRegType find option selected val 获取select选中的text ddlRegType find option selected text 获取select选中的
  • uniapp的那些坑

    1 selectedColor不起作用 1 查看位置是否写对 与lis同级 2 是否为16进制 selectedColor写的rgb不支持 3 是否被其他样式覆盖 其他地方也设置过selectedColor 可以全局搜索一下 2 pages
  • Web启动项目走Https协议(Webpack版,Umi版和Host代理版)

    需求 Web项目的启动 一般是默认的http协议 在某些业务需求时 需要走https来调试 Webpack版本 只需在webpack的devServer中配置就可以了 devServer host 0 0 0 0 port 8080 htt
  • 20最佳代码审查工具-专门为开发人员准备

    程序员总是面临最后期限的压力和很多延误软件设计相当不稳定 整个产品是不稳定的 这种不稳定性的设计软件的原因是 它是不能正常测试 来的工作代码审查工具 的代码审查工具可以帮助web开发人员指出他们哪些区域的程序代码是错误的也可能有机会是不正确
  • vue/cli3添加自定义icon图标

    1 从阿里巴巴矢量图表库将需要的图标 加入购物车 点击购物车 2 选择添加至项目 3 下载到本地 放到项目中 4 在main js中引入iconfont css文件 以实际位置为准 import assets fonts download
  • 禁止ios浏览器页面上下滚动 (橡皮筋效果)弹性滚动 微信的下拉回弹

    发现之前阻止页面滚动的代码e preventDefault代码失效了 于是自己折腾了一番 找到了解决办法 一 前言 浏览器在移动端有一个默认触摸滚动的效果 让我们感触最深的莫过于微信浏览器里面 下拉时自带橡皮筋的效果 然而在开发的时候我们经
  • uni-app项目中使用scss语法

    最近正在学习uni app开发 我先把文档浅略翻了遍 发现组件和接口几乎都是按照微信小程序走 但是视图层上的语法又是按照vue的语法走的 所以开发过程一定要注意这点 然后我想在uni app项目中使用scss语法 但是具体怎么安装呢 历经曲
  • React 笔记 jsx

    严格约定 React 组件必须以 大写字母开头 而 HTML 标签则必须是小写字母 React JSX JSX 是由 React 推广的 JavaScript 语法扩展 用于表达组件的 特殊语法的 js 函数 要求标签必须闭合 返回的组件必
  • <a>标签的超链接前面会自动加上当前(网站)地址

    当前 网站 地址是 fyh com 在代码里写 a 标签时 会自动在链接前添加 fyh com 例如写如下代码 a href www baidu com baidu a 在浏览器中点击链接会跳转至 fyh com www baidu com

随机推荐

  • Unity 初识:坐标系与向量

    世界坐标系 场景中的绝对坐标系 场景上所有物体都是以该坐标系的原点来确定各自位置的 世界坐标即物体在世界坐标系中的位置 局部坐标系 以物体的世界坐标为原点 角度为朝向 大小为单位 所产生一个新的坐标系 该坐标系中 物体的位置 旋转 大小都会
  • 免费国外视频素材网站

    这里自己收藏几个可以免费下载国外视频的网站 希望大家喜欢 可以的话给个关注哟 Pexels Videos https videos pexels com Pexels 是一个著名的免费图片平台 每天都会有大量的设计师和博客写手来这里为他们的
  • 前端接入萤石云

    萤石云有两个方法使用 npm引入 非npm引入 两个方法中的js内容不同 所以容器初始化方法也不同 详情可到github查看 https github com Hikvision Ezviz npm引入 步骤一 首先通过npn下载 npm
  • 对字符串按照一定的长度来分行或者添加其他数据

    核心代码 对字符串按照一定的长度来分行或者添加其他数据 param str 原始字符串 param int length 插入的间隔长度 param string append 需要插入的字符串 return string 返回字符串 fu
  • 【程序员面试金典】实现一个函数,检查二叉树是否平衡,

    题目描述 实现一个函数 检查二叉树是否平衡 平衡的定义如下 对于树中的任意一个结点 其两颗子树的高度差不超过1 给定指向树根结点的指针TreeNode root 请返回一个bool 代表这棵树是否平衡 题目分析 lt 方法1 gt 平衡二叉
  • [附代码]多输入AD模数转换,数据接受模块 Verilog 实现 (授人与渔)

    要素察觉 本文基于 AD7888 八输入通道 模数转换芯片 对转换后的数据在 FPGA 中进行接收 所使用的 HDL 为 Verilog 所有实现步骤依据 AD7888 DataSheet 中给出的相关数据和时序图 对原理和相应 Veril
  • mysql中的锁

    锁分类 MySQL中的锁 按照锁的粒度分 分为以下三类 1 全局锁 锁定数据库中的所有表 2 表级锁 每次操作锁住整张表 3 行级锁 每次操作锁住对应的行数据 全局锁 全局锁就是对整个数据库实例加锁 加锁后整个实例就处于只读状态 后续的DM
  • 网易笔试题

    网易笔试不难 但是给了我一个教训 所以记下来以留念 时间 11月3日8 00 后来改到10 00 地点 西安交通大学教2南315教室 赶到考场时 离考试开始时间只差2分钟了 找了个座位坐下后没有任何的等待笔试就开始了 网易的笔试题目很有趣
  • CVE-2023-21839 【vulhub weblogic 漏洞复现】

    漏洞概述 由于Weblogic IIOP T3协议存在缺陷 当IIOP T3协议开启时 允许未经身份验证的攻击者通过IIOP T3协议网络访问攻击存在安全风险的WebLogic Server 漏洞利用成功WebLogic Server可能被
  • ffmpeg命令大全

    ffmpeg命令大全 FFMPEG 目录及作用 FFMPEG基本概念 FFMPEG 命令 基本信息查询命令 主要参数 视频参数 音频参数 录制 录屏 分解与复用 滤镜 简单滤镜 复杂滤镜 直播相关 前言 FFMPEG是特别强大的专门用于处理
  • c/c++获取文夹下所有图片文件路径

    在做项目的时候 我们有时候会遇到给定一个文件夹目录 获取该目录下某种类型的文件的路径 也就是遍历一个目录下的所有文件 经过查询 发现可以通过 代码实例 获取某一目录下所有的 jpg文件路径 include
  • Java知识点汇总第二篇(红色为重点内容,黄色为应用较多的,蓝色为了解的

    一 1 标识符 定义 用来表示变量名 类名 方法名 数组名和文件名的有效字符序列 以字母 下划线 美元符号等开始 后面可以跟字母 下划线 美元符号 数字等字符 注 不能以数字开始 大小写敏感 不能与关键字相同 2 关键字 定义 Java中被
  • 计算机网络-6-应用层

    Lecture06 应用层 本节PPT包含5 7三层 The Session Layer 会话层 The Presentation Layer 展示层 The Application Layer 应用层 1 第五层 The Session
  • 性能测试常见指标有哪些

    性能测试的常见指标包括 1 响应时间 Response Time 用户发送请求到系统返回结果所花费的时间 2 吞吐量 Throughput 单位时间内系统处理的请求数量 通常以每秒请求数 SPS或TPS 表示 3 并发用户数 Concurr
  • libev学习系列之三:libev编译安装

    libev学习系列之三 libev编译安装 版本说明 版本 作者 日期 备注 0 1 ZY 2019 5 31 初稿 目录 文章目录 libev学习系列之三 libev编译安装 版本说明 目录 源码结构 正常编译 交叉编译 源码结构 4 2
  • 龙书虎书鲸书啃不动?试试豆瓣评分9.5的猴书

    相传 编译原理界有三大圣书 龙书是为Compilers Principles Techniques and Tools 虎书是为Modern Compiler Implementation in C 鲸书是为Advanced Compile
  • python自动化办公(三十一)TKinter 先登录授权窗口,授权成功后进入master主窗口

    一 主简介 先登录授权窗口 比如验证账号密码信息等等 授权成功后进入master主窗口 验证成功后 进入主页面 Tkinter实现登录成功后进入主界面 月半的博客 CSDN博客 tkinter登录成功跳转主窗体
  • 安装Pycharm工具 -- ubuntu18.04

    在Ubuntu18 04下 pycharm工具的安装及其快捷方式的创建 下载pycharm安装包 tar gz包 网址 https www jetbrains com pycharm tar gz 安装包解压缩 此处没有指定解压到哪个路径
  • 最经典的黑客技术入门知识

    最经典的黑客技术入门知识 整理 Ackarlix 第一节 什么是黑客 以我的理解 黑客 大体上应该分为 正 邪 两类 正派黑客依靠自己掌握的知识帮助系统管理员找出系统中的漏洞并加以完善 而邪派黑客则是通过各种黑客技能对系统进行攻击 入侵或者
  • js原型和原型链你只要看这一篇

    一 原型概述 任何对象都有一个原型对象 这个原型对象由对象的内置属性 proto 指向它的构造函数的prototyoe指向的对象 即任何对象都是由一个构造函数创建的 被创建的对象都可以获得构造函数的prototype属性 注意 对象是没有p