10道JavaScript基础面试题,你能对几道(三)

165 阅读4分钟
第 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 题

防抖和节流的区别是什么?

防抖:规定一个时间间隔,前一次执行后的时间间隔内再次执行则会取消上一次的执行,依次类推,只执行最后一次

节流:规定一个时间间隔,在这个时间间隔内,执行多次同一事件,只会执行一次