web 面试题总结和解析
web 面试题总结和解析
第一题
console.log('123'+1+7) --> 12317
console.log(1+'123'+7) --> 11237
console.log(1+7+'123') --> 8123
解析:
这道题真的有点脑残,但是我还是打错了,因为基本平时不注意。
其实很简单,看位置,如果最开始是字符串那就是连接,如果是数字那就是计算。
第二题
var val = 12;
function fun1(){
console. log(val);
var val = 20;
console.log(val);
}
fun1();
输出结果是什么?
解析:输出Undefined 和 20
解题思路:
考点:一、函数内部作用域、二、变量提升
首先函数内部使用var声明了一个局部变量val
,但是val
并没有在这个局部变量中声明过,所以JavaScript 会在最前面加上var val
,这就是变量提升。
实际上代码在运行的时候是这样的:
var val;
console. log(val);
val = 20;
console.log(val);
详细解析:函数中声明变量的时候,实际在函数中先执行var val
,意思就是var 在一个作用域中设置时,JavaScript 实际会默认标准语法先做声明,即先var val
。为什么会这样呢?这是因为JavaScript是弱性语言,很多东西是编辑器自己完成的,它不同于强行语言,例如java、ts等,但是这个流程还是要走的,因此当你人为的这样写的时候,其实际编辑器不是这样解析的,它会首先去做声明,即所谓的变量提升,所以如果是大型项目还是要使用TS来写,因为这样可以降低BUG的产生。
延伸题:
var val = 12;
function fun1(){
console. log(val);
val = 5;
console.log(window.val);
var val = 20;
console.log(val);
}
fun1();
理解了上面的例子那这个就很简单了,答案是Undefined、12、20
。是不是超简单(* ̄︶ ̄)。
至于为什么没有5
那就得自己想一下了哈哈(* ̄︶ ̄)。
再延伸一点:
假如注销掉var val = 20
呢?
var val = 12;
function fun1(){
console. log(val);
val = 5;
console.log(window.val);
// var val = 20;
console.log(val);
}
fun1();
那结果就会是12 5 5
。所以关键就在于var val
的位置,更直白一点就是,当前作用域是否声明了变量。
第三题
<script>
console.log([] == null); // false
console.log(Boolean([])); // true
console.log(![]); // false
console.log(![] == ![]); // true
console.log([] == []); // false
</script>
解题思路:
js中基本数据类型和引用数据类型
基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配
(Undefined / Null / Boolean / Number / String),直接按值存放,可以直接访问
引用类型:存放在堆内存中的对象;每个空间大小不一样,根据情况进行特定的分配
(对象 / 数组 / 函数) ,先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据
所以,
(1)空数组[]
实际是一个指针,即[] == null
为false
(2)判断console.log(Boolean([]))
的时候,首先要明白真值(truthy)的含义除被定义为falsy的所有值,叫真值。
哪那些是假值呢?
类型 | 内容 |
---|---|
空字符串 | false |
undefined | false |
null | false |
布尔值 | false |
数字 | 0 和NaN |
对象(数组、对象) | 都为真值(但打印时为[] 或者 {} ) |
分清了什么是真值,什么是假值以后就只需要知道Boolean(val)
是什么了。Boolean(val)
是一个转换函数,将val转成布尔值,而[]
本身为真值
,所以Boolean(val)
就是true
,所以console.log(Boolean([]))
输出true
。
(3)console.log(![]);
这里的!
有强转功效,可以将值转化为相反的布尔值 ,因此输出为false
(4)console.log(![] == ![]);
原理一样,先被转Boolean值,然后都是false
,因此输出true
(5)console.log([] == []);
里面的[]
是一个堆的指针指向的不同位置,所以不会是相等的,因此是false