JS原型详解

2023-11-03

原型

  原型是 JavaScript 面向对象特性中重要的概念,也是大家太熟悉的概念。因为在绝大多
数的面向对象语言中,对象是基于类的(例如 Java 和 C++ ),对象是类实例化的结果。而在
JavaScript 语言中,没有类的概念①,对象由对象实例化。打个比方来说,基于类的语言中类
就像一个模具,对象由这个模具浇注产生,而基于原型的语言中,原型就好像是一件艺术品
的原件,我们通过一台 100% 精确的机器把这个原件复制出很多份。
 让我们看看如何使用原型和构造函数共同生成对象。

function Person() {
}
Person.prototype.name = 'BYVoid';
Person.prototype.showName = function () {
console.log(this.name);
};
var person = new Person();
person.showName();

  上面这段代码使用了原型而不是构造函数初始化对象。这样做与直接在构造函数内定义
属性有什么不同呢?
1. 构造函数内定义的属性继承方式与原型不同,子对象需要显式调用父对象才能继承构 造函数内定义的属性。
2. 构造函数内定义的任何属性,包括函数在内都会被重复创建,同一个构造函数产生的 两个对象不共享实例。
3. 构造函数内定义的函数有运行时闭包的开销,因为构造函数内的局部变量对其中定义 的函数来说也是可见的。

下面这段代码可以验证以上问题:

function Foo() {
var innerVar = 'hello';
this.prop1 = 'BYVoid';
this.func1 = function(){
innerVar = '';
};
}
Foo.prototype.prop2 = 'Carbo';
Foo.prototype.func2 = function () {
console.log(this.prop2);
};
var foo1 = new Foo();
var foo2 = new Foo();
console.log(foo1.func1 == foo2.func1); // 输出 false
console.log(foo1.func2 == foo2.func2); // 输出 true

尽管如此,并不是说在构造函数内创建属性不好,而是两者各有适合的范围。那么我们
什么时候使用原型,什么时候使用构造函数内定义来创建属性呢?

  1. 除非必须用构造函数闭包,否则尽量用原型定义成员函数,因为这样可以减少开销。
  2. 尽量在构造函数内定义一般成员,尤其是对象或数组,因为用原型定义的成员是多个 实例共享的。

接下来,我们介绍一下JavaScript中的原型链机制。


原型链

  JavaScript 中有两个特殊的对象: Object 与 Function,它们都是构造函数,用于生
成对象。 Object.prototype 是所有对象的祖先, Function.prototype 是所有函数的原
型,包括构造函数。我把 JavaScript 中的对象分为三类,一类是用户创建的对象,一类是**构
造函数对象,一类是原型对象**。用户创建的对象,即一般意义上用 new 语句显式构造的对
象。构造函数对象指的是普通的构造函数,即通过 new 调用生成普通对象的函数。原型对象
特指构造函数 prototype 属性指向的对象。这三类对象中每一类都有一个 proto
性,它指向该对象的原型,从任何对象沿着它开始遍历都可以追溯到 Object.prototype。
构造函数对象有 prototype 属性,指向一个原型对象,通过该构造函数创建对象时,被创
建对象的 proto 属性将会指向构造函数的 prototype 属性。原型对象有 constructor
属性,指向它对应的构造函数。让我们通过下面这个例子来理解原型:

function Foo() {
}
Object.prototype.name = 'My Object';
Foo.prototype.name = 'Bar';
var obj = new Object();
var foo = new Foo();
console.log(obj.name); // 输出 My Object
console.log(foo.name); // 输出 Bar
console.log(foo.__proto__.name); // 输出 Bar
console.log(foo.__proto__.__proto__.name); // 输出 My Object
console.log(foo. __proto__.constructor.prototype.name); // 输出 Bar

  我们定义了一个叫做 Foo ()的构造函数,生成了对象 foo。同时我们还分别给 Object
和 Foo 生成原型对象。
   图A-1 解析了它们之间错综复杂的关系
   js原型间的关系
                     图 A-1 JavaScript 原型之间的关系

  在 JavaScript 中,继承是依靠一套叫做原型链(prototype chain)的机制实现的。属性
继承的本质就是一个对象可以访问到它的原型链上任何一个原型对象的属性。例如上例的
foo 对象,它拥有 foo. _ _ proto_ _ 和 foo. _ _ proto_ _ . _ _ proto _ _ 所有属性的浅拷
贝(只复制基本数据类型,不复制对象)。所以可以直接访问foo.constructor(来自foo.
_ _ proto_ _ ,即Foo.prototype), foo.toString(来自foo. _ _ proto_ _ . _ _ proto__,
即Object.prototype)。
这里写图片描述

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

JS原型详解 的相关文章

  • 由于 apollo-client 未定义,无法解构 GraphQL 查询?

    我正在寻找调试与错误消息相关的问题 未捕获的类型错误 无法解构 0 apollo client WEBPACK IMPORTED MODULE 4 useQuery 因为它未定义 Context 我正在为我的 React js 项目设置后端
  • 如何使用 JavaScript 创建链接?

    我有一个标题字符串和一个链接字符串 我不知道如何将两者放在一起以使用 JavaScript 在页面上创建链接 任何帮助表示赞赏 我试图解决这个问题的原因是因为我有一个 RSS 源并且有一个标题和 URL 列表 我想将标题链接到 URL 以使
  • JavaScript 中的埃拉托斯特尼筛法对大量数据无限运行

    我一直在尝试写埃拉托斯特尼筛法 http en wikipedia org wiki Sieve of EratosthenesJavaScript 中的算法 基本上我只是按照以下步骤操作 创建从 2 到 n 1 的连续整数列表 令第一个素
  • IE从哪个版本开始支持Object.create(null)?

    您可以通过多种方式在 JavaScript 中创建对象 creates an object which makes the Object prototype of data var data1 new Object Object liter
  • 如何使用javascript将大图像转换为十六进制?

    如果我尝试将图像转换为十六进制 无论我使用哪个函数 我都会收到此错误消息 该图像的大小为 7 MB 19812 毫秒 清理 1401 2 1455 0 gt 1401 2 1455 0 MB 9 9 0 ms 自上次 GC 以来 8 3 m
  • 隐藏 Div 的父级

    我只是想隐藏父divcomments section div class content content green div div div 我试过这个 document getElementById comments section pa
  • Draggable JS Bootstrap 模式 - 性能问题

    对于工作中的项目 我们在 JavaScript 中使用 Bootstrap Modal 窗口 我们想让一些窗口可移动 但我们遇到了 JQuery 的性能问题 myModal draggable handle modal header Exa
  • React-Redux:state.setIn() 和 state.set() 有什么区别?

    我见过使用setIn and set 在一些react redux代码中 state setIn state set 我在这里找到了一些文档https facebook github io immutable js https facebo
  • 设置 cookie 时中断 JavaScript 执行

    当设置 cookie 时 是否可以始终中断浏览器开发人员工具中的 javascript 执行 无需显式设置 JS 断点 document cookie 在 html head 块的开头添加此代码片段效果很好
  • 调整图像大小并将画布旋转 90 度

    这里有很多关于在 js 上使用画布旋转图像的主题 我阅读了其中的大部分内容 但无法找到解决我的问题的方法 我正在接收任何分辨率的图像 来自上传组件 我将其大小调整为 1024x768 如下所示 var canvas document cre
  • 尝试将数据存储在点击器网站中

    我正在尝试存储一个名为的变量score无论何时刷新 您都会一次又一次地使用它 我不明白的是它的代码是什么 我尝试了一些方法 但似乎都不起作用 这是我的答题器网站 但是当我尝试使用 JavaScript 来存储它时 它不起作用window o
  • 在 HTML5 画布中,如何用我选择的背景遮盖图像?

    我试图用画布来实现这一点 globalCompositeOperation 但没有运气 所以我在这里问 这里有类似的问题 但我没有在其中找到我的案例 我的画布区域中有图层 从下到上的绘制顺序 画布底座填充纯白色 fff 用fillRect
  • Javascript split 不是一个函数

    嘿朋友们 我正在使用 javascript sdk 通过 jQuery facebook 多朋友选择器在用户朋友墙上发布信息 但是我收到此错误friendId split 不是函数 这是我的代码 function recommendToFr
  • 检查 jQuery 1.7 中是否存在基于文本的选择选项

    所以我有以下 HTML 片段
  • 为什么我们在打字稿中使用 HTMLInputElement ?

    我们为什么使用 document getElementById ipv as HTMLInputElement value 代替 document getElementById ipv value 功能getElementById返回具有类
  • DataTables row.add 到特定索引

    我正在替换这样的行项目 var targetRow entity row dataTable targetRow closest table dataTable DataTable dataTable row targetRow remov
  • Vuejs 2:去抖动不适用于手表选项

    当我在 VueJs 中反跳此函数时 如果我提供毫秒数作为原语 它就可以正常工作 但是 如果我将其提供为对 prop 的引用 它会忽略它 这是道具的缩写版本 props debounce type Number default 500 这是不
  • Javascript Replace() 和 $1 问题

    我正在尝试创建一个脚本来搜索文本中的模式并在它找到的字符串周围包裹一个标签 shop attributes td each function this html function i html return html replace E 0
  • 在 CKEditor 中设置字体大小和字体系列

    我正在使用 ckeditor 我想问一下这个插件如何设置font family和font size 我尝试过使用 CKEDITOR config font defaultLabel Arial CKEDITOR config fontSiz
  • Vue.js[vuex] 如何从突变中调度?

    我有一个要应用于 json 对象的过滤器列表 我的突变看起来像这样 const mutations setStars state payload state stars payload this dispatch filter setRev

随机推荐

  • 通过web页面查看HDFS文件系统

    一 背景 因为做hadoop的开发 所以有些时候需要通过web对hdfs文件系统进行查看 如果开发机器是Linux系统 那么只要更改 etc hosts文件就可以了 但是在Windows下 通过web页面查看 通常会报错 说是找不到域名 因
  • 特征选择-过滤式选择

    过滤式方法先按照某种规则对数据集进行特征选择 然后再训练学习器 特征选择过程与后续学习器无关 这相当于先用特征选择过程对初始特征进行 过滤 再用过滤后的特征来训练模型 某种规则 按照发散性或相关性对各个特征进行评分 设定阈值或者待选择阈值的
  • 数据密集、计算密集、IO密集,hadoop如何应对?

    I O bound I O密集型 I O bound 指的是系统的CPU效能相对硬盘 内存的效能要好很多 此时 系统运作 大部分的状况是 CPU 在等 I O 硬盘 内存 的读 写 此时 CPU Loading 不高 计算密集型 CPU b
  • 【AD错误】“Could not find board outline using primitives...“解决办法

    参考 https blog csdn net ReCclay article details 82960495 解决办法 主要是PCB上有的元件封装也有Keep out layer 的画线 CTRL A设定板子大小时会把里面的元件封装的画线
  • 数据治理-DAMA元数据模块总结

    最近在看DAMA元数据模块做了如下的总结 供大家参考学习 1 什么是元数据 元数据的定义是关于数据的数据 它不仅仅包括了技术和业务流程 数据规则和约束 还包括逻辑数据结构和物理数据结构等 它描述的是数据本身 2 元数据的作用 元数据对于数据
  • qt获取ftp服务器信息,qt获取ftp服务器目录

    qt获取ftp服务器目录 内容精选 换一换 Linux x86 64 64位 服务器 常见的有EulerOS Ubuntu Debian CentOS OpenSUSE等 Windows 7及以上版本 请参见JRE地址下载JRE Linux
  • Take Control

    Turn Off Notifications Remove Toxic Apps Remove apps that profit off of addiction distraction outrage polarization and m
  • 【HTML基础汇总】

    HTML 前期整体脉络 2017年1月7日 14 23 24 0 序 HTML 前期整体脉络 序 前言 总览 HTML 基础 1 HTML简介 11 什么是标记语言 2 HTML 基础结构 3 标签 31 什么是标签 32 块元素标签 32
  • 一起实战Springboot开发后端管理系统4:数据库连接池Druid和HikariCP

    上一篇文章主要讲解了如何再Matrix Web中使用Mybatis Plus Mybatis Plus作为Orm框架 连接数据库需要连接数据库的依赖 WEB 系统高并发环境下 频繁的进行数据库连接操作 造成系统技术瓶颈问题 无效的资源开销
  • 剑指offer第二版面试题5:替换空格(java)

    题目 请实现一个函数 把字符串中的每个空格替换成 20 例如输入 We are happy 则输出 We 20are 20happy 说明 在网络编程中 如果URL参数中含有特殊字符 如 空格 等 可能导致服务器端无法获得正确的参数值 我们
  • [OtterCTF 2018]之Misc篇(NSSCTF)刷题记录⑦

    NSSCTF Misc篇 OtterCTF 2018 OtterCTF 2018 General Info OtterCTF 2018 Play Time OtterCTF 2018 Silly Rick OtterCTF 2018 Wha
  • linux 查看端口被哪个进程占用

    linux 查看端口被哪个进程占用及对应程序安装地址 查询端口被哪个进程占用 查看进行号28998对应的物理地址 杀掉1827号进程 查询端口被哪个进程占用 查看9995端口被哪个进程占用 lsof i tcp 9995 查看进行号2899
  • Mac系统下android studio无法识别手机

    1 设置 辅助功能 开发人员工具 勾选 USB调试 允许模拟位置 这两项 2 将手机连接电脑 选择连接方式 媒体设备 MTP 3 打开mac电脑的 关于本机 系统报告 系统信息硬件中找到USB USB设备中找到连接的手机 在下面栏中找到 厂
  • db2 xml 转 table【XQuery系列】

    版本 DB2 Version 9 1 1 创建测试表 初始化数据 create table emp doc XML INSERT INTO EMP VALUES
  • 机考[71-80]

    华为机考 071 整数编码 072 整数对最小和 073 整型数组按个位值排序 074 执行时长 075 字符串变换最小字符串 076 字符串分割 077 字符串加密 078 字符串筛选排序 079 字符串统计 080 字符串序列判定 07
  • docker命令学习

    docker运行mysql并允许外网访问 docker run p 3306 3306 name mysql e MYSQL ROOT PASSWORD 123456 d docker io mysql latest p 外网映射 e设置m
  • 13. Jupyter Notebook介绍、安装及使用

    一 什么是Jupyter Notebook 1 简介 Jupyter Notebook是基于网页的用于交互计算的应用程序 其可被应用于全过程计算 开发 文档编写 运行代码和展示结果 Jupyter Notebook官方介绍 简而言之 Jup
  • 《电子相框》--2.fb设备与图片显示

    接着上一篇博客的总结 继续项目的技术点展示 一 fb设备显示图片基础的步骤 1 确定打开的设备 一般设备在 dev fbxx 2 两个与显示有关的结构体变量 struct fb fix screeninfo finfo struct fb
  • ajax加密url参数,JS加解密URL参数encodeURIComponent() decodeURIComponent()

    参考1 http www w3school com cn js jsref encodeURIComponent asp 参考2 http www w3school com cn js jsref decodeURIComponent as
  • JS原型详解

    原型 原型是 JavaScript 面向对象特性中重要的概念 也是大家太熟悉的概念 因为在绝大多 数的面向对象语言中 对象是基于类的 例如 Java 和 C 对象是类实例化的结果 而在 JavaScript 语言中 没有类的概念 对象由对象