原始类型存储的都是值
boolean
null
undefined
number
string
symbol
对象类型存储的是地址(指针)
将变量赋值给另外一个变量时,复制的是原本变量的地址(指针),也就导致了两个变量的值都发生了改变。
typeof 对于原始类型来说,除了 null 都可以显示正确的类型
typeof 对于对象来说,除了函数都会显示 object
判断一个对象的正确类型,这时候可以考虑使用 instanceof,因为内部机制是通过原型链来判断的
instanceof 判断类型也不是完全准确的。
延申:
number问题:0.1+0.2!=0.3
0.1二进制表示:末尾是0011循环,裁剪后,末尾只剩002
JS 采用的浮点数标准却会裁剪掉二进制里循环的数字,出现精度丢失
解决:
parseFloat((0.1 + 0.2).toFixed(10)) === 0.3 // true
把 Number 四舍五入为指定小数位数的数字
[1,2,3,4,5,5].splice(1,2,4)
(2) [2, 3]
let c=[1,2,3,4,5,5]
undefined
c.splice(1,2,4)//splice(删除起始位置,删除多少项,插入哪些项)
(2) [2, 3]
c
(5) [1, 4, 4, 5, 5]
接口数据去重:
let result= [
{id:'2323'}, {id:'23233'}, {id:'2323'}
]
//forEach splice
let resultClone=[]
result.forEach(item=> {
let index=resultClone.indexOf(item.id)
if(index ===-1){
resultClone.push(item.id)
}
})
浅拷贝
实现方式一:
let a=[1,2,3,4]
let b=[...a]
a.splice(0,1)
b
(4) [1, 2, 3, 4]
a
(3) [2, 3, 4]
b
(4) [1, 2, 3, 4]
对象扩展运算符...可以实现第一层级的拷贝(此处指:只拷贝值,不拷贝地址指针)
let aa={
name:'dfd',
person:{
age:23
}
}
undefined
let bb={...aa}
undefined
aa.name='qgz'//可以实现第一层级的拷贝
"qgz"
bb
{name: "dfd", person: {…}}
let a=[
{
name:'dfd',
person:{
age:23
}
}
]
let b=[...a]
a[0]={}
b
0: {name: "qgz", person: {…}}
length: 1
__proto__: Array(0)
a[0].name='qgz' //此处修改的是第二层,所以:
b
[{…}]0: {name: "qgz", person: {…}}length: 1__proto__: Array(0)
...底层实现:
class Student{
constructor(name, age) {
this.name=name;
this.age=age;
}
}
Student.prototype.Objectvalues = function () {
var buffer = [];
console.log(this)//Student{name: "小刚", age: 18}
for(key in this) {
buffer.push(this[key]);
}
return buffer;
}
var stu = new Student("小刚",18);
let keys = stu.Objectvalues();
keys
let aa=Object.values(stu)
aa
(2) ["小刚", 18]
进入正题:
深拷贝:
function deepClone(obj) {
function isObject(o){
return(typeof o ==='object' || typeof o ==='function')&& o!=null
}
if(!isObject(obj)){
throw new Error('非对象')
}
//...浅拷贝第一层,如果直接: let cloneValue =obj 导致所有层级都拷贝地址指针
let cloneValue = Array.isArray(obj)?[...obj]:{...obj}
//静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。
Object.keys(obj).forEach(function (key) {
cloneValue[key]=isObject(obj[key])?deepClone(obj[key]):obj[key]
})
return cloneValue
}