草庐IT

javascript - 对于 JavaScript 多维数组的深拷贝,深入一层似乎就足够了。这是真的吗?

coder 2025-03-16 原文

注意:我只是一个编码新手,所以这个问题的核心可能存在明显的错误或误解。

本质上,我需要在 JavaScript 中“按值”深度复制多维数组到未知深度。我原以为这需要一些复杂的递归,但似乎在 JavaScript 中您只需要深复制一个级别就可以按值复制整个数组。

举个例子,这是我的测试代码,使用了一个故意复杂的数组。

function test() {
  var arr = [ ['ok1'],[],[ [],[],[ [], [ [ ['ok2'], [] ] ] ] ] ];
  var cloned = cloneArray(arr);
  arr = '';   // Delete the original
  alert ( cloned );
}


function cloneArray(arr) {  
  // Deep copy arrays. Going one level deep seems to be enough.
  var clone = [];
  for (i=0; i<arr.length; i++) {
    clone.push( arr[i].slice(0) )
  }
  return clone;
}

在我运行这个测试(Ubuntu 上最新的稳定版 Chrome 和 Firefox)时,即使是数组的最深部分似乎也被克隆中的值成功复制了,即使在原始文件被删除之后,尽管切片() “复制”只深入了一层。这是 JavaScript 中的标准行为吗?我可以依靠它来为旧版浏览器工作吗?

最佳答案

您的测试在是否制作真实副本方面存在缺陷,这使得您得出的结论是错误的,即您正在获取嵌套数组中所有数据的完整副本。您只是在进行两级复制,而不是 N 级复制。

Javascript 是一种垃圾回收语言,因此您实际上并没有删除变量或对象,即使您尝试这样做也不会影响在代码中其他地方引用的同一个变量。要查看您是否真的拥有一个完全独立的副本,请尝试将一个对象嵌套两层深,然后更改原始数组中该对象的属性。你会发现同一个对象在克隆的数组中发生了变化,因为你没有进行深度克隆。两个数组都引用了完全相同的对象。

这是 an example .

function cloneArray(arr) {  
  // Deep copy arrays. Going one level deep seems to be enough.
  var clone = [];
  for (i=0; i<arr.length; i++) {
    clone.push( arr[i].slice(0) )
  }
  return clone;
}

var x = [[{foo: 1}]];

var y = cloneArray(x);
x[0][0].foo = 2;

// now see what the value is in `y`
// if it's 2, then it's been changed and is not a true copy
// both arrays have a reference to the same object
console.log(y[0][0].foo);    // logs 2

如果第三层也是另一个数组,也会出现同样的结果。 您将必须递归遍历每个对象类型的元素,然后克隆该对象本身以获得嵌套数组中所有内容的完整克隆。

如果您想要执行深度复制(到任意级别)并适用于所有数据类型的代码,请参阅 here .

仅供引用,您的 cloneArray() 函数假定数组的所有第一级成员本身都是数组,因此如果它包含任何其他类型的值则不起作用。

关于javascript - 对于 JavaScript 多维数组的深拷贝,深入一层似乎就足够了。这是真的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25100714/

有关javascript - 对于 JavaScript 多维数组的深拷贝,深入一层似乎就足够了。这是真的吗?的更多相关文章

  1. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  2. ruby - 如何在 Ruby 中获取多维哈希中的键? - 2

    因此,对于普通哈希,您可以使用它来获取key:hash.keys如何获取如下所示的多维哈希的第二维键:{""=>{"first_name"=>"test","last_name"=>"test_l","username"=>"test_user","title"=>"SalesManager","office"=>"test","email"=>"test@test.com"}}每个项目都是唯一的。所以我想从上面得到的键是:first_name,last_name,username,title,officeandemail 最佳答案

  3. ruby - 在 Ruby 中动态生成多维数组 - 2

    我正在尝试动态构建一个多维数组。我想要的基本上是这样的(为简单起见写出来):b=0test=[[]]test[b]这给了我错误:NoMethodError:undefinedmethod`test=[[],[],[]]而且它工作正常,但在我的实际使用中,我不会事先知道需要多少个数组。有一个更好的方法吗?谢谢 最佳答案 不需要像您正在使用的索引变量。只需将每个数组附加到您的test数组:irb>test=[]=>[]irb>test[["a","b","c"]]irb>test[["a","b","c"],["d","e","f"]]

  4. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  5. ruby - 如何在ruby中制作动态多维数组? - 2

    我有一个关于多维数组的初学者ruby​​问题。我想按年份和月份对条目进行排序。所以我想创建一个包含年->月->月条目的多维数组所以数组应该是这样的:2009->08->Entry1->Entry209->Entry32007->10->Entry5现在我有:@years=[]@entries.eachdo|entry|timeobj=Time.parse(entry.created_at.to_s)year=timeobj.strftime("%Y").to_imonth=timeobj.strftime("%m").to_itmparr=[]tmparrentry}@years.pu

  6. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  7. ruby-on-rails - 我将 Rails3 与 tinymce 一起使用。如何呈现用户关闭浏览器javascript然后输入xss? - 2

    我有一个用Rails3编写的站点。我的帖子模型有一个名为“内容”的文本列。在帖子面板中,html表单使用tinymce将“content”列设置为textarea字段。在首页,因为使用了tinymce,post.html.erb的代码需要用这样的原始方法来实现。.好的,现在如果我关闭浏览器javascript,这个文本区域可以在没有tinymce的情况下输入,也许用户会输入任何xss,比如alert('xss');.我的前台会显示那个警告框。我尝试sanitize(@post.content)在posts_controller中,但sanitize方法将相互过滤tinymce样式。例如

  8. ruby-on-rails - 对于 Ruby 应用程序,是否有比 Sanitize 更好的替代方案? - 2

    我爱Sanitize.这是一个了不起的实用程序。我遇到的唯一问题是,它需要永远准备一个开发环境,因为它使用Nokogiri,这对编译时间来说是一种痛苦。是否有任何程序可以在不使用Nokogiri的情况下执行Sanitize的操作(如果没有别的,只是温和地执行它的操作)?这将以指数方式提供帮助! 最佳答案 Rails有自己的SanitizeHelper。根据http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html,它将Thissanitizehe

  9. ruby - 使用 Selenium WebDriver 启用/禁用 javascript - 2

    出于某种原因,我必须为Firefox禁用javascript(手动,我们按照提到的步骤执行http://support.mozilla.org/en-US/kb/javascript-settings-for-interactive-web-pages#w_enabling-and-disabling-javascript)。使用Ruby的SeleniumWebDriver如何实现这一点? 最佳答案 是的,这是可能的。而是另一种方式。您首先需要查看链接Selenium::WebDriver::Firefox::Profile#[]=

  10. ruby-on-rails - 对于诸如libyaml之类的已编译库,Ruby(或RVM)在文件系统中搜索哪些位置以加载或解析它们? - 2

    操作系统:CentOS6.2x86_64很抱歉缩进太古怪了。这是我的第一篇SO帖子,我是新来设置服务器的。不过,我正在学习,并将详细说明我尝试解决此问题所采取的步骤以及寻求帮助的地方。我是一位有抱负的年轻Web开发人员,并且我在其他人配置的服务器上工作,因此,这对我来说是全新的。我正在准备我最近购买的用于运行Rails应用程序的linode。我遵循了此处http://blog.blenderbox.com/2011/01/07/installing-rvm-ruby-rails-passenger-nginx-on-centos/提供的初始安装指南,并更改了步骤:sudobash反射(

随机推荐