Javascript继承:父级的数组变量保留值

2024-02-20

我在这里尝试在 JavaScript 中使用继承,但发现数组值存在问题Parent由 a 继承的类Child班级。下面的代码是正常的继承:

var Parent = function() {
    this.list = [];
};

var Child = function() {};

Child.prototype = new Parent;
Child.prototype.constructor = Child;

var obj1 = new Child;

obj1.list.push("hello");

console.log(obj1.list); // prints ["hello"];

当我初始化新的Child对象(继承Parent,其中包含名为的数组变量list) to obj1并试图推动obj1.列表值为“你好”,obj1.列表打印 [“hello”] ..到目前为止一切顺利。

当我执行上面的示例并尝试初始化新的时,问题就出现了Child反对obj2然后推obj2's list值为“再见”,并且obj2.列表现在打印[“你好”,“再见”]。 (见下面的代码:)

var obj2 = new Child;

obj2.list.push("goodbye");

console.log(obj2.list); // prints ["hello", "goodbye"];

我在这里可能有一个误解,但是list数组中Parent以某种方式保留了价值,我不知道为什么。

这是一个大麻烦,因为如果我重复使用Parent类到许多其他子类,如上面的情况,如果Parent将数组变量共享给其子类,该值也将共享给其他子类,这对我来说是意想不到的。

我所期望的是,Child类代表新对象,同样适用于Parent上课时Child类被初始化为obj1,然后当我初始化新的Child反对obj2,推入的值来自obj1不应该与共享obj2.

- 问题 -

谁能帮我找出为什么list(数组变量Parent)在上面的示例中保留值/共享由子对象启动的值(在上面的情况下,obj1 and obj2)?

如果您有另一个可以解决此问题的解决方案,那将非常好,但我很乐意先找出上述问题。


当子对象具有从其原型对象继承的属性时,真正发生的是子对象具有参考到包含属性的原型。孩子没有自己的副本。所以两个孩子都使用同一个数组——(一)上的一个Parent您分配给的原型对象Child.prototype.

首先是一些图片,然后是更多文字。 :-)

new Parent()给你这个:


+-----------------+
| Parent instance |
+-----------------+
| list = []       |
+-----------------+  

...然后您分配给Child.prototype.

Then, new Child()给你这个:


+------------------+
| Child instance 1 |
+------------------+        +-----------------+
| (prototype)      |------->| Parent instance |
+------------------+        +-----------------+
                            | list = []       |
                            +-----------------+  

Doing new Child()再次给你另一个:



+------------------+      +------------------+
| Child instance 1 |      | Child instance 2 |
+------------------+      +------------------+
| (prototype)      |---+  | (prototype)      |---+
+------------------+   |  +------------------+   |
                       |                         |
                       |                         |     +-----------------+
                       +-------------------------+---->| Parent instance |
                                                       +-----------------+
                                                       | list = []       |
                                                       +-----------------+  

正如您所看到的,所有Child实例是sharing相同Parent实例(他们的原型),上面有一个数组。

当你说:

var obj = new Child();
obj.list.push("foo");

...这是 JavaScript 引擎在看到信息时会执行的操作obj.list:

  1. 看看有没有obj有它的own属性称为list。如果没有,那么:
  2. 看看有没有obj的原型有其own属性称为list。如果没有,那么:
  3. 看看有没有obj的原型 的原型有其own属性称为list.
  4. 等等,直到我们用完原型。

就你而言,自从obj没有它的own list属性,引擎着眼于它的原型(Parent您分配给的实例Child.prototype),在本例中确实具有该属性。所以就用了那个。它不会复制给孩子或任何东西,它是used。当然,由于它是一个数组,因此将某些内容推送到数组上实际上是将其推送到数组上。

如果你要assign某事obj.list, then obj会得到它的own list财产,打破链条。所以说this.list = []; in Child会给每个孩子自己的清单。

每当原型有一个时你就会看到这一点对象引用其上,对象是可以修改的类型(“可变”对象)。数组、日期、普通对象 ({})、正则表达式等,它们都有状态并且都可以修改,所以您会看到它们。 (String实例是不可变的,因此尽管发生了同样的事情,但您看不到任何效果,因为字符串无法更改。)

对于原语,虽然你继承了它们,但你不能改变它们的状态(你只能replace它们具有不同状态的新原语),因此您不会看到相同的效果。因此,如果obj继承财产foo从它的原型来看,foo is 42, alert(obj.foo)将从原型中获取值并显示“42”。改变的唯一方法foo就是说obj.foo = 67或类似的——这给出了obj its own备份foo,与原型的副本不同。 (即使您使用类似的东西也是如此++ and --, e.g. ++obj.foo;这确实被评估为obj.foo = obj.foo + 1).

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

Javascript继承:父级的数组变量保留值 的相关文章

  • PHP:我是否将事件驱动编程与信号感知接口(信号和槽/观察者模式)混淆了?

    我看到很多人说 Symfony2 Zend Framework 2 等都是事件驱动的 在桌面世界中 通过事件驱动编程 我了解到应用程序每当其状态发生变化时都会通知其观察者 由于 PHP 应用程序是无状态的 因此无法执行此类操作 IE 让观察
  • Jquery文件上传插件进度条

    这个插件 https github com blueimp jQuery File Upload wiki管理网页中的文件上传 并且可以在上传过程中添加很多 UI 元素 您创建一个输入文件类型元素 然后绑定 js 文件 使用实例化代码和 w
  • 有没有办法将 Google 文档分割成多个 PDF?

    我想在 Google Scripts VBA 代码中复制我为 Word 文档编写的代码 基本上 它通过搜索我插入文档中的标签 将文档 切片 为多个 PDF 文件 目的是允许合唱团使用 forScore 管理乐谱的应用程序 在切片点插入先前注
  • 我可以用一个简单的函数制作一个迭代器吗? (没有生成器或 Symbol.iterator)

    我一直在尝试使用普通函数创建一个迭代器 而不使用生成器或使用Symbol iterator用于学术目的的协议 为此 我创建了一个函数 它返回一个带有next参数 但尝试将其作为iterable的论证for of循环会产生不需要的结果 这是到
  • Javascript 制作音频 blob

    我正在测试 html 音频标签 我想制作音频 blob url 就像 youtube 或 vimeo 那样 并将其添加到 src 开始播放音频 我一直在测试new Blob and URL createObjectURL 但我不知道如何使用
  • 光标:IE 8 和 9 中的自动行为

    我想要的是为整个正文标记指定cursor pointer 这样页面的背景是可点击的 但我也希望页面的其余部分像以前一样工作 所以我尝试为div设置cursor auto 其中包含这一页 在 FF Chrome 和 safari 中 它工作得
  • 在each() 和forEach() 中使用break 和 continue

    如果我们不能使用 break 和 continue 关键字 我不确定我是否理解函数式循环 映射的价值 我可以做这个 collections users models forEach function item index can t use
  • Chrome 跨域 PATCH 请求不起作用

    我有一个带有 REST Api 的网站 现在我正在创建一个浏览器扩展 它将从某些页面收集数据并将它们发送回 REST Api 因为我希望我的扩展能够与 Firefox 和 Chrome 兼容 并且易于维护 所以我将实际代码作为脚本标记注入到
  • 在Javascript中将RGB数组转换为RGBA数组的快速方法

    我正在使用的模拟器在内部存储 RGB 值的一维帧缓冲区 但是 HTML5 画布在调用 putImageData 时使用 RGBA 值 为了显示帧缓冲区 我当前循环遍历 RGB 数组并以某种方式创建一个新的 RGBA 数组与此类似 https
  • 处理时区转换的 JavaScript 库

    是否有一个 JavaScript 库可以处理时区转换 并考虑 DST 规则和此类内容 我知道有类似的问题 但我见过的问题似乎都没有真正适合我的问题的答案 我想在时区 A 创建一个日期并能够对其进行操作 添加天数 小时等 然后将其转换为另一个
  • Webpack - 资产大小限制中的警告:以下资产超出了建议的大小限制 (244 KiB)

    当我在生产模式下运行 webpack 时 有资产规模限制 超出 的警告 我怎样才能运行而不出现这个错误 在我的项目中 我包含 css 并且我看到 webpack 构建中包含一些 node module 目录 但是如果我排除 css 的 no
  • 如何将OpenLayers多边形坐标转换为纬度和经度?

    我正在使用开放层 https openlayers org en latest examples draw freehand html绘制多边形并保存坐标的技术 这是我的代码 var raster new ol layer Tile sou
  • 如何获取 Spotify API 的访问令牌?

    我已经研究 Spotify api 和示例源代码几天了 但我仍然不知道如何获取访问令牌来访问用户的播放列表数据 我已经到达了拉起登录窗口 用户登录 然后收到授权码的地步 此时 我尝试做这样的事情 window open https acco
  • 如何处理 setTimeout() 的多个实例?

    阻止创建 setTimeout 函数的多个实例 在 JavaScript 中 的最推荐 最佳方法是什么 一个例子 伪代码 function mouseClick moveDiv div 0001 mouseX mouseY function
  • Ajax 函数在重定向后不保存滚动位置

    正如标题所述 我编写了一个 ajax 函数 该函数应该滚动到用户在重定向之前所在的位置 我写了一个alert对于测试场景 它确实触发了 但滚动不断回到顶部 我在这里做错了什么 JavaScript ajax type GET url Adm
  • Kendo 刷新 (DropDownList.refresh()) 不起作用错误未定义

    我试图在另一个 DropDownList 更改后刷新下拉列表 但 Refresh 方法未定义错误正在升级 我尝试再次读取数据源 它显示它正在加载 但数据仍然相同 帮助解决这个问题请 Code DropDownList1 change fun
  • javascript 闭包和对象引用

    我的情况有点晦涩难懂 主要是因为我认为我已经掌握了闭包 所以基本上我想要的是将集合重置为默认值 假设我有一个集合 它具有带有对象参数数组的构造函数 var c new collection x y z 然后集合定期更新 因为我没有保留数组的
  • “memset”没有 DLL 那么如何 ctype 它

    如何使用memset在 jsc 类型中 没有对应的 DLL 我搜索 搜索了 js ctype 代码 但找不到要破解的示例 如果你只是想memset一个数组为零字节 然后我有 好消息 大家 js ctypes 会将新数组初始化为零 否则 最简
  • 使用 javascript 从亚马逊 URL 中抓取 ASIN

    假设我有一个像这样的亚马逊产品 URL http www amazon com Kindle Wireless Reading Display Generation dp B0015T963C ref amb link 86123711 2
  • 文件和目录条目 API 在 Chrome 中损坏?

    我正在尝试使用文件和目录条目 API 创建一个文件上传器工具 该工具允许我将文件和目录的任意组合放入浏览器窗口中 以供读取和上传 我完全意识到 可以通过使用文件输入元素来实现类似的功能webkitdirectory已启用 但我正在测试一个用

随机推荐