JavaScript深浅拷贝

深浅拷贝

浅拷贝

首先浅拷贝和深拷贝只针对引用类型
浅拷贝:拷贝的是地址
常见方法:

  1. 拷贝对象**:Object.assgin() **/ 展开运算符 {…obj} 拷贝对象
  2. 拷贝数组**:Array.prototype.concat() **或者 […arr]
    

    <script>

        const o = {
            name:"小明",
            age:20,
            denger:"男",
            famliy:{
                mother:"小明妈妈"
            }
        }
//      方法一
        // const red = {...o
        // }
        // console.log(o); // 下面的o.name更改的就是原来的对象;不影响red
        // o.name = "red";
        // console.log(red);
        // 方法二
        const red = {

        }
        Object.assign(red, o);
        console.log(red);
        red.name = "red"
        red.famliy.mother = "red mother"
        console.log(red);
        console.log(o);
    </script>

屏幕截图(1).png

更改对象里面的方法属性会出现影响;所有对象的方法里的属性都改变了。

如果是简单数据类型拷贝值,**引用数据类型拷贝的是地址 **(简单理解: 如果是单层对象,没问题,如果有多层就有问题)

深拷贝

深拷贝:拷贝的是对象,不是地址
常见方法:

  1. 通过递归实现深拷贝
  2. lodash / cloneDeep
  3. 通过**JSON.stringify()**实现
  4. 通过递归实现深拷贝
    1. 函数递归:
      如果一个函数在内部可以调用其本身,那么这个函数就是递归函数
      1. 简单理解:函数内部自己调用自己, 这个函数就是递归函数
      2. 递归函数的作用和循环效果类似
      3. 由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return

屏幕截图(2).png

let num = 1;
function fn() {
    if (num >= 6) {
        return document.write(num);
    }
    num++;
    fn(); // 函数内部调用自己
}
fn()

** 利用递归函数实现 setTimeout 模拟 setInterval效果 **


利用递归函数实现 setTimeout 模拟 setInterval效果
需求:
①:页面每隔一秒输出当前的时间
②:输出当前时间可以使用:new Date().toLocaleString()

<body>
	<h1></h1>

	<script>


	let h1 = document.querySelector("h1")
function getTime(){
	const time = new Date().toLocaleString();
	let str = time;

	h1.innerHTML = time;

	setTimeout(getTime, 1000);

}
getTime();

	</script>
</body>

屏幕截图(3).png

  1. js库 **lodash **里面 cloneDeep 内部实现了深拷贝


        import { cloneDeep } from "lodash";
        const o = {
            uname: "username ",
            age: 20,
            hobby: ['篮球', '足球'],
            famliy: {
                baby: "baby"
            }
        }
        // _.cloneDeep(要被克隆的对象)
        const p = _.cloneDeep(o);
        console.log(p);
        p.famliy.baby = 'lao baby';
        console.log(o);
  1. 通过JSON.stringify()实现
const obj ={
	uname:"username",
	age:20,
	hobby: ['篮球', '足球'],
	famliy: {
		baby: "baby"
	}
}
const o = JSON.parse(JSON.stringify(obj));
console.log(o);
o.famliy.baby ="lao baby";
console.log(obj);

image.png

异常处理

throw 抛异常

异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法继续运行

  1. throw 抛出异常信息,程序也会终止执行
  2. throw 后面跟的是错误提示信息
  3. Error 对象配合 throw 使用,能够设置更详细的错误信息
function counter(x,y){
	if(!x || !y){
		throw new Error("参数不能为空");
	}
	return x + y;
}
document.write(counter())

image.png

try /catch 捕获异常

我们可以通过** try / catch **捕获错误信息(浏览器提供的错误信息) try 试试 catch 拦住 finally 最后

  1. try…catch 用于捕获错误信息
  2. 将预估可能发生错误的代码写在 try 代码段中
  3. 如果 try 代码段中出现错误后,会执行 catch 代码段,并截获到错误信息4. finally 不管是否有错误,都会执行
function foo(){
	try{
		//查找DOM结点
		const p = document.querySelector(".p");
		p.style.color = "red";
	}catch(error){
		// try 代码段中执行有错误时,会执行catch代码段
		// 查看错误信息
		console.log(error.message);
		console.log("出现问题");
		// 终止代码
		return
	}finally{
		alert("已执行")

	}
	console.log("如果出现错误,我的语句不会执行");
}
foo()

debugger

const arr = [1,3,5]
const newarr = arr.map((item, index) =>{
	debugger
	console.log(item);
	console.log(index);
	return item+10;
})
console.log(newarr);

处理this

this指向

this 是 JavaScript 最具“魅惑”的知识点,不同的应用场合 this 的取值可能会有意想不到的结果,在此我们对以往学习过的关于【 this 默认的取值】情况进行归纳和总结。
目标: 了解函数中 this 在不同场景下的默认值,知道动态指定函数 this 值的方法
普通函数的调用方式决定了 this 的值,即【谁调用 this 的值指向谁】

this指向-普通函数

  • 目标: 能说出普通函数的this指向
  • 普通函数的调用方式决定了 this 的值,即【谁调用 this 的值指向谁

普通函数没有明确调用者时 this 值为 window,**严格模式下没有调用者时 this 的值为 undefined **

// 普通函数
function sayhi() {
	console.log(this);

}
// 函数表达式
const sayhello = function(){
	console.log(this);
}
// 函数的调用方式决定了 this 的值
sayhi(); // window
window.sayhi();
// 普通对象
const user = {
	name:"小明",
	walk:function(){
		console.log(this);
	}
}
// 动态为 user 添加方法
user.sayhi = sayhi;
user.sayHello = sayhello
// 函数调用方式,决定了 this 的值
user.sayhi
user.sayHello

this指向-箭头函数

  • 目标: 能说出箭头函数的this指向

箭头函数中的 this 与普通函数完全不同,也不受调用方式的影响,事实上箭头函数中并不存在 this !

  1. 箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的
  2. 箭头函数中的this引用的就是最近作用域中的this
  3. 向外层作用域中,一层一层查找this,直到有this的定义
  console.log(this);// 此处指向window
    const sayhi = function(){
        console.log(this); // 该箭头函数中的 this 为函数声明环境中 this 一致
    }

    const user = {
        name:"小明",
        // 该箭头函数中的 this 为函数声明环境中 this 一致
        walk:()=>{
            console.log(this);
        },
    }
    sayhi()
    user.walk()

image.png
注意情况1:
在开发中【使用箭头函数前需要考虑函数中 this 的值】,事件回调函数使用箭头函数时,this 为全局的 window
因此DOM事件回调函数如果里面需要DOM对象的this,则不推荐使用箭头函数

改变this

性能优化

综合案例

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值