一、JS变量
1. JS 数据类型分类
1.1 值类型
- String
- Number
- Boolean
- null :空
- undefined : 未定义
- Symbol :唯一的
- BigInt : 任意精度的整数
- undefined 和 null 的区别
- undefined:定义了但没有赋值
- null:定义了且赋值为null
初始值赋值为null,表明现在数据不明,但将来会赋值为对象
结束时赋值为null:让对象成为垃圾对象,被垃圾回收器回收
1.2 引用类型(Object)
- Object
- function
- array
- Date
- RegExp
- null 也是特殊引用类型,指针指向空地址
/**
* obj:引用变量,即变量中存储的是引用(地址)
* 引用变量中存储的是对象所在空间的地址
*/
let obj = {
name:'哈哈'
}
- 基本类型的传递,是传递值
- 引用类型的传递,传递的是地址
2. typeof 运算符
- 用于检测变量的数据类型
- 可以检测所有的值类型
- 可以检测函数
- 可以判断是否是引用类型,但是不能判断具体类型
- 即
typeof不能判断 object与array、null与object
2.1 instanceof 运算符
- 原生JS判断实例类型
- 用于判断当前实例对象是不是某种数据类型
3. 深拷贝与浅拷贝
- 浅拷贝: 只克隆对象的“
表层
”,如果对象的某些属性值又是引用类型,则不克隆他们,只是传递他们的引用 - 深拷贝:
克隆对象的全貌
,不管是基本类型还是引用类型,都可以进行克隆;对象的深克隆也会使用递归
3.1 手写深拷贝
/**
* 深拷贝
* @param {obj} 要拷贝的对象,默认值为空对象
*/
function deepClone(obj = {
}) {
// 最终返回的结果,初始化为null,表示后期作为引用类型使用
let result
// 判断是数组还是对象,还是基本值类型
// typeof 只能判断出是引用类型,但是不能判断具体是数组还是对象,都会返回object
// Array.isArray()可以判断一个对象是否是数组,所以可以先判断数组,不是数组再判断是否是对象
if(Array.isArray(obj)) {
// 是数组类型,则将result初始化为数组
result = []
// 遍历数组
for(let i =0;i<obj.length;i++) {
// 先判断遍历结果的类型
// 然后将遍历结果添加到result中
result.push(deepClone(obj[i]))
}
}else if(typeof obj === 'object') {
// 是对象类型,将result初始化为对象
result = {
}
// 遍历对象
for(let key in obj) {
// 先判断遍历结果的类型,然后再添加到result中
result[key] = deepClone(obj[key])
}
}else {
// 是其他类型:null、基本类型
return obj
}
return result
}
// 测试
let person = {
name:'dudu',
age:19,
hobbies: ['eat','play-game',{
game:'贪吃蛇'
}]
}
let people = deepClone(person)
4. 类型转换转换的坑
4.1 字符串拼接
- 有字符串的运算,就会变成字符串拼接
- 在前后端交互时要注意判断
const a = 10 + 10 // 20
const b = 10 + '10' // '1010'
const c = true + '10' // 'true10'
4.2 ==运算符
- ===:称为
等同符
,当两边值的类型相同时,直接比较值,若类型不相同,直接返回false - == :称为
等值符
:当等号两边的类型相同时,直接比较值是否相等,若不相同,则先转化为类型相同的值,再进行比较
类型转换规则:
- 如果等号两边是boolean、string、number三者中任意两者进行比较时,优先转换为数字进行比较。
- 如果等号两边出现了null或undefined,null和undefined除了和自己相等,就彼此相等
注意:NaN==NaN //返回false NaN不等于任何值
除了判断是否等于 ==null 外,其他一律用 ===
4.3 if 语句和逻辑运算
- truly变量: !!a === true 的变量 ( 两次取反后为true )
- falsely 变量:!!a === false 的变量
falsely 变量:0、NaN、''、null、undefined、false
- 除以上falsely 变量之外都是 truly 变量
- if 语句用truly 变量 和 falsely变量进行判断
5. 相关面试题
- typeof 能判断哪些类型?
typeof 可以判断值类型和function类型
不可以判断 array 和 object 、null 和 object
- 何时用 ===,何时用 ==
除了 == null 之外,其他一律用 ===
二、原型和原型链
1. class继承
1.1 class的语法
class className {
// 构造函数
constructor() {
console.log('调用成功')
}
}
// 调用类
new className()
- class类名的首字母一般大写
class Student {
// 属性
constructor(name,studentId) {
this.name = name
this.studentId = studentId
}
// 方法
sayHi() {
console.log(
`hello,我是${
this.name},我的学号是${
this.studentId}`
)
}
study() {
console.log('我喜欢学习!!!')
}
}
// 实例化
const dudu = new Student('dudu',12542)
console.log(dudu.name)
dudu.sayHi()
dudu.study()
1.2 继承
- 实现继承的关键:子类拥有父类的
全部属性和方法
,同时子类还可以定义自己特有的属性和方法
- Class可以通过
extends
关键字实现继承 - 父类的静态方法可以被子类继承
- 继承父类的属性用
super
// 父类
class People {
constructor(name) {
this.name = name
}
// 方法
eat() {
console.log(
`我是${
this.name},我喜欢吃东西!!`
)
}
}
// 子类
class Student extends People {
constructor(name,studentId) {
super(name) // 继承父类的name
this.studentId = studentId
}
sayHi() {
console.log(
`你们好,我是${
this.name},我的学号是${
this.studentId}`
)
}
}
// 子类
class Teacher extends People{
constructor(name,major) {
super(name)
this.major = major
}
teach() {
console.log(`我是${
this.name}老师,我教的科目是${
this.major}`)
}
}
// 实例化
const dudu = new Student('dudu',12542)
dudu.eat()
dudu.sayHi()
// 实例化
const teacher = new Teacher('Lisa','英语')
teacher.teach(