你不知道的Javascript “谜题”

你不知道的Javascript “谜题”


["1", "2", "3"].map(parseInt)
  
A. ["1", "2", "3"]
B. [1, 2, 3]
C. [0, 1, 2]
D. other

解析:D

map接受两个参数,一个回调函数 callback, 一个回调函数的this值,其中回调函数接受三个参数 currentValue, index, arrary,而题目中, map只传入了回调函数parseInt,其次,parseInt 只接受两个两个参数 string, radix(基数)。

在没有指定基数,或者基数为 0 的情况下,JavaScript 作如下处理:

  • 如果字符串 string 以"0x"或者"0X"开头, 则基数是16 (16进制).
  • 如果字符串 string 以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪个基数由实现环境决- 定。ECMAScript 5 规定使用10,但是并不是所有的浏览器都遵循这个规定。因此,永远都要明确给出radix参数的值。
  • 如果字符串 string 以其它任何值开头,则基数是10 (十进制)。
    所以本题即问
parseInt('1', 0);
parseInt('2', 1);
parseInt('3', 2);

首先后两者参数不合法.
所以答案是 [1, NaN, NaN]


[typeof null, null instanceof Object]
        
A. ["object", false]
B. [null, false]
C. ["object", true]
D. other

解析:A

typeof 返回一个表示类型的字符串,instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。

typeresult
Undefined“undefined”
Null“object”
Boolean“boolean”
Number“number”
String“string”
Symbol“symbol”
Host objectImplementation-dependent
Function“function”
Object“object”

所以typeof null返回object,但是null并不存在于参数 object 的原型链上,所以返回false。


[ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ]
        
A. an error
B. [9, 0]
C. [9, NaN]
D. [9, undefined]

解析:A

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

reduce接收两个参数,一个回调函数,一个可选的将用作累积的初始值。

如果提供了 initialValue,则 reduce 方法会对数组中的每个元素调用一次 callbackfn 函数(按升序索引顺序)。如果未提供 initialValue,则 reduce 方法会对从第二个元素开始的每个元素调用 callbackfn 函数。

回调函数接收四个参数,依次是:

  • 通过上一次调用回调函数获得的值。如果向 reduce 方法提供 initialValue,则在首次调用函数时,total 为 initialValue。
  • 当前数组元素的值。
  • 当前数组元素的数字索引。
  • 包含该元素的数组对象。

pow() 方法返回 x 的 y 次幂。

[3, 2, 1].reduce(Math.pow) 拆分开来就是:

Math.pow(3, 2)    // 9
Math.pow(9, 1)    // 9

但是reduce在两个情况下会抛出异常,当满足下列任一条件时,将引发 TypeError 异常:

  • callbackfn 参数不是函数对象。
  • 数组不包含元素,且未提供 initialValue。
    所以 [].reduce(Math.pow) 会抛出异常

var val = 'smtg';
console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing');
        
A. Value is Something
B. Value is Nothing
C. NaN
D. other

解析:D

+的优先级大于?,所以原题等价于:

console.log('Value is true' ? 'Something' : 'Nothing') // Something

var name = 'World!';
(function () {
    if (typeof name === 'undefined') {
        var name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();
        
A. Goodbye Jack
B. Hello Jack
C. Hello undefined
D. Hello World

解析:A

在javascript里,声明变量或函数会被提升,就是说,变量提升是JavaScript将声明移至作用域 scope (全局域或者当前函数作用域) 顶部的行为。

但是javascript只提升声明,而不是初始化,如果使用一个在已经使用后才声明和初始化的值,这个值将是undefined,所以这题就相当于:

var name = 'World!';
(function () {
    var name;
    if (typeof name === 'undefined') {
        name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();

var END = Math.pow(2, 53);
var START = END - 100;
var count = 0;
for (var i = START; i <= END; i++) {
    count++;
}
console.log(count);
        
A. 0
B. 100
C. 101
D. other

解析:D

2的53次方是js能正确计算且不失精度的最大整数。 js中可以表示的最大整数不是2的53次方,而是1.7976931348623157e+308。
Math.pow(2, 53) = 9007199254740992。最大值加1还是9007199254740992,所以这个循环会一直下去
9007199254740992 +1还是 9007199254740992 ,这就是因为精度问题,如果 9007199254740992 +11或者 9007199254740992 +111的话,值是会发生改变的,只是这时候计算的结果不是正确的值,就是因为精度丢失的问题。


var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
        
A. [undefined × 7]
B. [0, 1, 2, 10]
C. []
D. [undefined]

解析:C

array.filter(function(currentValue,index,arr), thisValue)

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。filter接收两个参数, 一个回调函数,一个是可选的回调函数的this值,默认为undefined。

回调函数依次接收三个参数:

  • 必须。当前元素的值
  • 可选。当期元素的索引值
  • 可选。当期元素属于的数组对象

再说稀疏矩阵,当你取数组中某个没有定义的数时:

arr[4] // undefined

但是当你遍历它时,你会发现它并没有元素。JavaScript会跳过这些缝隙,所以答案为: []


function showCase(value) {
    switch(value) {
    case 'A':
        console.log('Case A');
        break;
    case 'B':
        console.log('Case B');
        break;
    case undefined:
        console.log('undefined');
        break;
    default:
        console.log('Do not know!');
    }
}
showCase(new String('A'));
        
A. Case A
B. Case B
C. Do not know!
D. undefined

解析:C

switch 是严格比较,用的是 ===,String 实例和字符串不一样。

var s_prim = 'foo';
var s_obj = new String(s_prim);

console.log(typeof s_prim); // "string"
console.log(typeof s_obj);  // "object"
console.log(s_prim === s_obj); // false

所以答案是 Do not know!


function showCase2(value) {
    switch(value) {
    case 'A':
        console.log('Case A');
        break;
    case 'B':
        console.log('Case B');
        break;
    case undefined:
        console.log('undefined');
        break;
    default:
        console.log('Do not know!');
    }
}
showCase2(String('A'));
        
A. Case A
B. Case B
C. Do not know!
D. undefined

解析:A

String(x)不创建对象,但返回一个字符串,即typeof String(1)===“string”


function isOdd(num) {
    return num % 2 == 1;
}
function isEven(num) {
    return num % 2 == 0;
}
function isSane(num) {
    return isEven(num) || isOdd(num);
}
var values = [7, 4, '13', -9, Infinity];
values.map(isSane);
        
A. [true, true, true, true, true]
B. [true, true, true, true, false]
C. [true, true, true, false, false]
D. [true, true, false, false, false]

解析:C

7 % 2 => 1
4 % 2 => 0
'13' % 2 => 1
-9 % % 2 => -1
Infinity % 2 => NaN

Array.isArray( Array.prototype )
        
A. true
B. false
C. error
D. other

解析:A
Array.prototype 本身也是一个 Array


var a = [0];
if ([0]) {
  console.log(a == true);
} else {
  console.log("wut");
}
        
A. true
B. false
C. "wut"
D. other

解析:B

  • boolean([0]) === true
  • [0] == true
    • true 转换为数字 => 1
    • [0] 转化为数字失败, 转化为字符串 ‘0’, 转化成数字 => 0
    • 0 !== 1

[]==[]
        
A. true
B. false
C. error
D. other

解析:B

[] 是Object, 两个 Object 不相等


'5' + 3
'5' - 3
        
A. "53", 2
B. 8, 2
C. error
D. other

解析:A
-会尽可能的将两个操作数变成数字,而 + 如果两边不都是数字,那么就是字符串拼接

[1 < 2 < 3, 3 < 2 < 1]
        
 
A. [true, true]
B. [true, false]
C. error
D. other

解析:A

'<‘运算符顺序是从左到右,所以变成了[true < 3, false < 1],接着进行隐式类型转换,’<'操作符的转换规则:

  • 如果两个操作值都是数值,则进行数值比较
  • 如果两个操作值都是字符串,则比较字符串对应的字符编码值
  • 如果只有一个操作值是数值,则将另一个操作值转换为数值,进行数值比较
  • 如果一个操作数是对象,则调用valueOf()方法(如果对象没有valueOf()方法则调用toString()方法),得到的结果按照前面的规则执行比较
  • 如果一个操作值是布尔值,则将其转换为数值,再进行比较

这里首先通过Number()转换为数字然后进行比较,true转换成1,false转换成0,就变成了[1 < 3, 0 < 1]


3.toString()
3..toString()
3...toString()
        
A. "3", error, error
B. "3", "3.0", error
C. error, "3", error
D. other

解析:C

很多人都踩过3.toString()的坑,虽然JavaScript会在调用方法时对原始值进行包装,但是这个点是小数点呢、还是方法调用的点呢,于是乎第一个就是error了,因为JavaScript解释器会将其认为是小数点。

而第二个则很好说通了,第一个点解释为小数点,变成了(3.0).toString(),结果就是"3"了。

第三个也是,第一个点为小数点,第二个是方法调用的点,但是后面接的不是一个合法的方法名,于是乎就error了。


(function(){
  var x = y = 1;
})();
console.log(y);
console.log(x);
        
A. 1, 1
B. error, error
C. 1, error
D. other

解析:C
在作用域内,变量定义和函数定义会先行提升,所以里面就变成了:

(function(){
    var x;
    y = 1;
    x = 1;
})();

这点会问了,为什么不是var x, y,这就是坑的地方…这里只会定义第一个变量x,而y则会通过不使用var的方式直接使用,于是乎就隐式定义了一个全局变量y,所以,y是全局作用域下,而x则是在函数内部,结果就为1, error


var a = /123/,
    b = /123/;
a == b
a === b
        
A. true, true
B. true, false
C. false, false
D. other

解析:C
JavaScript中的正则表达式依旧是对象,使用typeof运算符就能得出结果:

console.log(typeof /123/);
//输出结果:
//"object"

==运算符左右两边都是对象时,会比较他们是否指向同一个对象,可以理解为C语言中两个指针的值是否一样(指向同一片内存),所以两个结果自然都是false


var a = [1, 2, 3],
    b = [1, 2, 3],
    c = [1, 2, 4]
a ==  b
a === b
a >   c
a <   c
        
A. false, false, false, true
B. false, false, false, false
C. true, true, false, true
D. other

解析:A

JavaScript中Array的本质也是对象,所以前两个的结果都是false,而JavaScript中Array的>运算符和<运算符的比较方式类似于字符串比较字典序,会从第一个元素开始进行比较,如果一样比较第二个,还一样就比较第三个,如此类推,所以第三个结果为false,第四个为true。


function foo() { }
var oldName = foo.name;
foo.name = "bar";
[oldName, foo.name]
        
A. error
B. ["", ""]
C. ["foo", "foo"]
D. ["foo", "bar"]

解析:C
使用函数定义方式时,会给function对象本身添加一个name属性,保存了函数的名称,很好理解oldName为foo。name属性时只读的,不允许修改,所以foo.name = “bar”;之后,foo.name还是foo。


var a = {class: "Animal", name: 'Fido'};
a.class
        
A. "Animal"
B. Object
C. an error
D. other

解析:D
class是关键字。根据浏览器的不同,结果不同:

  • chrome的结果: “Animal”
  • Firefox的结果:“Animal”
  • Opera的结果:“Animal”
  • IE 8以上也是: “Animal”
  • IE 8 及以下: 报错

var min = Math.min(), max = Math.max()
min < max
        
A. true
B. false
C. error
D. other

解析:B

Math.min 不传参数返回 Infinity, Math.max 不传参数返回 -Infinity.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值