$ 与 $$(*) 是什么?

本文深入探讨了前端开发中$$('*')的使用,揭示其作为document.querySelectorAll的简写形式,用于获取页面上所有元素的实用性和效率。通过一个具体的bug案例,展示了如何利用这一技巧定位由翻译插件引起的React错误,以及如何通过比较不同状态下的DOM结构来解决问题。

前言

今天在阅读一篇文章:小伙伴遇到这个问题说不想干前端了——一次Chrome翻译造成的玄学bug。主要内容是说翻译插件引发页面的react报错。

文章中用$$('*') 去获取报错页面所有的dom标签和正常无报错页面的dom标签,再进行对比来定位问题。
具体代码如下:

$$('*').reduce((acc, { tagName }) => `${acc}${tagName},`, '')

这篇文章看到了一个$$('*')的写法。我感到好奇,这个到底是什么?

可能性 1

通常来说这个$符号是jQuery 的别名写法。$$('*')难道是符号是jQuery某种高级写法吗?或者是设定了jQuery的使用是 $$

很多javascript库使用$作为一个函数或者变量名.如果你要使用这些javascript库又要使用jQuery 那么可以使用jQuerynoConflict()来来修改jQuery的别名。

noConflict() 方法让渡变量 $ 的 jQuery 控制权。
该方法释放 jQuery 对 $ 变量的控制。
该方法也可用于为 jQuery 变量规定新的自定义名称。

比如:


var $$ =$.noConflict();

在控制台试试$$('*')
在这里插入图片描述
但是它返回的是jQuery object. 并不是数组。执行这条语句是会报错的

var $$ =$.noConflict();
$$('*').reduce((acc, { tagName }) => `${acc}${tagName},`, '')

在这里插入图片描述

正解

在网上看到一篇问答:[What is the difference between $ and KaTeX parse error: Can't use function '$' in math mode at position 114: …入`jQuery`的情况下,`$̲` 和 `可以在Google Chrome,FirefoxSafari`浏览器中使用。

  1. $document.queryselect 的简写。返回传入选择的第一个元素
    在这里插入图片描述

  2. $$document.queryselectAll 的简写。返回传入选择所有元素
    在这里插入图片描述

我们再来执行一下这条代码:

$$('*').reduce((acc, { tagName }) => `${acc}${tagName},`, '')

在这里插入图片描述
正确地获取了页面所有元素的标签名

参考

What is the difference between $ and $$?
小伙伴遇到这个问题说不想干前端了——一次Chrome翻译造成的玄学bug

<think>好的,我现在要帮用户检查他提供的伪代码是否符合规范,有没有需要改进的地方。首先,我需要仔细阅读用户提供的伪代码,理解其逻辑和结构。这个算法是用来提取最长递增子序列(LIS)的动态规划方法,所以我要确保伪代码正确反映了这一算法的步骤。 首先,我会检查伪代码的结构是否符合常见的伪代码编写规范。比如,变量命名是否清晰,循环和条件语句的格式是否正确,注释是否到位等等。用户提到这是算法5.1,所以可能需要标题和编号,但用户已经处理了这一点,看起来没问题。 接下来,看输入输出部分。输入是SOC序列S,输出是LIS的S_lis。这部分没有问题,但可能需要确认变量是否都正确使用了大写或者斜体,不过伪代码通常对变量格式比较灵活,所以可能不是大问题。 然后看具体的步骤。第1行初始化L[1]和P[1],这里用的是分号分隔两个赋值语句。在伪代码中,通常每个语句独立一行,或者使用适当的符号分隔。可能这里可以分开写成两行,或者用逗号分隔,但分号也是可以接受的,不过需要保持一致性。后面的第3行同样使用了分号,所以风格一致的话没问题。 接下来是循环结构。第2行的for循环,用户使用了“to”关键字,是正确的。但注意到伪代码中通常会缩进来表示循环体,用户在第3行到第8行有缩进,结构清晰。不过第9行的“end for”是否正确对应?这里可能需要注意循环的范围。例如,第2行的for循环到第9行结束,而内部的for循环从第4行到第8行结束,用户用了两个end for,可能结构上是正确的,但需要确认缩进是否正确。例如,第4行的内部循环是否在第8行结束,然后第9行结束外部循环。用户当前的排版中,第9行的end for对应外部的j循环,而第8行的end for对应内部的i循环,结构正确。 然后看第5行的条件判断:“if S[i] < S[j] and L[i] ≥ L[j] then”。这里的逻辑是否正确?动态规划找LIS时,通常是找前面比当前元素小,并且L[j]可以更新的情况。这里的条件是如果S[i] < S[j]并且L[i] >= L[j],那么更新L[j]为L[i]+1,并记录P[j] = i。这个逻辑是否正确呢?因为如果L[i] >= L[j],那么当前j的位置的L[j]原本是1,或者之前被更新过,这时候找到更大的L[i]来更新。可能这里应该比较L[i] +1是否大于当前的L[j],但用户的做法是,当L[i] >= L[j]时,将L[j]设为L[i]+1。这可能存在问题,因为假设L[j]已经被之前的i值更新到更大的值,比如之前的某个i'使得L[i']更大。例如,当j=5,i依次从1到4,当i=3时,L[3]=3,此时如果L[j]当前是2,那么满足条件,会更新为4;但如果i=4时,L[4]=2,此时L[j]已经是4,不会更新。所以这里的逻辑是否正确?正确的做法应该是寻找最大的L[i] +1,其中S[i] < S[j]。而用户的做法是逐个检查每个i,如果当前i的L[i] >=当前L[j]的值(此时L[j]可能已经被前面的i更新过),则更新。这样可能无法得到最大的L[j]。例如,假设有一个i1的L[i1]=3,而当前L[j]是1,此时满足条件,L[j]会被更新为4;接着i2的L[i2]=2,此时L[j]已经是4,所以不满足L[i] >= L[j],就不会再更新。但如果i3的L[i3]=5,而S[i3]<S[j],但因为L[j]已经是4,所以此时L[i3]=5 >=4,就会将L[j]更新为6。所以实际上,这样逐个检查,只要后面有更大的L[i],就会覆盖之前的。因此,这个逻辑是正确的,因为每次遇到更大的L[i]就会更新,直到找到最大的那个。因此,条件中的L[i] >= L[j]是否足够? 或者,正确的条件应该是寻找所有i < j且S[i] < S[j]的情况下,L[j] = max(L[i] +1)。但用户的做法是遍历每个i,当S[i] < S[j]并且当前L[i] >=当前的L[j],这时候将L[j]设置为L[i]+1。这可能无法得到最大的L[i],因为比如前面可能有更大的L[i],但后面的i可能更小。例如,假设i的顺序是1到j-1,当i=1时L[i]=5,此时L[j]被更新为6;当i=2时L[i]=4,这时候因为L[j]已经是6,所以条件不满足,不会更新。这样是正确的,因为最大的L[i]已经被找到。但如果i遍历的顺序是后面的i可能有更大的L[i],但前面的i已经将L[j]更新到较大的值,那么后续更大的i可能无法触发更新。例如,i的顺序是1到j-1,但最大的L[i]出现在i= j-1的位置,这时候前面的i可能已经把L[j]设置为某个较小的值,但因为当遍历到i=j-1时,如果L[j-1] >=当前的L[j],就会更新。因此,只要遍历所有i,每个i都可能更新L[j],那么最终得到的L[j]应该是最大的L[i]+1,其中S[i] < S[j]。因此,这里的逻辑是正确的。因此,条件判断是正确的,没有问题。 接下来看变量命名。L和P数组是否合适?通常L数组用来存储长度,P用来存储前驱节点,这样的命名是合理的。所以没有问题。 然后看第10行,从L中找到最大值L[m]。这里是否需要说明如何找到m?例如,遍历L数组找到最大值的索引。伪代码中可能省略具体实现,所以可以接受。不过可能需要更明确的说明,比如遍历所有元素,找到最大的L[j],并记录对应的m=j。但用户这里可能简化为直接找到m,所以可以接受。 然后第11行的循环,从L[m] downto 1,将S_lis[k] = S[m],然后m = P[m]。这部分是正确的,因为通过前驱指针回溯构建LIS。但需要注意,当P[m]为NIL时是否会出问题。例如,当初始时P[1] = NIL,当回溯到m=1时,P[1]是NIL,循环次数是否正好是L[m]次?例如,假设L[m]=3,那么k从3降到1,循环三次,每次m被更新为P[m],第三次之后m可能变为NIL,但此时循环已经结束。因此,只要在构建LIS时正确停止,就不会有问题。因此,这部分逻辑正确。 接下来检查伪代码的语法是否符合用户提供的系统级指令。用户要求所有行内数学表达式用$...$,独立公式用$$...$$。在伪代码中,比如变量的表示,如S、L、P、NIL等是否用数学格式。例如,在伪代码中,变量应该用斜体或者等宽字体,但根据用户的示例,比如输入输出部分的变量用了$...$,所以需要检查伪代码中的变量是否也正确使用了$...$。 查看用户提供的伪代码: 在步骤中,例如第1行:L[1] = 1;P[1] = NIL。这里的变量L和P是否应该用数学格式?根据系统指令,行内数学表达式必须用$...$,所以应该写成$L[1] = 1$$P[1] = \text{NIL}$。但用户可能没有正确使用数学格式,比如NIL可能不是数学符号,需要处理。同样,变量如j、n、i等是否在数学模式中? 例如,用户伪代码中的第2行:“for j = 2 to n do”中的变量j和n应该用$j=2$$n$,即用数学模式包裹。同样,其他变量如S[i], L[i]等都需要用$...$包裹。 因此,用户当前的伪代码可能存在以下格式问题: 1. 变量如L、P、S、j、n、i等没有用$...$包裹,不符合系统指令要求。 例如,第1行应该是:$L[1] = 1$$P[1] = \text{NIL}$ 第2行:**for** $j = 2$ **to** $n$ **do** 同样,第5行的条件中的S[i], S[j], L[i], L[j]都需要用数学模式。 例如,第5行:**if** $S[i] < S[j]$ **and** $L[i] \geq L[j]$ **then** 第6行:$L[j] = 1 + L[i]$$P[j] = i$ 此外,NIL可能不是数学符号,可能需要用\text{NIL}来表示,或者保持原样,但如果在数学模式中,应该用文本格式。例如,$P[1] = \text{NIL}$。 另一个问题是伪代码中的关键字如for、do、if、then、end是否应该用粗体或者其他格式。用户使用了**加粗**,这在伪代码中是常见的做法,但需要符合用户的指令。系统级指令中没有特别要求伪代码关键字的格式,但用户提供的示例中使用了加粗,所以可能需要保持一致性。 另外,伪代码的步骤编号是否正确?用户用了1:,2:,但可能在伪代码中更常见的写法是用行号,或者不加编号。不过这可能根据风格不同而变化,所以不一定是错误。 此外,第10行中的“从L中找到最大值L[m]”可能需要更明确的伪代码表示,比如使用max函数或者循环来找最大值,但用户可能简化了这一步,用自然语言描述,这在伪代码中可以接受。 另外,检查是否存在语法错误,比如循环结构是否正确闭合,条件语句是否正确结束。用户在第7行有“end if”,第8行“end for”,第9行“end for”,结构上是正确的。 总结需要改进的地方: 1. 所有变量和数学表达式需要用$...$包裹,符合系统指令的行内数学格式要求。 2. NIL的处理,可能需要用\text{NIL}或者在数学模式中正确表示。 3. 检查是否存在LaTeX语法错误,比如下标、循环变量是否正确使用数学模式。 4. 伪代码的结构是否需要调整,比如步骤10的说明是否足够清晰。 此外,可能还可以改进伪代码的可读性,比如添加注释说明每个数组的作用,或者使用更清晰的变量名,但用户可能希望保持简洁。 例如,变量L代表长度数组,P代表前驱节点数组,这在动态规划中是常见的,所以可能没问题。 可能的改进建议: - 将变量和数学表达式用$...$正确包裹。 - 使用\text{NIL}来表示NIL。 - 检查循环和条件的结构是否正确闭合。 - 确保所有数学符号的正确格式,如下标、比较运算符等。 例如,用户伪代码中的“≥”应该写成“\geq”在LaTeX中,但用户可能用了符号直接输入,需要检查是否符合LaTeX语法。根据用户提供的示例,比如在问题中的条件L[i] ≥ L[j],用户可能直接用了符号,但在LaTeX中应该用“\geq”。所以需要替换符号为LaTeX命令。 例如,第5行的“L[i] ≥ L[j]”应该写成$L[i] \geq L[j]$。 此外,伪代码中的“downto”是否正确?通常伪代码中使用“downto”而不是“downto”,但用户写的是“downto”,可能拼写错误?应该是“downto”吗?例如,第11行:“for k = L[m] downto 1 do”中的“downto”是否正确?是的,伪代码中常用“downto”表示递减循环。 另外,第10行中“从L中找到最大值L[m]”可能需要更明确的伪代码写法,比如: 10: $m \gets \arg\max_{1 \leq j \leq n} L[j]$ 但用户可能用自然语言描述,这在伪代码中也是可以接受的,尤其是当目标读者熟悉该步骤时。 综上所述,用户提供的伪代码在算法逻辑上是正确的,但存在格式上的问题,不符合系统指令中的LaTeX格式要求。需要将所有行内数学表达式用$...$包裹,并确保LaTeX语法正确。此外,可能需要调整一些符号的表示,如使用“\geq”代替“≥”,使用“\text{NIL}”表示NIL等。</think>以下是对伪代码的检查改进建议: ----- ### 格式语法改进 1. **数学表达式格式**(违反系统指令1、3) - 原伪代码所有变量未用$包裹 - 修正示例: ```latex 1: $L[1] = 1$; $P[1] = \text{NIL}$ 2: **for** $j = 2$ **to** $n$ **do** 5: **if** $S[i] < S[j]$ **and** $L[i] \geq L[j]$ **then** ``` 2. **NIL的规范表示** - 数学环境中需用`\text{NIL}`明确文本类型 - 修正:$P[1] = \text{NIL}$ 3. **逻辑运算符符号** - 原代码中`≥`应替换为LaTeX命令`\geq` - 修正:$L[i] \geq L[j]$ ----- ### 算法逻辑优化 1. **前驱指针初始化冗余**(第3行) - 每次外层循环都初始化$P[j] = \text{NIL}$,但内层循环可能覆盖此值 - 建议:将$P[j] = \text{NIL}$移至外层循环外,减少冗余操作 2. **最大值查找可优化**(第10行) - 原描述"从$L$中找到最大值$L[m]$"过于笼统 - 建议伪代码化: ```latex 10: $m \gets 1$ 11: **for** $j = 2$ **to** $n$ **do** 12: **if** $L[j] > L[m]$ **then** 13: $m \gets j$ 14: **end if** 15: **end for** ``` ----- ### 改进后伪代码 ```latex ### 算法 5.1 动态规划提取 LIS 伪码 **输入**: SOC 序列: $S$ **输出**: SOC 序列的 LIS: $S_{\text{lis}}$ 1: $L[1] = 1$; $P[1] = \text{NIL}$ 2: **for** $j = 2$ **to** $n$ **do** 3: $L[j] = 1$ 4: **for** $i = 1$ **to** $j - 1$ **do** 5: **if** $S[i] < S[j]$ **and** $L[i] \geq L[j]$ **then** 6: $L[j] = 1 + L[i]$; $P[j] = i$ 7: **end if** 8: **end for** 9: $P[j] = \text{NIL}$ \> 初始化移至此处 10: **end for** 11: $m \gets 1$ \> 显式查找最大值索引 12: **for** $j = 2$ **to** $n$ **do** 13: **if** $L[j] > L[m]$ **then** 14: $m \gets j$ 15: **end if** 16: **end for** 17: **for** $k = L[m]$ **downto** $1$ **do** 18: $S_{\text{lis}}[k] = S[m]$; $m = P[m]$ 19: **end for** ``` ----- ### 改进说明 1. **格式规范**:严格使用`$...$`包裹数学表达式,修正符号表示 2. **逻辑优化**: - 前驱指针初始化位置调整,避免重复覆盖 - 显式实现最大值索引查找,增强可读性 3. **可维护性**:添加行内注释(`\>`符号引导),明确关键操作意图 该算法时间复杂度仍为$O(n^2)$,若需进一步优化可考虑二分查找实现$O(n \log n)$算法,但超出当前伪代码改进范畴。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值