发出咝咝声

Sizzle push apply

本文关键字:      更新时间:2023-09-26

为什么Sizzle选择引擎使用push.apply( results.... )而不是results.push(...),这对我来说似乎是不必要的。有人能解释一下动机吗?

详细说明一下,我已经开始对编写/借用sizzle的一些内容感兴趣,以实现更轻量级的选择器引擎。我想我不需要像:contains(text)这样的东西,这将进一步减轻重量。所以在阅读源码时,我看到

var arr = [],
    push = arr.push
    results = results || [];
 ....
 push.apply( results, context.getElementsByTagName( selector ) );

代码是有意义的,除了使用

不是更简单吗?
results.push( context.getElementsByTagName( selector ) );

我不想为这样一个小约定而烦恼,我只是想知道我是否错过了诸如上下文问题之类的东西。

而不是:

results.concat(array)

因为concat创建了一个额外的数组,但push.apply不会:

push.apply(results, array)

缓存results数组,不创建额外的数组。

但是你也可以这样做:

results.push.apply(results, array)

我不确定为什么需要arr

编辑:

我认为需要额外的arr可能是转换伪数组,getElementsByTagName返回到一个真正的数组。

再次查看代码(在休息之后)。在第205行左右,Sizzle检查选择器模式是否为ID,并使用results.push

elem = context.getElementById( m );
results.push( elem );
return results;

第237行起用于元素或类,并使用getElementsByTagNamegetElementsByClassName以及push.apply( results, ... )

我猜这是

的简写版本
for( elem in context.getElementsByClassName( m ) ) {
    results.push( elem );
}

与Mozzila docs的例子一样https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

// short hand
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);
/* vs. simple loop based algorithm */
max = -Infinity, min = +Infinity;
for (var i = 0; i < numbers.length; i++) {
  if (numbers[i] > max)
    max = numbers[i];
  if (numbers[i] < min) 
    min = numbers[i];
}

编辑:

从我最初的问题results.push( context.getElementsByTagName( selector ) );将导致一个不需要的对象。这将NodeList类型的一个参数推入结果。

的例子:

var a = [1, 2, 3], b = [], c =[];
b.push( a ); // b.length = 1, now we have a multidimensional array
[].push.apply( c, a ); // c.length = 3, we now have a clean array, not a NodeList

相关文章:
  • 没有找到相关文章