merge
您正在查看的函数是一个公共 jQuery 方法:jQuery.merge()
或$.merge()
. 因此,您可能认为阅读文档会对这个问题有所了解。jQuery.merge()
不幸的是,至少在撰写本文时并非如此。
正如其他答案和评论中所解释的,当是 an时,这个对数字length
属性的测试总是会成功,因为 an总是有一个 numeric 。在代码中进行此测试的唯一可能原因是处理is not an的情况。second
Array
Array
length
second
Array
但是文档根本没有提到这种情况。它只讨论两者first
都是second
原生 JavaScriptArray
对象,而不是“类数组”对象的情况。
如果这个记录的用法就是这个函数所做的一切,那将是毫无用处的,因为 JavaScript 提供了一个非常好的本机array.concat(array)
方法,可以用来代替jQuery.merge()
.
所以看起来这个函数的真正目的必须是在它的无证使用中。让我们在jQuery.merge() 文档页面的 Chrome 控制台中尝试一下。打开开发者工具,选择 Console 选项卡,然后输入一个类似于文档中的示例:
jQuery.merge( [ 'a', 'b' ], [ 'c', 'd' ] )
然后尝试同样的事情.concat()
:
[ 'a', 'b' ].concat([ 'c', 'd' ])
他们都将记录完全相同的内容:
["a", "b", "c", "d"]
由于这是 jQuery,因此“类数组”对象的最可能情况是 jQuery 对象。例如,该文档页面当前包含三个<h3>
元素,因此我们可以通过以下方式获取它们:
$('h3')
这将记录:
[►<h3>…</h3>, ►<h3>…</h3>, ►<h3>…</h3>]
这不是一个数组,但它看起来很像一个数组,而且它确实有一个数字length
属性,我们可以用它来检查:
typeof $('h3').length
所以让我们尝试一下concat
:
['x'].concat( $('h3') )
哎呀。这应该给我们一个包含四个元素的数组,'x' 后跟三个 DOM 元素。相反,我给了我们一个包含两个元素的数组,jQuery 对象作为第二个元素:
[►e.fn.init[3] ]
看起来 jQuery 的“类数组”对象对于.concat()
.
奇怪的是,其他一些数组方法可以处理 jQuery 的类数组对象,例如.slice()
:
Array.prototype.slice.call( $('h3'), 1 )
这记录了正确的结果,一个包含两个元素的数组:
[►<h3>…</h3>, ►<h3>…</h3>]
所以让我们试试$.merge()
:
$.merge( ['x'], $('h3') )
果然,这记录了我们的预期:
["x", ►<h3>…</h3>, ►<h3>…</h3>, ►<h3>…</h3>]
还有另一种方法可以做到这一点。jQuery 提供了一个.toArray()
方法,所以我们可以通过将它与 结合来做同样的事情.concat()
:
['x'].concat( $('h3').toArray() )
这记录了与通话相同的内容$.merge()
。
如果first
是一个 jQuery 对象呢?
$.merge( $('h1'), $('h3') )
这也有效:
[<h1 class="entry-title">jQuery.merge()</h1>,
►<h3>…</h3>, ►<h3>…</h3>, ►<h3>…</h3>]
所以看起来这就是这个方法的目的:array.concat()
对 jQuery 对象做类似的操作。
可是等等!这仍然没有回答为什么非数字的额外代码在那里的问题.length
。毕竟,一个 jQuery 对象确实有一个 numeric .length
,所以我们还没有练习非数字情况的代码。
因此,这部分代码必须用于处理 jQuery 对象以外的其他目的。那会是什么?
我们可以通过访问jQuery 源存储库src
并在包含代码的目录中找到文件merge:
(它恰好是core.js
)来了解更多信息。然后使用Blame按钮并在页面中搜索merge:
代码以查看代码的提交注释是什么。同样,我们现在想知道的代码是else
子句,其中typeof l
不是数字。
该提交由John Resig于 2009 年 12 月 9 日提交,并附有评论“Rewrote merge()(现在更快、更不钝)。已修复 #5610。” 该页面上的讨论存在一些争议:
好吧,您的版本仅在覆盖长度属性的特殊(非常罕见)情况下更快。在所有其他情况下,我的速度都快一点。此外,您没有考虑 obj.length = new Number(N) 的情况 - 但是我想它并不那么相关。
这有助于稍微解释一下,但问题 #5610 是什么?也许这会告诉我们。在 GitHub 存储库上看不到问题跟踪器?jQuery 有自己的问题跟踪器,如果我们在那里搜索#5610
(或在 Google 上搜索)jquery issue 5610
,我们最终会找到问题 #5610:
MAKEARRAY 可能导致浏览器在具有长度属性的非数组对象上崩溃
描述
我还没有用 1.4 测试过这个
对于具有转换为非零正整数的长度属性的对象,makeArray 将创建一个长度为未定义的数组。
>>> jQuery.makeArray({'length': '5'})
[undefined, undefined, undefined, undefined, undefined]
如果长度属性为零、负数或小数,则 Firefox 和 Safari 都会挂起。(FF 显示无响应的脚本错误,Safari 挂起直到崩溃)
>>> jQuery.makeArray({'length': '0'})
>>> jQuery.makeArray({'length': '5.2'})
>>> jQuery.makeArray({'length': '-3'})