总结步骤
- 题目
- 知识点
- 解答
变量类型和计算
- ECMAScript 有
5种基本数据类型
和1种复杂数据类型
,和ES2015(就是ES6)新增的symbol 基本数据类型
,共7种
。 -
前5种基本数据类型
包括Undefined
,Null
,Boolean
,String
,Number
。 -
1种复杂数据类型
就是Object
题目
- typeof 能判断哪些类型?
- 何时使用
===
何时使用==
? - 值类型和引用类型的区别?
- 手写深拷贝
知识点
1.数据类型
就是上边总结的7种(6种基本数据类型和1种复杂数据类型)
。
1.1这些数据按照存储方式区分,可分为值类型
和引用类型
。
- 值类型 :
Undefined
,Boolean
,String
,Number
,symbol
- 引用类型:
Object
,Array
,Function
(Null
属于特殊引用类型)
1.2 值类型
和引用类型
的区别
- 存储位置不同
a:值类型存贮在
栈内存
中,如果一个函数中声明了一个值类型的变量,那么当函数执行完后,这个变量会自动销毁
;
b:引用类型的变量会保存在栈内存
中,但是变量值会存贮在堆内存
中,引用类型的变量不会自动销毁,当没有引用变量引用它时,系统的垃圾回收机制
会回收它
- 复制方式不同
a: 值类型的直接赋值就是
深复制
b: 引用类型的直接赋值实际上传递引用
,就是浅复制
c: 之所以会采用不同的复制方式,是出于性能方面的考虑,因为值类型占用空间比较少,复制的时候对性能影响不大,而引用类型可能会占用比较大的空间,直接赋值可能会耗时较长,影响性能
- 值类型无法添加属性和方法
- 引用类型可以添加属性和方法
- 值类型的比较是值的比较,只有当他们的值相等的时候才相等;注意比较
===
和==
的区别,==
双等比较的时候做了类型转换,===
全等是值和类型都相同了才相等。 - 引用类型的比较是引用地址的比较
// 值类型
let a = 100;
let b = a;
console.log(b); //100
a = 200;
console.log(b); // 100
// 引用类型
let a = {age:20};
let b = a;
console.log(b.age) // 20
b.age = 30;
console.log(a.age) // 30
// 引用类型的比较
// 两个空对象在堆内存中的地址不一样,所以即使两个一模一样的对象也不一定相等
let a ={}
let b = {}
a === b //false
2.typeof 运算符
- 识别所有的值类型
- 识别函数
- 判断是否是引用类型(不可再细分)
typeof 'abc' // string
typeof 100 // number
typeof undefined // undefined
typeof true // boolean
typeof function(){} // function
typeof console.log // function
typeof null //object
typeof {} // object
typeof [1,2,3] // object
let a = Symbol('a')
typeof a //symbol
也就是说,除了值类型和函数外,其他引用类型通过typeof判断都是object,如果我们想进一步知道,具体是对象,还是数组,还是null,通过typeof是不行的。
3.深拷贝
为了对比先看下 浅拷贝
// 函数的注释,以vscode为例子 一个斜杠/加两个星号回车就可以了 /** enter
const obj1 = {
name: '灰太狼',
age: 30,
say() {
console.log(this.name)
},
address: {
city:'hangzhou'
},
arr:['a','b','c']
}
const obj2 = obj1
obj2.address.city = 'shaoxing'
console.log(obj1.address.city) //shaoxing
下边是深拷贝
/**
*
* @param {Object} obj 要拷贝的对象
*/
function (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
}
const obj2 = deepClone(obj1)
obj2.address.city = 'shaoxing'
console.log(obj1.address.city) // hangzhou
深拷贝3个关键点
- 判断引用类型和值类型,如果是值类型或是null直接返回
- 判断是数组还是对象,初始化返回对象或数组
- 遍历要深拷贝的对象或数组,然后判断属性是否是原型属性,不是原型属性才遍历,然后递归
网友评论