前端面试题整理 - JS 基础篇
今天复习的是js基础相关的面试题,涵盖了变量类型、深拷贝、类型转换
问题1:值类型和引用类型的区别是什么?
问:什么是值类型?
值类型占用空间固定,保存在栈中
Tip: 当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了。
举例:
let a = 100
let b = a
a = 200
console.log(b)
// 输出:100
问:什么是引用类型?
引用变量存储在栈中的是指向堆中的数组或者对象的地址,修改引用类型总会影响到其他指向这个地址的引用变量。
let a = { age: 20 }
let b = a
b.age = 21
console.log(a.age)
// 输出:21
问:常见的值类型有哪些?
let a
const s = 'abc'
const n = 100
const b = true
const s = Symbol('s')
问:引用类型有哪些?
- 对象
- 数组
- 函数(特殊的引用类型)
问题2:typeof判断哪些类型?
typeof能识别出所有的值类型
、函数
以及引用类型
。
只判断到引用类型,引用类型下不再细分
,==它不能判断出null或者是数组或者是对象==
比如下面的图片:
问题3:如何手动实现深拷贝DeepClone()?
- 判断:对传入的参数进行判断,是数组或者对象(因为针对深拷贝的就是对象或者数组)
- 判断:如果传入的值是数组,定义result为[],否则定义result为{}
- 处理:for循环obj
- 判断:看一下每一个key是不是对象的自己的属性,而不是原型的属性。
- 处理:递归调用deepClone
- 结果:每次循环都返回递归的值,最终得到一个新的对象
深拷贝实现代码:
/**
* 深拷贝
* @param {Object} obj 要拷贝的对象
*/
function deepClone(obj = {}) {
if (typeof obj !== 'object' || obj == null) {
// obj 是 null ,或者不是对象和数组,直接返回
return obj
}
// 初始化返回结果
let result
if (obj instanceof Array) {
result = []
} else {
result = {}
}
for (let key in obj) {
// 保证 key 不是原型的属性
if (obj.hasOwnProperty(key)) {
// 递归调用!!!
result[key] = deepClone(obj[key])
}
}
// 返回结果
return result
}
问题4:类型转换的问题
问:字符串拼接有什么要注意的?
字符串和数字的拼接会变成字符串。
问:何时使用===,何时使用==
==
会尽量让两边转换之后相等。
记住一个规则,判断null
的时候用==
,其他的地方全部用===
if判断和逻辑运算相关
if运算判断的就是truely变量
和falsely变量
。
问:那么什么是truely变量和falsely变量?
答:两次取反,得到true,说明是true变量,否则就是false变量。例:
!!a === true
!!b === false
常见的falsely变量如下图:
上了上图的变量,其余的都是truely变量
最后上一道真题甜点
看下面的代码,执行输出的结果是什么?
1. const obj1 = {x: 100, y:200}
2. const obj2 = obj1
3. let x1 = obj1.x
4. obj2.x = 101
5. x1 = 102
6. console.log(obj1)
分析:
第二行把第一行的obj2赋值给obj1,这时候obj1和obj2指向同一个堆内存
。
第三行,把obj1.x赋值给x1,x1是一个值类型
,所以这是一个干扰项
,第5行的x1赋值并不会影响obj1和obj2.
第四行,改变obj2的x值,其实修改的同一个堆内存
的x,这样打印obj1的时候,输出的就是101
答案:101
转载自:https://juejin.cn/post/6977890638876540959