1、
console.log(["1", "2", "3"].map(parseInt)); //答案 //[1, NaN, NaN]
parseInt(string, radix)函数可解析一个字符串,并返回一个整数。
当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。
举例:
如果 string 以 "0x" 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。
如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。
如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。
如果想让 parseInt(string, radix) 返回 NaN,有两种情况:
1>第一个参数不能转换成数字。
2>第二个参数不在 2 到 36 之间。
我们重新定义 parseInt(string,radix) 函数来观察参数的个数导致输出的结果:(这一段属于他人想法)
1>当给parseInt传2个参数的时候:
var parseInt = function (string, radix) { return string + "-" + radix; };
["1", "2", "3"].map(parseInt);
输出结果为:
["1-0", "2-1", "3-2"]
2 > 当给parseInt传3个参数的时候:
var parseInt = function (string, radix, obj) { return string + "-" + radix + "-" + obj; };
["1", "2", "3"].map(parseInt);
输出结果:
["1-0-1,2,3", "2-1-1,2,3", "3-2-1,2,3"]
3 > 当给parseInt传4个参数的时候:
var parseInt = function (string, radix, obj, other) { return string + "-" + radix + "-" + obj + "-" + other; }; ["1", "2", "3"].map(parseInt);
结果:
["1-0-1,2,3-undefined", "2-1-1,2,3-undefined", "3-2-1,2,3-undefined"] map给parseInt传递了三个值:数组每一项,数组每一项的索引,数组本身;在这个题目里相当于每循环一次就执行一次parseInt, parseInt(1, 0, [1, 2, 3]);//第二位参数为0,默认是十进制,所以结果是1. parseInt(2, 1, [1, 2, 3]);//第二位参数为1,正好不在2到36之内,所以是NaN. parseInt(3, 2, [1, 2, 3]);//第二位参数为2,假如说是二进制,那么第一位参数只能出现1和0,但是它却是3,所以是NaN;或者按照第一位参数是3,那么第二位参数就可代表3以上的进制,但是它却是2,所以是NaN.比如parseInt(4,3);结果也是NaN,
2、
[typeof null, null instanceof Object]
答案
["object", false]
3、
[[3, 2, 1].reduce(Math.pow), [].reduce(Math.pow)]
答案
报错
Array.reduce方法接收四个值:
previousValu 上一次值
currentValue 当前值
currentIndex 当前值的索引
array 数组
Math.pow方法接收两个参数,
底数
幂数
所以[3, 2, 1].reduce(Math.pow)的值应该是9 ,第一次Math.pow(3,2)等于9,第二次Math.pow(9,1)等于9,至于最后一个[].reduce(Math.pow)应该数组为空,所以无法计算。
4、
var val = 'value'; console.log('Value id ' + (val === 'value') ? 'Something' : 'Nothing'); console.log('Value id ' + (val === 'value111') ? 'Something' : 'Nothing');
console.info('Value id '+(val === 'value')?'Something':'Nothing');
//'Value id '+(val === 'value')这个得到的是'Value id true'这个再转成Boolean是true啊,是true肯定是something啊。同理下面那个是'Value id false'这个也是true啊。那么肯定还是something。这个三元运算符的意思是,如果前面的值为真,那么就执行?后面的语句,
否则执行:后面的语句。你要把三元写在一起,+号的优先级高于三元运算符,低于小括号的优先级。
5、
var name = 'World'; (function () { console.log(name); //undefined if (typeof name === 'undefined') { var name = "Jack"; console.info('Goodbye ' + name); } else { console.info('Hello ' + name); } })(); var name = 'World'; (function () { console.log(name); //World why????????????? typeof name; })();
答案:Goodbye Jack
自执行函数里是私有作用域,所以 var name = "Jack"; 会将name提到作用域顶端,先赋值为undefined,所以才会输出Goodbye Jack,如果将var name= "Jack"; 改成 name= "Jack"
那么输出为Hello world
6、
var END = Math.pow(2, 53); var START = END - 100; var count = 0; console.log(START); console.log(END); for (var i = START ; i <= END ; i++) { console.log(count); count++; } console.log(count);
答案
程序会陷入死循环
这道题考的是JavaScript数字范围的题。在JavaScript中,只有一种数字:IEEE 754标准的64位浮点数,范围是-2^53~2^53(包含边界值),所以Math.pow(2, 53)即为javascript中所能表示的最大整数,在最大整数在继续增大就会出现精度丢失的情况,
END + 1 的值其实是等于END的,题中当START=END的时候,继续执行,但当下一次 START继续加1的时候,因为超出了边界,所以变为恒等,造成了死循环。
所以可以把for循环中的i <= END变为 i < END即可输出正确。
7、
var ary = [0, 1, 2]; ary[10] = 10; console.log(ary.filter(function (x) { return x === undefined; })); console.log(ary[4]); //undefined
答案
[]
给ary数组第10个位置赋值为10的话,那么其中断开的位置实际上是用undefined补齐的。
在Array.filter方法中,会对未赋值的或已经删除的项进行调用,所以返回空数组。
8、
var two = 0.2; var one = 0.1; var eight = 0.8; var six = 0.6; console.log([two - one == one, eight - six == two]);
答案
[true,false]
js浮点数运算时,会将10进制转换为2进制运算,这会导致精度丢失的问题,例如0.8-0.6时,所得到的是0.20000000000000007。
9、
function showCase(value) { console.log(value);//String {0: "A", length: 1, [[PrimitiveValue]]: "A"} switch (value) { case 'A': console.info('Case A'); break; case 'B': console.info('Case B'); break; case undefined: console.info('undefined'); break; default: console.info('Do not know!'); } } showCase(new String('A'));
答案
Do not konw!
当使用new 时,创建的是string对象,而非原始的string字符串
JS本身有原始字符串和字符串对象之分,只不过在调用方法和获取属性时的时候会自动转换,但typeof运算符运算时是不会转换的。Number和Boolean同样适用
当String('A')时,创建的就是原始的字符串了。
10、
console.log(Array.isArray(Array.prototype));
答案
true
11、
var a = [0]; console.log([0]); if ([0]) { console.info(a == true); } else { console.info("else"); }
答案
false
a本身是一个长度为1的数组,而当数组不为空时,其转换成bool值为true。
而==左右的转换,会使用如果一个操作值为布尔值,则在比较之前先将其转换为数值的规则来转换,Number([0]),也就是0,于是变成了0 == true,结果自然是false,
12、
console.log([] == []);
答案
false
这题考的是数组字面量创建数组的原理和==运算符,首先JS中数组的真实类型是Object这点很明显typeof []的值为"object",而==运算符当左右都是对象时,则会比较其是否指向同一个对象。而每次调用字面量创建,都会创造新的对象,也就是会开辟新的内存区域。所以指针的值自然不一样,结果为 false
13、
console.log([('5' + 3), ('5' - 3)]);
答案
["53", 2]
加法: 加法运算中,如果有一个操作值为字符串类型,则将另一个操作值转换为字符串,最后连接起来
减法: 如果操作值之一不是数值,则被隐式调用Number()函数进行转换
14、
var ary = Array(3); ary[0] = 2 ary=ary.map(function (elem) { return '1'; }); console.log(ary);
答案
["1"]
map在使用的时候,只有数组中被初始化过元素才会被触发,其他都是undefined,所以结果为["1"]
15、
function sidEffecting(arr) { arr[0] = arr[2]; } function bar(a, b, c) { c = 10;//向函数传递参数时,arguments数组中的对应单元会和命名参数建立关联,以得到相同的值,相反,不传递参数就不会建立关联。 console.log(arguments[2]); sidEffecting(arguments); return a + b + c; }
console.log(bar(1, 1, 1));
答案
21
arguments 对象其实是一个类数组对象,里面有length属性和索引1、2、等等属性,所以,这里传入arguments其实传入的是一个对象,将引用传入,从而会影响当前函数内部的值。
补充:
function a() { var arr = [1]; b(arr); return arr; } function b(a) { a = [2]; } console.log(a()); //[1] function c() { var arr = {name:"aa"}; d(arr); return arr; } function d(a) { a.name="bb"; } console.log(c()); //Object {name: "bb"}
当参数为数组时,会建立一个副本,而对象时,则会将引用传入。
16、
var a = 111111111111111110000; b = 1; console.info(a + 1);
答案
111111111111111110000
a已经超出js整数范围边界。所以会发生精度丢失的问题。
17、
var x = [].reverse; console.log(x());
答案
报错
var arr = new Array(3) arr[0] = "George" arr[1] = "John" arr[2] = "Thomas" document.write(arr + "<br />") document.write(arr.reverse())
18、
console.log(Number.MIN_VALUE > 0);
答案
true
19、
console.log([1 < 2 < 3, 3 < 2 < 1]);
答案
[true, true]
比较时会根据优先级从左至右进行比较,所以转换为 [true<3,false<1] ,又在比较时,如果有数字,则将操作数进行number转换,所以其实比较的是[1<3,0<1]
20、
console.log(2 == [[[2]]]);
答案
true
隐式转换,会将[[[2]]]转换为"2",然后进行数字和字符串进行比较,再讲字符串用number方法转换为数字,所以为true。
21、
console.log(3.toString()); console.log(3..toString()); console.log(3...toString());
答案
error 3 error
数字进行tostring时,需要填写两个.,因为数字类型无法区分是小数点还是方法调用的点。所以第一个会报错,第二个调用,第一个.是数字的小数点,第二个是方法调用的.,所以是正确的,第三个多了一个点。
22、
(function () { var x1 = y1 = 1; })();
console.info(y1);
console.info(x1);
答案
1 x1 is not defined
自执行函数中的作用域是私有的,当执行完成之后会将内部的变量释放。
然而题中的y1其实是 y1=1 前面并没有var,所以在执行的时候,编译器会进行处理,如果从未声明,那么会创建一个全局变量进行存放。
23、
var a = Function.length; var b = new Function().length; console.log(a);//1 console.log(b);//0 console.log(a === b);
答案
false
24、
var a = Date(0); var b = new Date(0); var c = new Date(); console.log(a); console.log(b); console.log(c); console.log([a === b, b === c, a === c]);
答案
[false, false, false]
var d1 = Date(); //返回一个字符串(string),没有getDate等日期对象方法,内容为当前时间 var d2 = new Date(); //返回一日期对象,可以调用getDate(),内容为当前时间 var d3 = Date("2000-1-1");//返回一个字符串(string),内容仍旧为当前时间,也就是不受参数影响 var d4 = new Date("2000-1-1");//返回一日期对象,可以调用getDate(),内容为2000年元旦
25、
var min = Math.min(); var max = Math.max(); console.log(min);//Infinity console.log(max);//-Infinity console.log(min < max);
答案
false
Math.min()和Math.max()是两个比较函数,并不是返回最大最小值的函数,文档上进行了说明,如果传入参数的个数为0,那么Math.min()返回Infinity,而Math.max()返回-Infinity
26、
var a = new Date("2014-03-19"); var b = new Date(2014, 03, 19); console.log(a);//2014/3/19 上午8:00:00 console.log(b);//2014/4/19 上午12:00:00 console.log([a.getDay() === b.getDay(), a.getMonth() === b.getMonth()]);
答案
false
27、
function foo(a) { var a; return a; } function bar(a) { var a = 'bye'; return a; } console.log([foo('hello'), bar('hello')]);
答案
["hello", "bye"]
当内部变量和参数同名时,js会自动进行对应。
28、
var a = { class: "Animal", name: 'Fido' }; console.log(a.class);
答案
Animal
class是关键字。根据浏览器的不同,结果不同
29、
var a = /123/; var b = /123/; console.log(a == b); console.log(a === b);
答案
false
false
30、
var a = [1, 2, 3], b = [1, 2, 3], c = [1, 2, 4] console.log(a == b); console.log(a === b); console.log(a > c); console.log(a < c);
答案
false false false true
JavaScript中Array的'>'运算符和'<'运算符的比较方式类似于字符串比较字典序,会从第一个元素开始进行比较,如果一样比较第二个,还一样就比较第三个,如此类推,所以第三个结果为false,第四个为true。
31、
var a = {}, b = Object.prototype; console.log([a.prototype === b, Object.getPrototypeOf(a) === b]);
答案
[false, true]
32、
function foo() { } var oldName = foo.name; foo.name = "bar"; console.log([oldName, foo.name]);
答案
["foo", "foo"]
函数的name属性,使用函数定义方式时,会给function对象本身添加一个name属性,保存了函数的名称,很好理解oldName为"foo"。name属性时只读的,不允许修改,所以foo.name = "bar";之后,foo.name还是"foo",所以结果为["foo", "foo"]
33、
function aaa(a, b, c) { c = 3; console.log(arguments[0] + 'arguments[0]'); console.log(arguments[1] + 'arguments[1]'); console.log(arguments[2] + 'arguments[2]'); } aaa('a', 'b');
答案
a,b,undefind
如果参数没有传递,那么arguments与参数变量是不会绑定的,所以即使重新赋值,(实际是在作用域中新建了一个变量)arguments也会为undefined。
如果传递了这个参数变量,那么会自动进行绑定,所以无论对哪个进行改变,都会一起变化。
34、
36 var foo = { baz: 1, bar: function () { return this.baz; } // }; //var baz=2; (function () { //var baz=3; console.log(arguments[0]()); })(foo.bar); (function () { console.log(arguments[0].call(foo)); })(foo.bar)
答案
undefind 1
第一个自执行函数,其实是将foo.bar方法的引用传递进去,所以在方法调用的时候,其实是没有上下文的,this其实指向的Windows,即使在自执行函数中,声明了baz,也是在自执行内部的作用域,而不是window。
第二个自执行函数,通过用call方法强行指定了bar方法的this为foo对象,所以结果会为1.