经典js基础题目及详解

423 阅读3分钟

写在前面,我是从老师视屏中学得,自己感受到坑蛮多的,然后写这篇文章,可以复习下印象更深,也希望更多人看到,能避免一些坑。

题目一

let result = 100 + true + 21.2 + null + undefined + "tencent" + [] + 9 + false;
console.log(result);
console.log([] == false);
console.log(![] == false);
  1. 基本数据类型:number、string、boolean、null、undefined、symbol、bigint
  2. 引用数据类型:object、function

解题:

  1. 其他类型会转换为number类型(对象先转换为string->number)
  • Number([val])
  • parseInt([val])、parseFloat([val])
  1. 隐式转换(浏览器内部默认先转换为number再进行计算的)
  • isNaN([val])
  • 在 ‘+’ 左右出现字符串视为字符串拼接,不是运算符。
  • ...
  1. 类型相同
  • {} == {} // false,因为对象比较是堆内存地址比较
  • [] == [] // false
  • NaN == NaN // false
  1. 类型不同
  • null == undefined // true null === undefined // false null、undefined和其他都不等
  • string == object ,要把对象转为字符串。
  • 其余先转为number类型在进行比较。

答案

let result = 100 + true(1) + 21.2 + null(0) + undefined(NaN) + "tencent" + []('') + 9 + false('false')
Number(undefined) // NaN
// NaNtencent9false

答案

console.log([] == false);
Number([]) // 0
false // 0
0 == 0 // true

console.log(![] == false);
// 运算符优先级更高,!非 结果boolean
![] // false
// false、false类型相同
false == false // true

题目二

let a = ?
if (a == 1 && a == 2 && a == 3) {
  console.log(1)
} 

解题

方式1

对象会隐式调用toString();

let a = {
  i: 0,
  toString() {
    return ++this.i;
  }
}

答案

方式2

方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。 MDN

let i = 0;
Object.defineProperty(window, 'a', {
 get() {
   return ++ i;
 }
})

题目三

let arr = [10.18, 0, 10, 25, 23];
arr = arr.map(parseInt);
console.log(arr);

解题

parseInt(string, radix) MDN

  • 解析一个字符串并返回指定基数的十进制整数, radix 是2-36之间的整数,表示被解析字符串的基数。
  • 如果 parseInt 遇到的字符不是指定 radix 参数中的数字,它将忽略该字符以及所有后续字符,并返回到该点为止已解析的整数值。 parseInt 将数字截断为整数值。 允许前导和尾随空格。

Array.prototype.map():

parseInt(10.18, 0); // radix会默认为10进制,所以答案是10
parseInt(0, 1); // 2-36 1不再其中返回NaN
parseInt(10, 2); // 2
parseInt(25, 3); // 5会被忽略 只解析2 所以答案是2
parseInt(23, 4); // 11
最终结果:[10, NaN, 2, 2, 11]

答案

题目四

let a = {n: 1};
let b = a;
a.x = a = {n: 2};
console.log(a.x);
console.log(b);

解题

我尽力画了,希望可以看懂。最终a指向{n: 2},b指向 {n: 1, x: {n: 2}}; 图解 答案

题目五

var a = 0;
if(true) {
 a = 1;
 function a() {};
 a = 21;
 console.log(a);
}
console.log(a);

这个题完全摸不着头脑,我把概念写下。

  • 变量提升:当前上下文的执行之前,会把var/function声明或者定义,带有var只声明,带有function声明家定义,如果遇到{},新老版本表现不一致(兼容ES3\ES6)
  • IE浏览器 <= IE10,不管有没有{},统一声明+定义,也不存在块级作用域。
  • 新版浏览器
    • {}中的function,在全局只声明不定义。
    • {}中出现function/let/const会创建一个块级上下文。 遇到function a(){}这行代码,为了兼容ES3/ES6会把代码之前所有对于a的操作映射给全局一份,后面的则不会再处理,形成块级作用域,认为是私有。大家可以在浏览器调试看看scope变化 答案