值类型
字符串、数字、布尔、undefined、symbol
var a='abc' //字符串类型
var b=18 //数字
var c=true //布尔
var d //undefined
var e=Symbol('e') //symbol
引用类型
对象、数组、null
var obj={age:18} //对象
var arr=[1,2,3] //数组
var a=null //null 特殊引用类型,指向空地址
typeof运算符
用于判断值类型
var a='abc' typeof a // 'string'
var b=18 typeof b // 'number'
var c=true typeof c // 'boolean'
var d typeof d // 'undefined'
var e=Symbol('e') typeof e // 'symbol'
//判断函数
typeof console.log //'function'
typeof function (){} //'function'
//能识别引用类型(不能再继续识别,不会判断成null|数组|对象)
typeof null //'object'
typeof [1,2] //'object'
typeof {age:18} //'object'
注意
:typeof判断的结果为string
类型
例如:typeof typeof a //此时判断结果为'string'
浅拷贝
浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。
const obj1={
name:'张三',
age:18,
address:{
city:'beijing'
},
arr:[1,2,3,4]
}
const obj2=obj1
//修改obj2的name
obj2.name='李四'
console.log(obj1.name)//李四
consoel.log(obj2.name)//李四
使用浅拷贝拷贝的是引用值,当一个对象的值发生变化另一个对象的值也会发生变化
深拷贝
将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。
const obj1={
name:'张三',
age:18,
address:{
city:'beijing'
},
arr:[1,2,3,4]
}
const obj2=deepClone(obj1)
//修改obj2的name
obj2.name='李四'
console.log(obj1.name)//张三
consoel.log(obj2.name)//李四
/**
*深拷贝
*/
function deepClone(obj={}){
//如果obj不是对象或者null就直接返回该对象
if(typeof obj!=='object'|| 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
}
使用深拷贝拷贝的是对象的属性,所以不会发生修改一个对象的值另一个对象的值也会随之改变
==运算符
存在隐式类型转换
100 == '' //true
0 == '' //true
0 ==false //true
false == undefined //true
null == undefined //true
===运算符
不存在隐式类型转换
100 == '' //false
0 == '' //false
0 ==false //false
false == undefined //false
null == undefined //false
问题
typeof能判断哪些类型?
- 识别所有值类型
- 识别函数
- 判断是否是引用类型(不可再细分)
何时使用 === 何时使用 ==
除了 == null之外,其他一律使用=== 比如
const obj={x:100}
if(obj.a==null){}
//相当于
//if (obj.a===null|| obj.a===undefined)
值类型和引用类型的区别
- 存储位置不一样
值类型的变量会保存在栈内存中
引用类型的变量名会保存在堆内存中 - 复制方式不一样
值类型保存的是值
引用类型保存的是地址