一.浅拷贝
拷贝的是地址
1.拷贝对象:Object.assgin() / 展开运算符**{ ...obj }**拷贝对象
2.拷贝数组:Array.prototype.concat() 或者** ...arr **
javascript
<body>
<script>
const obj = {
name:'张三',
age:18,
}
console.log(obj);
// 使用对象的引用类型特性,修改a,也会修改obj的属性
const a = obj
a.name = '李四'
console.log(a);
console.log(obj);
</script>
</body>

javascript
<body>
<script>
const obj = {
name:'张三',
age:18,
}
console.log(obj);
// 使用对象的浅拷贝方法,不会改变原对象的属性值
const a = { ...obj }
a.age = 20
console.log(a);
console.log(obj);
</script>
</body>

javascript
<body>
<script>
const obj = {
name:'张三',
age:18,
}
console.log(obj);
// 浅拷贝第二种方法
const a = {}
Object.assign(a, obj)
a.age = 20
console.log(a);
console.log(obj);
</script>
</body>

如果是简单数据类型拷贝值,引用数据类型拷贝的是地址
简单理解:如果是单层对象,没问题,如果有多层就有问题
javascript
<body>
<script>
const obj = {
name:'张三',
age:18,
family : {
name:'李四'
}
}
console.log(obj);
const a = {}
Object.assign(a, obj)
a.family.name = '王五'
console.log(a);
console.log(obj);
</script>
</body>

直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对象栈里面的地址
浅拷贝如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响
二.深拷贝
拷贝的是对象,不是地址
1.通过递归函数实现深拷贝
2.lodash/cloneDeep
3.通过**JSON.stringify()**实现
通过递归函数实现深拷贝:
javascript
<body>
<script>
const obj = {
name:'张三',
age:18,
habby:['篮球','足球']
}
const a = {}
function deepCopy(newObj, oldObj){
for(let key in oldObj){
// 处理数组问题
if(oldObj[key] instanceof Array){
newObj[key] = []
deepCopy(newObj[key], oldObj[key])
}else{
newObj[key] = oldObj[key]
}
// console.log(key); //属性名 name age
// console.log(oldObj[key]); //属性值 张三 18
}
}
deepCopy(a, obj)
a.habby.push('跑步')
console.log(a);
console.log(obj);
</script>
</body>

js库lodash里面cloneDeep内部实现了深拷贝:
使用npm安装:

javascript
<body>
// 引入lodash库
<script src="./node_modules/lodash/lodash.min.js"></script>
<script>
const obj = {
name:'张三',
age:18,
habby:['篮球','足球'],
family:{
name:'李四'
}
}
const a = _.cloneDeep(obj)
a.family.name = '王五'
console.log(a);
console.log(obj);
</script>
</body>

通过JSON.stringify()实现深拷贝:
javascript
<body>
<script>
const obj = {
name:'张三',
age:18,
habby:['篮球','足球'],
family:{
name:'李四'
}
}
// 把对象转换成JSON字符串,再转换成对象
const a = JSON.parse(JSON.stringify(obj))
a.family.name = '王五'
console.log(a);
console.log(obj);
</script>
</body>

三.递归函数
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数(函数内部自己调用自己)
递归函数的作用和循环效果类似
由于递归很容易发生"栈溢出"错误(stack overflow),所以必须要加退出条件return
javascript
<body>
<script>
let i = 1
function fn(){
console.log(`这是第${i}次`);
if(i >= 6){
return
}
i++
fn()
}
fn()
</script>
</body>

案例:利用递归函数实现setTimeout模拟setinterval效果,页面每隔一秒输出当前的时间
javascript
<body>
<div></div>
<script>
function getTime(){
document.querySelector('div').innerHTML = new Date().toLocaleString()
setTimeout(getTime, 1000)
}
getTime()
</script>
</body>
