44道JavaScript送命题
<p>很久以前看过一个老外写的帖子,JavaScript Puzzlers!,直译就是JavaScript难题,里面列举了44道JavaScript选择题,大部分都是让人摸不着头脑的题目,需要仔细琢磨一番才能得到正确答案。也有一些作者也没有解释清除,直接通过实验给出答案了。</p><p>这44个问题是在ECMA 262(5.1)环境下,浏览器中试验的,如果是node环境下可能不同。这是因为二者环境差异,比如node环境下顶层变量是global,浏览器环境下则是windows。</p>
<p>本文部分内容也参考了文章Javascript 变态题解析。</p>
<h1>1. map&parseInt传参</h1>
<p><strong>["1", "2", "3"].map(parseInt)结果是什么?</strong></p>
<p>map方法指定一个回调函数,重新创建一个由回调函数返回值组成的新数组。该方法的原型是:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> new_array = arr.map(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> callback(currentValue[, index[, array]]) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Return element for new_array </span>
}[, thisArg])</pre>
</div>
<p>map接受2个参数,一个是回调函数callback,一个是回调函数的this值。</p>
<p>解释如下:</p>
<ul>
<li><strong>callback</strong>:生成新数组元素的函数,有三个参数</li>
<li><strong>currentValue</strong>:callbac当前正在处理的元素</li>
<li><strong>index</strong>:callback当前正在处理的当前元素的索引</li>
<li><strong>array</strong>:map方法调用的数组本身</li>
<li><strong>thisArg</strong>:执行callback函数时值被当做this</li>
</ul>
<p>Number.parseInt接受两个参数,原型<strong>Number.parseInt(string[, radix])</strong>,一个是要解析的值,一般是字符串,如果不是的话,使用toString方法将它转化为字符串。参数radix,是一个介于<strong>2</strong>到<strong>36</strong>之间的整数,如果省略该值或者为0,则按照10进制来解析,也就是说默认值是10,如果是“0x”或者“0X”开头,则以16进制为基数。如果小于2或者大于36,则parseInt返回NaN。</p>
<p>也就是说[].map(parseInt)这种写法根本就是想当然的,本题相当于下面的三句:</p>
<p>parseInt('1', 0);<br>parseInt('2', 1);<br>parseInt('3', 2);</p>
<p>这三句只有第一句会把第二个参数0默认为10,把10进制中的字符串“1”转换为10进制整数,结果是1;第二句在1进制里的字符串“2”转换为10进制整数,因为1进制里没有2,所以返回NaN;第三句把2进制中的字符串“3”转换为10进制整数,因为2进制中没有3,所以返回NaN;最终结果是。</p>
<p>另外,如果想得到正确的结果,应该这样写["1", "2", "2"].map(i => parseInt(i))。</p>
<h1>2. typeof和instanceof</h1>
<p><strong>运行这个表达式结果是什么?</strong>,这个主要考察typeof,instanceof两个操作符,前者是返回一个字符串表示未经计算的操作数的类型,后者是判断null的原型链中是否出现了Object函数的原型Object.property。</p>
<p>这两个操作符用来判断类型,前者常用来判断字面量,后者用来判断对象的类型,但是两个都有缺陷,详见另一篇文章《javascript中判断数据类型》</p>
<p>但是null是一个比较特殊的值,type of null返回的是“objec”,这是因为JavaScript最初实现中,值是由一个表示类型的标签和实际数值表示的。对象的类型标签是0,由于null代表是空指针(大多数平台下值为0x00),因此null的类型标签是0,typeof null也就返回“object”。</p>
<p>null是所有原型链的最顶端,null instanceof Object返回false,假设null这个值有构造函数Null,obj instanceof Null才会返回true。</p>
<p>所以上面表达式返回["object", false]。</p>
<h1>3.reduce&Math.pow传参</h1>
<p><strong>表达式[ .reduce(Math.pow), [].reduce(Math.pow) ]返回什么?</strong></p>
<p> 和第1题有些类似。arr.reduce方法对数组中每个元素执行一个自定义的reducer函数(升序执行),并将结果汇总为单个值,这个常常用来累加一个数组中的数字。原型如下:</p>
<div class="cnblogs_code">
<pre>arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]) </pre>
</div>
<ul>
<li><strong>callback</strong>:数组中每个值要执行的函数,有四个参数。</li>
<li><strong>accumulator</strong>:它是上一次回调函数时得到的值,或者initialValue。</li>
<li><strong>currentValue</strong>:数组中正在处理的当前元素。</li>
<li><strong>index</strong>:可选,数组中正在处理的元素的索引,如果提供了initialValue,则起始索引号为0,否则从索引1开始。</li>
<li><strong>array</strong>:调用reduce()的数组</li>
<li><strong>initialValue</strong>:作为第一次调用callback时的第一个参数的值。如果没有提供初始值,则将使用数组中的第一个元素。在没有初始值的空数组上调用reduce将报错。</li>
</ul>
<blockquote>
<p>注意:如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。</p>
<p>回调函数第一次执行时,<code>accumulator</code> 和<code>currentValue</code>的取值有两种情况:</p>
<ol>
<li>如果调用<code>reduce()</code>时提供了<code>initialValue</code>,<code>accumulator</code>取值为<code>initialValue</code>,<code>currentValue</code>取数组中的第一个值;如果没有提供 <code>initialValue</code>,那么<code>accumulator</code>取数组中的第一个值,<code>currentValue</code>取数组中的第二个值。</li>
<li>如果数组为空且没有提供initialValue,会抛出TypeError 。如果数组仅有一个元素(无论位置如何)并且没有提供initialValue, 或者有提供initialValue但是数组为空,那么此唯一值将被返回并且callback不会被执行。</li>
</ol></blockquote>
<p><strong>Math.pow(base, exponent)</strong>,返回基数base的指数exponent次幂,即base<sup>exponent。</sup></p>
<p>上面表达式调用reduce方法的时候没有提供initialValue,从索引1开始执行,第一次执行的时候accumulator取arr,这里是3,currentValue取第二个值,这里是2,传给Math.pow,得到9。然后.reduce(Math.pow),相当于Math.pow(9, 1),最终得到9。</p>
<p>第二个表达式是在空数组上调用reduce,并且没有提供initialValue,所以抛出错误:VM146:1 Uncaught TypeError: Reduce of empty array with no initial value at Array.reduce (<anonymous>)。</p>
<p>最后整个表达式的结果还是抛出错误。</p>
<h1>4. 优先级</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> val = 'smtg'<span style="color: rgba(0, 0, 0, 1)">;
console.log(</span>'Value is ' + (val === 'smtg') ? 'Something' : 'Nothing'); </pre>
</div>
<p>上面的表达式输出结果是什么?这个问题考察的是加号和三元运算的优先级,由于<strong>加号的优先级高于三元表达式</strong>,所以实际执行的是:</p>
<div class="cnblogs_code">
<pre>console.log('Value is true' ? 'Something' : 'Nothing'); </pre>
</div>
<p>因此最后输出“Something”。</p>
<h1>5.变量提升问题</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> name = 'World!'<span style="color: rgba(0, 0, 0, 1)">;
(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">typeof</span> name === 'undefined'<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> name = 'Jack'<span style="color: rgba(0, 0, 0, 1)">;
console.log(</span>'Goodbye ' +<span style="color: rgba(0, 0, 0, 1)"> name);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
console.log(</span>'Hello ' +<span style="color: rgba(0, 0, 0, 1)"> name);
}
})();</span> </pre>
</div>
<p>上面表达式输出什么?</p>
<p>这个是考察var变量提升问题,使用var申明的变量会提神到函数顶部,但是并不会初始化,这个是JavaScript内部机制。于是上面语句相当于:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> name = 'World!'<span style="color: rgba(0, 0, 0, 1)">;
(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> name = undefined;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">typeof</span> name === 'undefined'<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> name = 'Jack'<span style="color: rgba(0, 0, 0, 1)">;
console.log(</span>'Goodbye ' +<span style="color: rgba(0, 0, 0, 1)"> name);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
console.log(</span>'Hello ' +<span style="color: rgba(0, 0, 0, 1)"> name);
}
})();</span> </pre>
</div>
<p>name的声明放在了函数顶部,但是值是undefined。因为代码又放在一个<strong>闭包</strong>里,最外层那个name = “world”是不能访问的,闭包有隔离变量的作用。最后,上面的语句输出“Goodbye Jack”。</p>
<h1>6. JavaScript能表示的最大数</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> END = Math.pow(2, 53<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> START = END - 100<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> count = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> i = START; i <= END; i++<span style="color: rgba(0, 0, 0, 1)">) {
count</span>++<span style="color: rgba(0, 0, 0, 1)">;
}
console.log(count);</span> </pre>
</div>
<p><strong>上面表达式输出什么?</strong></p>
<p>乍一看是100,其实是干扰,这考察的不是循环,var变量啥的,而是JavaScript能表示的最大的数字是2<sup>53</sup>,即次幂表达式Math.pow(2, 53)<sup>。</sup>在这个最大数的基础上加上一个整数得到的结果都是不准确的。看下面的例子:</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">var</span> END = Math.pow(2, 53<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> START = END - 5<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> count = 0<span style="color: rgba(0, 0, 0, 1)">;
console.log(END); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 9007199254740992</span>
console.log(END + 7); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 9007199254740997</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740988</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740989</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740990</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740991</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740992</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740992</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740992</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740992</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740992</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740992</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740992</span>
console.log(START++ <= END, START); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true 9007199254740992</span> </pre>
</div>
<p>缩小了演示范围,END已经是最大值9007199254740992,END+7,应该得到9007199254740998,其实是得到9007199254740997,这是一个错误的计算结果。如果在START的基础上累加(每次加1),到第五次(包含第五次)得到的结果都是9007199254740992。所以在原题的i++过程中,运行到第100次之后每次得到的值都是9007199254740992,都满足i<=END,也就是说这是一个死循环,程序一直运行,得不到任何结果。</p>
<h1>7. 稀疏数组问题</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> ary = ;
ary[</span>10] = 10<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result = ary.filter(<span style="color: rgba(0, 0, 255, 1)">function</span>(x) { <span style="color: rgba(0, 0, 255, 1)">return</span> x === undefined;});</pre>
</div>
<p><strong>这个表达式的结果是什么?</strong></p>
<p>这个问题考察的是稀疏数组,稀疏数组中的未赋值的元素是空,并且filter会忽略这些元素,所以上面filter语句返回的是空数组[]。使用console.log()语句输出稀疏数组如下,可以看到console.log()语句也会忽略掉空位。</p>
<p><img src="https://img2020.cnblogs.com/blog/72678/202004/72678-20200422125322776-1187368358.png" alt=""> </p>
<p>所以本题输出的结果是[]。</p>
<h1> 8. 数字精度问题</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> two = 0.2<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> one = 0.1<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> eight = 0.8<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> six = 0.6<span style="color: rgba(0, 0, 0, 1)">;
console.log()</pre>
</div>
<p><strong>上面表达式输出结果是什么?</strong></p>
<p>这个考察的是JavaScript数字精度问题,JavaScript的Number类型为双精度IEEE 754 64位浮点类型,0.1不能精确的转换成二进制,会有溢出,遵循IEEE 754标准的语言都有这个毛病,包括java。这个问题造成0.1 + 0.2 != 0.3,0.8 - 0.6 != 0.2等等。这里先这样简单解释一下,下次专门写一篇来解释这个问题。</p>
<p>本题输出结果是。</p>
<h1>9. 字面量问题</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> showCase(value) {
</span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)">(value) {
</span><span style="color: rgba(0, 0, 255, 1)">case</span> 'A'<span style="color: rgba(0, 0, 0, 1)">:
console.log(</span>'Case A'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span> 'B'<span style="color: rgba(0, 0, 0, 1)">:
console.log(</span>'Case B'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> undefined:
console.log(</span>'undefined'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">:
console.log(</span>'Do not know!'<span style="color: rgba(0, 0, 0, 1)">);
}
}
showCase(</span><span style="color: rgba(0, 0, 255, 1)">new</span> String('A'));</pre>
</div>
<p><strong>上面的语句输出什么?</strong></p>
<p>这个其实考察的是字面量和对象是否恒相等的问题,case语句是使用恒等(===)来判断的,而‘A’ !== new Strting('A')返回false,所以最后输出‘Do not know’。判断恒等是三个等号'A' == new String('A')返回false,而两个等号会调用对象的toString()方法,'A'==new String('A')返回true,两个等号会先将右边的对象转换成字符串,如下图:</p>
<p><img src="https://img2020.cnblogs.com/blog/72678/202004/72678-20200422131422928-381754799.png" alt=""></p>
<h1>10. String()函数</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> showCase2(value) {
</span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)">(value) {
</span><span style="color: rgba(0, 0, 255, 1)">case</span> 'A'<span style="color: rgba(0, 0, 0, 1)">:
console.log(</span>'Case A'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span> 'B'<span style="color: rgba(0, 0, 0, 1)">:
console.log(</span>'Case B'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> undefined:
console.log(</span>'undefined'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">:
console.log(</span>'Do not know!'<span style="color: rgba(0, 0, 0, 1)">);
}
}
showCase2(String(</span>'A')); </pre>
</div>
<p>上面语句输出什么?String("A")不会创建一个对象,调用String方法返回一个字符串"A",所以输出“Case A”。</p>
<h1>11. 除法运算符%</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> isOdd(num) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> num % 2 == 1<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> isEven(num) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> num % 2 == 0<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> isSane(num) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> isEven(num) ||<span style="color: rgba(0, 0, 0, 1)"> isOdd(num);
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> values = ;
values.map(isSane);</span> </pre>
</div>
<p><strong>上面的map结果是什么?</strong></p>
<p>这个题目是考察求余运算符,前两个数字7,4没什么好说的。‘13’%2,<strong>%会把字符串转换成整形参与计算</strong>,得到1;-9%2会保留负号得到-1,符号是和第一个操作数保持一致,第二个操作数的符号会忽略,所以返回false,<strong>Infinity参与计求余计算得到NaN</strong>。所以最终结果是。</p>
<h1>12. parseInt</h1>
<div class="cnblogs_code">
<pre>console.log(parseInt(3, 8<span style="color: rgba(0, 0, 0, 1)">));
console.log(parseInt(</span>3, 2<span style="color: rgba(0, 0, 0, 1)">));
console.log(parseInt(</span>3, 0));</pre>
</div>
<p><strong>上面表达式分别输出什么?</strong></p>
<p>这里和第一题一样,再一次考察parseInt这个函数,把题目翻译翻译是问:把8进制里的3转化成10进制整数是3;把2进制中的3转换成10进制整形得到NaN,因为2进制中没有3;把10进制中的3转换成10进制整数还是3;所以最终结果是。</p>
<h1>13. Array.prototype</h1>
<div class="cnblogs_code">
<pre>console.log(Array.isArray(Array.prototype)); </pre>
</div>
<p><strong>上面表达式输出结果是什么?</strong></p>
<p>这个是一个非常容易忽略的知识点Array.property,是Array函数的原型对象,还是一个数组,从下面的语句可以看出:</p>
<p><img src="https://img2020.cnblogs.com/blog/72678/202004/72678-20200422223742073-1143066715.png" alt=""> </p>
<p> 所以本题的答案是true。</p>
<h1>14. if语句</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a = ;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> () {
console.log(a </span>== <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
console.log(</span>"wut"<span style="color: rgba(0, 0, 0, 1)">);
}</span> </pre>
</div>
<p><strong>上面这个语句得到什么?</strong></p>
<p>在JavaScript中if语句比较特殊,引用MDN中的介绍:</p>
<blockquote>
<p>任何一个值,只要它不是 <strong><code>undefined</code></strong><span style="font-family: "Open Sans", Arial, sans-serif">、</span><strong><code>null</code></strong>、 <strong><code>0</code></strong><span style="font-family: "Open Sans", Arial, sans-serif">、</span><strong><code>NaN</code></strong>或空字符串(<strong><code>""</code></strong>),那么无论是任何对象,即使是值为假的Boolean对象,在条件语句中都为真。</p>
</blockquote>
<p>这个特性给我们写if语句带来很大的便利,不需要考虑if语句中的变量类型,因为只要它不是上述的几种“没有意义”的值,判断都能通过,都能执行if语句。</p>
<p>但是非严格相等就不是这回事了,用==比较一个数组和true肯定得到false,所以本题结果是输出false。</p>
<h1>15. 对象比较问题</h1>
<div class="cnblogs_code">
<pre>[]==[] </pre>
</div>
<p><strong>上面语句的输出结果是什么?</strong></p>
<p>这个考察的是对象比较问题,[]是一个空数组,数组属于对象,对象比较无论如何比较都不相等。如下图:</p>
<p><img src="https://img2020.cnblogs.com/blog/72678/202004/72678-20200422225147185-1003485205.png" alt=""> </p>
<p> 上面比较对象<strong>(复杂数据)使用普通相等符号比较得到的结果都是false</strong>,所以本题结果是false。</p>
<h1>16. +是字符串连接符也是加法运算</h1>
<div class="cnblogs_code">
<pre>console.log('5' + 3<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>'5' - 3); </pre>
</div>
<p>加号遇到字符串的时候就是字符串连接符,会调用<strong>toString方法把另一个非字符串转换成字符串,然后来连接</strong>,所以第一个结果是字符串‘53’;第二个是减号,它的行为和加号刚好相反,<strong>它是把字符串转换成整形</strong>,第二个输出2。</p>
<p>所以本题输出['53', 2]。</p>
<h1>17. 加减运算和正负运算</h1>
<div class="cnblogs_code">
<pre>console.log(1 + - + + + - + 1); </pre>
</div>
<p><strong>上面表达式输出什么结果?</strong></p>
<p>这个要搞明白这个表达式其实是1 + (-+++-+1),除了第一个+是加法,后面的+,-都是<strong>正负运算</strong>,根据正正得正,正负得负,负负得正的原则-+++-+1是1,所以最后结果得到2。</p>
<h1>18. 还是稀疏数组</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> ary = Array(3<span style="color: rgba(0, 0, 0, 1)">);
ary[</span>0]=2<span style="color: rgba(0, 0, 0, 1)">
let s </span>= ary.map(<span style="color: rgba(0, 0, 255, 1)">function</span>(elem) { <span style="color: rgba(0, 0, 255, 1)">return</span> '1'<span style="color: rgba(0, 0, 0, 1)">; });
console.log(s);</span> </pre>
</div>
<p><strong>上面语句输出什么?</strong></p>
<p>这又是考察稀疏数组问题,<strong>map会忽略调稀疏数组中的空元素</strong>,输出结果是["1", empty × 2]。</p>
<h1>19. argument对象</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> sidEffecting(ary) {
arguments[</span>1] = 10<span style="color: rgba(0, 0, 0, 1)">;
ary[</span>0] = ary;
}
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> bar(a,b,c) {
c </span>= 10<span style="color: rgba(0, 0, 0, 1)">
sidEffecting(arguments);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> a + b +<span style="color: rgba(0, 0, 0, 1)"> c;
}
console.log(bar(</span>1,1,1)) </pre>
</div>
<p><strong>上面语句输出什么?</strong></p>
<p>这一题考察的是对argument对象的了解,argument是一个类数组对象,修改对象的属性值会影响其他使用到对象的地方,即使变量不在同一范围内。再加上对象属性可以使用类似数组下标的方式来访问,对象做了字符串到值的映射,而数组做的是数字到值的映射。</p>
<p>根据这些可以推导结果是21。</p>
<h1>20. JavaScript中的最大数</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a = 111111111111111110000<span style="color: rgba(0, 0, 0, 1)">,
b </span>= 1111<span style="color: rgba(0, 0, 0, 1)">;
console.log(a </span>+ b); </pre>
</div>
<p><strong>上面的语句输出什么内容?</strong></p>
<p>这个又一次考察JavaScript中的最大值问题,JavaScript中最大值是Math.pow(2, 53)=9007199254740992,计算过程中如果超出这个最大值范围就不准确了,但是怎么个不准确法,是不确定的。这里输出结果是111111111111111110000, 还是a的值。</p>
<h1>21. Array.property.reverse</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> x =<span style="color: rgba(0, 0, 0, 1)"> [].reverse;
x();</span> </pre>
</div>
<p><strong>上面语句输出什么?</strong></p>
<p>这个有些奇怪了,原文中解释说reverse方法会返回调用这个方法的数组本身(就是this),但是x()没有调用者,所以this指向了全局对象window。但是我在chrome中试过,这个是会报错的,报错信息是:Uncaught TypeError: Cannot convert undefined or null to object at reverse (<anonymous>)。这个可能是原文写的比较早,后面的浏览器修改了这个行为。</p>
<h1>22. Number.MIN_VALUE</h1>
<div class="cnblogs_code">
<pre>console.log(Number.MIN_VALUE > 0); </pre>
</div>
<p>这个考察Number.MIIN_VALUE的值,MDN上解释如下:</p>
<blockquote>
<p>Number.MIN_VALUE表示最小正数,即最接近 0 的正数 (实际上不会变成 0)。最大的负数是 <code>-MIN_VALUE</code>。</p>
</blockquote>
<p>所以Number.MIN_VALUE是大于0的,这里输出是true。</p>
<h1>23. 强制转换</h1>
<div class="cnblogs_code">
<pre>console.log(); </pre>
</div>
<p><strong>上面表达式输出什么?</strong></p>
<p>这里考察的是在大于号,<strong>小于号运算中true会被强制转换为1</strong>,<strong>false会被强制转换成0</strong>。相当于console.log(),转换后就是console.log(),所以这里输出结果是。</p>
<h1>24. 数组字面量的字符串表示</h1>
<div class="cnblogs_code">
<pre>console.log(2 == [[]]); </pre>
</div>
<p><strong>上面语句输出什么?</strong></p>
<p>这个题套路深,我先说答案,是true。连原文作者都惊叹这是什么鬼?原文是:the most classic wtf!如果试着解释的话,非严格相等==在遇到字面量[[]]的时候,会<strong>试图将它转换成字符串然后和2比较</strong>,但是<strong>[[]].toString()返回‘2’</strong>,然后‘2’ == 2返回true,是不是很惊喜?是不是想骂人?如下图,这样非严格相等就返回true了。</p>
<p><img src="https://img2020.cnblogs.com/blog/72678/202004/72678-20200423091729307-1580198841.png" alt=""> </p>
<h1>25. 3.和.3</h1>
<div class="cnblogs_code">
<pre>console.log(3<span style="color: rgba(0, 0, 0, 1)">.toString());
console.log(</span>3<span style="color: rgba(0, 0, 0, 1)">..toString());
console.log(</span>3...toString()); </pre>
</div>
<p>上面语句输出什么结果?</p>
<p>这里要搞清楚<strong>3.</strong>和<strong>.3</strong>都是合法的数字3.是一个省略了尾数部分0的数字,.3是一个省略了整数部分0的数字;第一句中但是toString()不是一个数字,所以第一句报错:Uncaught SyntaxError: Invalid or unexpected token。第二句相当于(3.).toString()输出”3“。第三句和第一句一样报错,原因也是一样的,第二个.后面的一串..toString()不是一个合法的数字,于是就报错了。</p>
<p>所以正确的答案是error,”3“,error。</p>
<h1>26. var和闭包问题</h1>
<div class="cnblogs_code">
<pre>(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(){
</span><span style="color: rgba(0, 0, 255, 1)">var</span> x = y = 1<span style="color: rgba(0, 0, 0, 1)">;
})();
console.log(y);
console.log(x);</span> </pre>
</div>
<p><strong>上面的语句输出什么?</strong></p>
<p>这一题考察的是对闭包和var变量的了解。<strong>闭包有隔离变量的作用</strong>,所以var不能提升变量,<strong>在闭包外部访问x是失败的</strong>,所以第二句输出Undefined。闭包中如果不使用var声明变量,<strong>直接不带var,这样申明y=1,反而y是全局的</strong>,在外部是可以访问到变量y的,所以第一句输出1。是不是很惊喜?</p>
<h1>27. 正则表达式不可相互比较</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a = /123/, b = /123/<span style="color: rgba(0, 0, 0, 1)">;
console.log(a </span>==<span style="color: rgba(0, 0, 0, 1)"> b);
console.log(a </span>=== b); </pre>
</div>
<p><strong>上面两句分别输出什么?</strong></p>
<p>这个考察的是正则表达式比较问题,虽然字面量内容相同,但是JavaScript认为这是两个正则表达式,是对象类型,他们是不相等的。这里输出结果为false false。</p>
<h1>28. 数组比较</h1>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">var</span> a = , b = , c = ;
console.log(a </span>==<span style="color: rgba(0, 0, 0, 1)">b);
console.log(a </span>===<span style="color: rgba(0, 0, 0, 1)"> b);</span><span style="color: rgba(0, 0, 0, 1)">
console.log(a </span>><span style="color: rgba(0, 0, 0, 1)"> c);
console.log(a </span>< c); </pre>
</div>
<p><strong>上面比较以此输出什么?</strong></p>
<p>即使数组字面量相等,使用==或者===判断两个数组也不相等。而大于,小于比较是<strong>按照字典顺序比较</strong>的,这里以a<c具体如下:</p>
<ul>
<li>比较a<c,相等,继续比较下一位</li>
<li>比较a<c,相等,继续比较下一位</li>
<li>比较a<c,返回true,于是a<c返回true</li>
</ul>
<p>所以上面以此输出false,false,false,true。</p>
<h1>29. 构造函数的原型</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a = {}, b =<span style="color: rgba(0, 0, 0, 1)"> Object.prototype
console.log(); </pre>
</div>
<p><strong>上面代码输出什么结果?</strong></p>
<p>JavaScript中函数才有prototype属性,对象是没有的,对象有__proto__,指向对象的构造函数的原型,所以a.prototype是undefined。b是Object函数的原型,是一个对象,所以第一个是false。第二个是使用getPrototypeOf方法获取对象a的原型(即a.__proto__),这个和Object.prototype相等的,所以第二个表达式返回true。</p>
<p>a.__proto__是对象的原型,它是浏览器暴露出来的属性,JavaScript标准中没有这个属性。下面的语句输出:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a = {}, b =<span style="color: rgba(0, 0, 0, 1)"> Object.prototype
console.log([</span>a.__proto__ === b); </pre>
</div>
<p>如下图:</p>
<p><img src="https://img2020.cnblogs.com/blog/72678/202004/72678-20200423131901186-224141075.png" alt=""> </p>
<h1>30. 函数的原型对象</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> f() {}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> a = f.prototype, b =<span style="color: rgba(0, 0, 0, 1)"> Object.getPrototypeOf(f);
console.log(a </span>=== b); </pre>
</div>
<p><strong>上面的语句输出什么?</strong></p>
<p>这还是考察函数原型问题。这f.prototype是获取函数f的原型对象,Object.getPrototypeOf(f)是获取对象构造函数的原型,注意函数也是对象,它的构造函数是Function(),因此f的构造函数的原型是Function.property,因此这这里输出false。</p>
<h1>31. Function.name</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> foo() { }
</span><span style="color: rgba(0, 0, 255, 1)">var</span> oldName =<span style="color: rgba(0, 0, 0, 1)"> foo.name;
foo.name </span>= "bar"<span style="color: rgba(0, 0, 0, 1)">;
console.log();</span> </pre>
</div>
<p><strong>上面的语句输出什么结果?</strong></p>
<p>这道题考察的是函数的name属性,<strong>function.name 属性返回函数实例的名称</strong>,<strong>这个属性是不可写的</strong>,因为访问器属性中writable属性为false。所以这一题输出的是['foo', 'foo']。</p>
<h1>32. str.replace</h1>
<div class="cnblogs_code">
<pre>console.log("1 2 3".replace(/\d/g, parseInt)); </pre>
</div>
<p>上面语句输出什么内容?这一题考察的是replace方法,str.replace方法的原型如下:</p>
<div class="cnblogs_code">
<pre>str.replace(regexp|substr, newSubStr|<span style="color: rgba(0, 0, 255, 1)">function</span>) </pre>
</div>
<p>参数解释如下:</p>
<ul>
<li><strong>regexp (pattern)</strong>:一个正则表达式对象(即RegExp对象)或者其字面量。该正则所匹配的内容会被第二个参数的返回值替换掉。它和substr是二选一的。</li>
<li><strong>substr (pattern)</strong>:一个将被newSubStr替换的字符串。其被视为一整个字符串,而不是一个正则表达式。仅第一个匹配项会被替换。它和regexp是二选一的。</li>
<li><strong>newSubStr (replacement)</strong>:用于替换掉第一个参数在原字符串中的匹配部分的字符串。该字符串中可以内插一些特殊的变量名。参考下面的使用字符串作为参数。它和function是二选一的。<br>
<table border="0">
<tbody>
<tr>
<td>变量名</td>
<td>代表的值</td>
</tr>
<tr>
<td>$$</td>
<td>插入一个 "$"。</td>
</tr>
<tr>
<td>$&</td>
<td>插入匹配的子串。</td>
</tr>
<tr>
<td>$`</td>
<td>插入当前匹配的子串左边的内容。</td>
</tr>
<tr>
<td>$'</td>
<td>插入当前匹配的子串右边的内容。</td>
</tr>
<tr>
<td>$n</td>
<td>假如第一个参数是 RegExp对象,并且 n 是个小于100的非负整数,那么插入第 n 个括号匹配的字符串。提示:索引是从1开始</td>
</tr>
</tbody>
</table>
</li>
<li><strong>function (replacement)</strong>:一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。参考下面的指定一个函数作为参数。它和newSubStr是二选一的。<br>
<table border="0">
<tbody>
<tr>
<td>变量名</td>
<td>代表的值</td>
</tr>
<tr>
<td>match</td>
<td>匹配的子串。(对应于上述的$&。)</td>
</tr>
<tr>
<td>p1,p2, ...</td>
<td>假如replace()方法的第一个参数是一个RegExp 对象,则代表第n个括号匹配的字符串。(对应于上述的$1,$2等。)例如,如果是用 /(\a+)(\b+)/ 这个来匹配,p1 就是匹配的 \a+,p2 就是匹配的 \b+。</td>
</tr>
<tr>
<td>offset</td>
<td>匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是 'abcd',匹配到的子字符串是 'bc',那么这个参数将会是 1)</td>
</tr>
<tr>
<td>string</td>
<td>被匹配的原字符串。</td>
</tr>
<tr>
<td>NamedCaptureGroup</td>
<td>命名捕获组匹配的对象</td>
</tr>
</tbody>
</table>
</li>
</ul>
<p>不得不说replace方法有点复杂,在这个例子中第一个参数是一个正则表达式,第二个参数是一个函数,函数参数以此是match,offset,string,NamedCaptureGroup,但是parseInt仅仅接受2个参数,所以相当于执行下面的语句:</p>
<p>parseInt('1', 0) // 10进制里的1是1<br>parseInt('2', 2) // 2进制里没有2,所以NaN<br>parseInt('3', 4) // 4进制中的3是3</p>
<p>所以最终结果是"1 NaN 3",这个作者很喜欢拿parseInt说事。</p>
<h1>33. eval函数</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> f() {}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> parent =<span style="color: rgba(0, 0, 0, 1)"> Object.getPrototypeOf(f);
console.log(f.name);
console.log(parent.name);
console.log(</span><span style="color: rgba(0, 0, 255, 1)">typeof</span><span style="color: rgba(0, 0, 0, 1)"> eval(f.name));
console.log(</span><span style="color: rgba(0, 0, 255, 1)">typeof</span> eval(parent.name));</pre>
</div>
<p><strong>上面的语句输出什么?</strong></p>
<p>第一句f.name就是”f“;parent是Function.prototype,这是一个对象,它没有name属性,所以第二句应该是啥都不输出;eval()函数会将传入的字符串当做 JavaScript 代码进行执行,eval(f.name)相当于eval('f'),执行结果是输出函数f的内容,type of计算返回function;最后一句返回空;</p>
<h1>34. exp.test</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> lowerCaseOnly =/^+$/<span style="color: rgba(0, 0, 0, 1)">;
console.log(); </pre>
</div>
<p><strong>上面语句输出什么内容?</strong></p>
<p>RegExp.prototype.test()方法的参数是一个字符串,<strong>如果不是字符串会尝试转换成字符串</strong>。所以上面两句相当于lowerCaseOnly.test("null"),lowerCaseOnly.test(”Undefined“),所以返回</p>
<h1>35. 数组元素最后一个逗号</h1>
<div class="cnblogs_code">
<pre>console.log([,,,].join(", "));</pre>
</div>
<p><strong>上面的表达式输出什么内容?</strong></p>
<p>我们定义一个有三个元素的数组的时候可以这样var arr = ; 也可以这样var arr = ;它后面了一个逗号,但是还是三个元素。本题的关键点就是[, , ,],这其实是一个有三个空元素的数组,输出<span class="object-description"> <span class="object-properties-preview">[<span class="object-value-undefined">empty × 3]。<strong>三个空元素用逗号连接起来最后输出是两个逗号</strong>,因为都是空元素,其实最后一个逗号后面是有一个空元素的。所以本题输出",,"。如下图:</span></span></span></p>
<p><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined"><img src="https://img2020.cnblogs.com/blog/72678/202004/72678-20200425213134128-1900838534.png" alt=""> </span></span></span></p>
<p>其实定义一个对象也可以在最后一个属性后面加上一个逗号,例如 var obj = { name: 'zhangsan', age: 20, };</p>
<h1>36. class关键字</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a = {class: "Animal", name: 'Fido'<span style="color: rgba(0, 0, 0, 1)">};
console.log(a.class);</span> </pre>
</div>
<p><strong><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">上面的语句输出什么?</span></span></span></strong></p>
<p><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">这一题是考察class关键字,我在chrome里输出的是正确的值“Animal”,记住在定义变量或者属性名字的时候尽量避免JavaScript关键字。如果<strong>属性里有关键字</strong>,可以这样使用<strong>a["class"]</strong>。</span></span></span></p>
<h1><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">37. 时间转换问题</span></span></span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a = <span style="color: rgba(0, 0, 255, 1)">new</span> Date("epoch"<span style="color: rgba(0, 0, 0, 1)">)
console.log(a);</span> </pre>
</div>
<p><strong><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">上面的表达式输出什么?</span></span></span></strong></p>
<p><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">new Date()构造函数传入的必须是一个时间字符串,即可以通过Date.parse()解析成功。所以本题输出Invalid Date。</span></span></span></p>
<h1><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">38. 函数的形参个数</span></span></span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a =<span style="color: rgba(0, 0, 0, 1)"> Function.length,
b </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Function().length
console.log(a </span>=== b); </pre>
</div>
<p><strong><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">上面表达式输出什么?</span></span></span></strong></p>
<p><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">Function 构造器本身也是个Function。他的length属性值为 1,所以a=1。该属性 Writable: false, Enumerable: false, Configurable: true。但是new Function()是一个对象,他没有形参,说以b=0,本题输出false。另外函数的实参的个数可以用argument.length获取。</span></span></span></p>
<h1><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">39. 还是时间转换问题</span></span></span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a = Date(0<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> b = <span style="color: rgba(0, 0, 255, 1)">new</span> Date(0<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> c = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Date();
console.log(); </pre>
</div>
<p><strong><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">上面的语句输出什么?</span></span></span></strong></p>
<p><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">直接调用函数Date(),得到的结果是一个表示时间的字符串;使用new操作符+构造函数,得到的是一个时间对象;参数是0返回的是格林威治0时,不带参数返回的是当前时间;搞清楚这些之后这题就简单了,a是一个时间字符串,b是一个时间对象,表示格林威治0时,c也是一个时间对象,不过是当前时间。所以本题输出</span></span></span></p>
<h1><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">40. Math.max()&Math.min()</span></span></span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> min = Math.min(), max =<span style="color: rgba(0, 0, 0, 1)"> Math.max()
console.log(min </span>< max); </pre>
</div>
<p><strong><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">上面语句输出什么?</span></span></span></strong></p>
<p><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">注意Max.max()和Max.min()传入的参数是一个数组,如果不传参,前者返回+Infinity,后者返回-Infinity。Infinity不能做比较,所以本题返回false。</span></span></span></p>
<h1><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">41. 正则表达式的“记忆”</span></span></span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> captureOne(re, str) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> match =<span style="color: rgba(0, 0, 0, 1)"> re.exec(str);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> match && match;
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> numRe= /num=(\d+)/<span style="color: rgba(0, 0, 0, 1)">ig,
wordRe </span>= /word=(\w+)/<span style="color: rgba(0, 0, 0, 1)">i,
a1 </span>= captureOne(numRe,"num=1"<span style="color: rgba(0, 0, 0, 1)">),
a2 </span>= captureOne(wordRe, "word=1"<span style="color: rgba(0, 0, 0, 1)">),
a3 </span>= captureOne(numRe,"NUM=2"<span style="color: rgba(0, 0, 0, 1)">),
a4 </span>= captureOne(wordRe,"WORD=2"<span style="color: rgba(0, 0, 0, 1)">);
console.log();</pre>
</div>
<p>上面表达式输出什么?这题考察的是正则表达式的/g选项,这个选项表示全局匹配;找到所有匹配,而不是在第一个匹配后停止。来看下面的例子:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> myRe = /ab*/<span style="color: rgba(0, 0, 0, 1)">g;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> str = 'abbcdefabh'<span style="color: rgba(0, 0, 0, 1)">;
console.log(myRe.exec(str));
console.log(myRe.exec(str));</span> </pre>
</div>
<p>输出结果如下:</p>
<p><img src="https://img2020.cnblogs.com/blog/72678/202004/72678-20200425231648813-1591377582.png" alt="" width="394" height="247"> </p>
<p> </p>
<p>从结果可以看出,执行两次都有返回结果,分别找到字符串中两处符合条件的匹配。</p>
<p>而原题中第一个正在有/g选项,第一次匹配成功之后会从当前位置往后查找,所以在执行a3 = captureOne(numRe, "NUM=2")的时候不是从字符串位置0开始查找的,而是从第5位开始,所有匹配就失败了,找不出1。</p>
<p>所以本题输出。</p>
<h1>42. Date中的month</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a = <span style="color: rgba(0, 0, 255, 1)">new</span> Date("2014-03-19"<span style="color: rgba(0, 0, 0, 1)">),
b </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Date(2014, 3, 19<span style="color: rgba(0, 0, 0, 1)">);
console.log(); </pre>
</div>
<p>上面表达式输出什么?这个问题考察的是Date对象中的月份问题,注意使用第二种方式定义时间对象,</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">new</span> Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]); </pre>
</div>
<p><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined"><strong>第二个参数是monthIndex,它是从0开始的,3表示4月份</strong>,所以本题输出。如果初学JavaScript,感觉套路深啊套路深。</span></span></span></p>
<h1><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">43. 正则表达式中的转义</span></span></span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">if</span> ('http://giftwrapped.com/picture.jpg'.match('.gif'<span style="color: rgba(0, 0, 0, 1)">)) {
console.log(</span>'a gif file'<span style="color: rgba(0, 0, 0, 1)">);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
console.log(</span>'not a gif file'<span style="color: rgba(0, 0, 0, 1)">);
}</span> </pre>
</div>
<p>String.prototype.match 接受一个正则, 如果不是, 按照 new RegExp(obj) 转化. 所以 . 并不会转义,所以开头的‘http://gifwrapped......’中/gif就匹配了 /.gif/,所以输出“a gif file”</p>
<h1><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">44. 变量提升</span></span></span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> foo(a) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> a;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> a;
}
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> bar(a) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> a = 'bye'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> a;
}
console.log(); </pre>
</div>
<p><span class="object-description"><span class="object-properties-preview"><span class="object-value-undefined">上面语句输出什么?a作为参数其实已经声明了, 所以 var a; var a = 'bye' 其实就是 a; a ='bye',所以本题输出["hello", "bye"]。</span></span></span></p>
<p> </p>
<p>JavaScript语法本来就有很多不合理的地方,导致书写JavaScript很容易出错,本文中如有错误,欢迎各位看官提出来。</p>
</div>
<div id="MySignature" role="contentinfo">
<p style="background-position: 1% 50%; border-top: #e0e0e0 1px dashed; border-right: #e0e0e0 1px dashed; border-bottom: #e0e0e0 1px dashed; border-left: #e0e0e0 1px dashed; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 60px; background: #969696 url("https://images.cnblogs.com/cnblogs_com/lloydsheng/239039/o_copyright.gif") no-repeat 1% 50%; font-family: 微软雅黑; font-size: 12px; color: #FFFFFF">
作者:<b><span style="font-size: 12px; color: red">Tyler Ning</span></b>
<br>
出处:http://www.cnblogs.com/tylerdonet/
<br>
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,请微信联系<strong >冬天里的一把火
</strong>
<div class="van-overlay" style="display: none;z-index: 1;position: fixed;top: 0;left: 0;z-index: 1;width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.7);"></div>
<imgid="pop-contect-wechat" style="display:none;width:20em;position: fixed;max-height: 100%;overflow-y: auto;transition: transform 0.3s;" src="https://files-cdn.cnblogs.com/files/tylerdonet/shouwangzhe059187.bmp"/>
</p><br><br>
来源:https://www.cnblogs.com/tylerdonet/p/12742547.html
頁:
[1]