第 1 题
console.log([] == false);
console.log({} == false);
console.log(typeof null);
//输出
true
false
object
解析: “==”运算符(两个操作数的类型不相同时)
- 如果一个值是null,另一个是undefined, 则他们相等
- 如果一个是number,另一个是string,则先将string转换成number在进行计算
- 如果一个是true, 则将其转换成1在进行计算,如果是false,则转换成0再计算
- 如果一个值是object,另一个是number或者object,则将object转换成原始值再进行比较
object到number的转换
- 如果该object具有valueOf()方法,则调用valueOf()后,再将原始值转换成number后返回
- 否则,如果该object具有toString()方法,则调用toString()后得一个原始值,再将原始值转换成number后返回
- 否则,JavaScript抛出一个类型错误异常
1、数组继承了默认的 valueOf() 方法,这个方法返回一个对象而不是一个原始值,因此,数组到number的转换则调用 toString() 方法。空数组转换为空字符串,空字符串转换为数字0. false转换未number也是0,所以 console.log([] == false) 输出true
2、Number({}.toString()) 返回的是NaN, false 转换为number是0, NaN != 0,所以输出为false
3、js 在底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息 000:对象 010:浮点数 100:字符串 110:布尔 1:整数
但是, 对于 undefined 和 null 来说,这两个值的信息存储是有点特殊的。 null:所有机器码均为0 undefined:用 −2^30 整数来表示 所以,typeof 在判断 null 的时候就出现问题了,由于 null 的所有机器码均为0,因此直接被当做了对象来看待。
第 2 题
var a = false.toString();
var aType = typeof a;
console.log(a);
console.log(aType);
//输出
'false'
'string'
console.log([1, 2, 3].toString());
//输出
'1,2,3'
console.log(1.toString());
//输出
Uncaught SyntaxError: Invalid or unexpected token
console.log(5..toString());
//输出
'5'
解析:当执行1.toString() 的时候,由于1.也是数字,所以此时变成(1.)toString(), 没有用到.调用到toString方法。
正确的写法可以是
1..toString()
1 .toString()
(1).toString()
第3 题
[1,1,2,3,5,47,8,8] 去重
//解析
//方法一
let temps = [1,1,2,3,5,47,8,8]
console.log([...new Set(temps)])
// [1, 2, 3, 5, 47, 8]
//方法二
let temps = [1,1,2,3,5,47,8,8]
console.log(Array.from(new Set(temps)))
// [1, 2, 3, 5, 47, 8]
第 4 题
var a = 666;
console.log(++a);
console.log(a++);
console.log(a);
//输出
667
667
668
解析: ++a 先执行+1操作,在执行取值操作, a++ 先执行取值操作,在执行+1操作
注意: ++ -- 这类操作符不能用于常量, 会抛出错误
console.log(1++)
//输出
Uncaught SyntaxError: Invalid left-hand side expression in postfix operation
如果a不是number类型,则会先进行Number(a)转换后再计算。
第 5 题
var x = 1;
if (function f() {}) {
x += typeof f;
}
console.log(x);
//输出
'1undefined'
解析: function f() {}作为判断条件的时候,音质转换成true, 但是并不会变量提升,因此函数f在外面时不存在的,所以,typeof f 是undefined, x += typeof f 其实就是 x = x + 'undefined'
第 6 题
console.log(x)
var x = 1
function x() {}
//输出
function x() {}
第 7 题
普通函数和箭头函数的区别是什么?
1:普通函数有this,箭头函数不会创建自己的this, this继承外部作用域的this,而且继承而来的this指向永远不变, .call()/.apply()/.bind()无法改变箭头函数中this的指向
2:箭头函数没有arguments这个内置对象
3:箭头函数不能作为构造函数使用
4:箭头函数没有原型prototype
let f1 = () => {
console.log('Hello World !')
};
console.log(f1.prototype);
// undefined
5:箭头函数不能用作Generator函数,不能使用yeild关键字
6:写法区别
const f11 = name => `我得名字叫${name}` ;
const f12 = (num1, num2) => num1 + num2 ;
const f13 = (name, age) => {
return `我得名字叫${name}, 年龄是${age}`;
}
const f14 = () => void doesNotReturn();
const doesNotReturn = () => {
console.log("doesNotReturn!")
}
const f3 = function(name, age){
return `我得名字叫${name}, 年龄是${age}`;
}
箭头函数有个明显得优势在于,可以简化回调函数
// 例子一
// 正常函数写法
[1,2,3].map(function (x) {
return x * x;
});
// 箭头函数写法
[1,2,3].map(x => x * x);
// 例子二
// 正常函数写法
var result = [2, 5, 1, 4, 3].sort(function (a, b) {
return a - b;
});
// 箭头函数写法
var result = [2, 5, 1, 4, 3].sort((a, b) => a - b);
第 8 题
var str = '123abc';
console.log(typeof str++);
//输出
'number'
解析: 使用++运算符时(不管是前置还是后置),如果变量不是number类型,都会先进行Number(str)转换,这里Number('122abc')转换的结果是NaN, NaN + 1: NaN 跟数字相加的结果还是NaN, NaN 为不是数字的数字,类型是number
第 9 题
const promise = new Promise((resolve, reject) => {
reject('error');
resolve('success1');
resolve('success2');
});
promise
.then((res) => {
console.log('then: ', res);
})
.catch((err) => {
console.log('catch: ', err);
});
//输出
catch: error
const promise = new Promise((resolve, reject) => {
resolve('success1');
resolve('success2');
reject('error');
});
promise
.then((res) => {
console.log('then: ', res);
})
.catch((err) => {
console.log('catch: ', err);
});
//输出
then: success1
第 10 题
防抖和节流的区别是什么?
防抖:规定一个时间间隔,前一次执行后的时间间隔内再次执行则会取消上一次的执行,依次类推,只执行最后一次
节流:规定一个时间间隔,在这个时间间隔内,执行多次同一事件,只会执行一次