草庐IT

javascript - 我可以创建一个 Array.isArray() 返回 true 的对象而不使用 Array 构造函数或数组文字吗?

coder 2025-03-13 原文

通过将其原型(prototype)设置为 Array.prototype,我可以轻松地使一个普通对象看起来像一个数组:

const obj = {};
Reflect.setPrototypeOf(obj, Array.prototype);

(我知道神奇的 length 属性和稀疏数组也存在一些问题,但这不是这个问题的重点。)

我想让 Array.isArray(obj) 返回 true(当然不修改 Array.isArray() 方法)。 MDN polyfill for Array.isArray()如下:

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}

通过使用 Symbol.toStringTag我可以使 Object.prototype.toString.call(obj) 返回 '[object Array]' 的属性:

obj[Symbol.toStringTag] = 'Array';
console.log(Object.prototype.toString.call(obj) === '[object Array]'); // true

现在 polyfilled Array.isArray()obj 返回 true(请忽略没有浏览器不这样做的事实支持 Array.isArray() 确实支持 Symbol.toStringTag)。但是, native Array.isArray() 函数仍然为 obj 返回 false。我查看了 ECMAScript 2017 规范,它说 Array.isArray()使用抽象操作 IsArray ,如果参数是 Array 奇异对象,则返回 true。如果参数是 Proxy,它会直接在目标对象上调用 IsArray,因此似乎使用 Proxy 在这里没有帮助。

有没有办法让Array.isArray(obj)返回true?明确地说,我不想修改 Array.isArray() 或任何其他内置对象。

这基本上与 Can you fake out Array.isArray() with a user-defined object? 相同的问题, 但它是 5 年前问的,答案是基于 ECMAScript 5 规范。我正在寻找基于 ECMAScript 2017 规范的答案。

最佳答案

不,正如您已经说过的那样,一个真正的数组(这是 Array.isArray 检测到的)是一个数组奇异对象,这意味着它的 .length 以一种特殊的方式表现。

构造的唯一方法是使用数组构造函数或 Array 的子类(依次调用数组构造函数)或来自另一个领域的相同方法。还有无数其他方法返回新数组(例如 String::splitString::matchArray.fromArray.of , Array 原型(prototype)方法, Object.keys, Object.getOwnPropertyNames).
此外,用于标记模板或代理应用/构造​​陷阱的函数将接收全新的数组,并且数组也被构造为 Promise.all.entries( ) 迭代器。

如果您正在寻找创建数组的语法方法,数组文字将是您的首选,但解构表达式(在数组文字或函数中)也可以从迭代器创建数组。

如果您的实际问题是“我可以将任意对象变成数组奇异对象吗?”,答案是肯定的

关于javascript - 我可以创建一个 Array.isArray() 返回 true 的对象而不使用 Array 构造函数或数组文字吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41170131/

有关javascript - 我可以创建一个 Array.isArray() 返回 true 的对象而不使用 Array 构造函数或数组文字吗?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  3. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  4. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  5. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  6. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  7. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

  8. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  9. Ruby Koans about_array_assignment - 非平行与平行分配歧视 - 2

    通过ruby​​koans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John

  10. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

随机推荐