大家有关于JavaScript知识点不知道可以去
博客主页:阿猫的故乡
系列专栏:JavaScript专题栏
欢迎关注:点赞收藏✍️留言
目录
学习目标:
学习内容:
学习时间:
学习知识:
深浅拷贝:
浅拷贝
深拷贝
练习:
总结
异常处理
throw 抛异常
• try /catch 捕获异常
• debugger
处理this
this指向
• 改变this
改变this指向
call
apply
bind
性能优化
js防抖和节流的区别
深入this学习,知道如何判断this指向和改变this指向
知道在JS中如何处理异常,学习深浅拷贝,理解递归
深浅拷贝
异常处理
处理this
性能优化
综合案例
提示:这里可以添加计划学习的时间
例如:
开发中我们经常需要复制一个对象。如果直接用赋值会有下面问题:
使用浅拷贝的注意点:
常见方法:
1. 拷贝对象:Object.assgin() / 展开运算符 {...obj} 拷贝对象
2.拷贝数组:Array.prototype.concat() 或者 [...arr]
直接赋值和浅拷贝有什么区别?
直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对
象栈里面的地址
浅拷贝如果是一层对象,不相互影响,如果出现多层对象拷贝还会
相互影响
2. 浅拷贝怎么理解?
拷贝对象之后,里面的属性值是简单数据类型直接拷贝值
如果属性值是引用数据类型则拷贝的是地址
首先浅拷贝和深拷贝只针对引用类型
深拷贝:拷贝的是对象,不是地址
常见方法:
1. 通过递归实现深拷贝
2. lodash/cloneDeep
3. 通过JSON.stringify()实现
常见方法:
1. 通过递归实现深拷贝
函数递归:
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数
常见方法:
1. 通过递归实现深拷贝
函数递归:
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数
利用递归函数实现 setTimeout 模拟 setInterval效果
需求:
①:页面每隔一秒输出当前的时间
②:输出当前时间可以使用:new Date().toLocaleString()
常见方法:
1. 通过递归函数实现深拷贝(简版)
深拷贝是指将一个对象复制到一个新对象中,并且新对象中所有的属性的值都是原对象中对应属性的复制,而且如果属性的值是对象类型,则对该对象也进行深拷贝,使得新对象与原对象完全独立。
要实现深拷贝,可以使用递归函数。递归函数是指在函数内调用自身的函数。使用递归函数可以遍历对象的所有属性,并将它们复制到新对象中。
下面是一个使用递归函数实现深拷贝的例子:
function deepCopy(obj) {
// 如果是简单类型或者 null,则直接返回
if (typeof obj !== 'object' || obj === null) {
return obj;
}
// 创建一个新对象
const newObj = Array.isArray(obj) ? [] : {};
// 遍历对象的所有属性
for (let key in obj) {
// 如果属性是对象类型,则递归调用该函数
if (typeof obj[key] === 'object') {
newObj[key] = deepCopy(obj[key]);
} else {
// 如果是简单类型,则直接复制值
newObj[key] = obj[key];
}
}
// 返回新对象
return newObj;
}
这个函数接受一个对象作为参数,并返回一个它的深度拷贝。如果参数是一个简单类型或者 null,则直接返回它本身。否则,创建一个新对象,遍历原对象的所有属性,如果属性是对象类型,则递归调用该函数,否则直接复制属性的值。最后返回新对象。
实现深拷贝三种方式?
自己利用递归函数书写深拷贝
利用js库 lodash里面的 _.cloneDeep()
利用JSON字符串转换
异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法继续运行
总结:
1. throw 抛出异常信息,程序也会终止执行
2. throw 后面跟的是错误提示信息
3. Error 对象配合 throw 使用,能够设置更详细的错误信息
我们可以通过try / catch 捕获错误信息(浏览器提供的错误信息) try 试试 catch 拦住 finally 最后
总结:
1. try...catch 用于捕获错误信息
2. 将预估可能发生错误的代码写在 try 代码段中
3. 如果 try 代码段中出现错误后,会执行 catch 代码段,并截获到错误信息
4. finally 不管是否有错误,都会执行
在 JavaScript 中,try/catch 语句用于捕获和处理代码执行期间抛出的异常(或错误)。try 块中的代码可能会抛出一个异常,如果这种情况发生,则异常会被传递到 catch 块中进行处理。
以下是使用 try/catch 语句的基本语法:
try {
// 可能会抛出异常的代码
} catch (e) {
// 异常处理逻辑
}
当 try 块中的代码抛出异常时,catch 块中的代码将被执行。catch 块中的参数 e 是一个异常对象,它包含有关异常的信息(例如错误消息)。
在 catch 块中,您可以执行任何适当的操作来处理异常。例如,您可以使用 console.log() 语句将错误消息写入控制台,或显示一个警报框来向用户指示发生了错误。
以下是一个简单的示例,演示如何使用 try/catch 块来捕获和处理异常:
try {
// 这行代码会抛出一个异常
undefinedFunction();
} catch (e) {
// 异常处理逻辑
console.log('发生了一个错误:' + e.message);
}
在此示例中,try 块中的代码会调用一个未定义的函数 undefinedFunction(),这将抛出一个异常。由于try/catch 块存在,异常被捕获并传递给 catch 块中的代码进行处理。在这个示例中,catch 块中的代码使用 console.log() 语句将错误消息写入控制台。
debugger
是 JavaScript 的内置调试器命令,它可以让你在代码中设置断点,以便在运行时暂停代码执行并检查程序状态。
在代码中插入 debugger
命令会启用调试器,并在执行到这个地方时暂停代码的执行。此时你可以在调试器中进行检查和调试。
以下是一个简单的示例:
function calculate(x, y) {
debugger;
return x + y;
}
var result = calculate(2, 3);
console.log(result);
在此示例中,我们创建了一个名为 calculate
的函数,它接受两个参数并返回它们的和。在函数中插入了 debugger
命令,这意味着在代码执行到这里时会暂停。然后我们调用 calculate
函数,并将返回值存储在 result
变量中。最后,我们在控制台中输出 result
的值。
当你在浏览器中执行此代码时,浏览器将在执行到 debugger
命令时自动启用调试器并暂停代码执行。在调试器中,你可以检查变量的值、执行代码段、单步运行代码以及检查调用栈等等。
请注意,在发布/生产环境中不应该将 debugger
命令留在你的代码中,因为它会干扰应用的正常运行。
this 是 JavaScript 最具“魅惑”的知识点,不同的应用场合 this 的取值可能会有意想不到的结果,在此我们对以往学习
过的关于【 this 默认的取值】情况进行归纳和总结。
目标: 了解函数中 this 在不同场景下的默认值,知道动态指定函数 this 值的方法
this
是 JavaScript 中的一个关键字,它代表当前函数执行的上下文对象。this
的值在不同的情况下会有不同的指向。
以下是一些常见的 this
指向:
全局作用域下的 this
指向全局对象 window
。
在函数中,this
的值取决于函数如何被调用,当函数被作为一个普通函数调用时,this
的值指向全局对象 window
。但是如果函数作为对象的方法调用时,this
的值指向这个对象。
function person() {
console.log(this);
}
person(); // 在全局作用域下调用,this 指向 window 对象
var obj = {
name: 'John',
sayName: function() {
console.log(this.name);
}
};
obj.sayName(); // 作为 obj 对象的方法调用,this 指向 obj 对象
在构造函数中,this
的值指向当前实例对象。
function Person(name) {
this.name = name;
this.sayName = function() {
console.log(this.name);
}
}
var john = new Person('John');
john.sayName(); // this 指向 john 实例对象
在事件处理函数中,this
的值指向触发事件的元素。
在箭头函数中,this
的值指向当前上下文对象。
var obj = {
name: 'John',
sayName: function() {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
obj.sayName(); // this 指向 obj 对象
需要注意的是,this
的值是在函数执行的时候才能确定,而不是在函数定义的时候。因此,在使用 this
时需要注意当前函数在什么上下文中被调用。
在 JavaScript 中,可以使用 call()
、apply()
、bind()
方法来改变函数中 this
的指向。
call()
和 apply()
方法可以直接将要改变的 this
上下文对象指定为函数调用时的第一个参数,接下来的参数是被调用函数的参数,这两个方法的主要区别在于传参的方式不同,call()
方法的参数是一系列的参数列表,而 apply()
方法的参数是一个数组。
function sayName() {
console.log(this.name);
}
var person1 = {
name: 'John'
};
var person2 = {
name: 'Mike'
};
sayName.call(person1); // 输出 'John'
sayName.apply(person2); // 输出 'Mike'
bind()
方法将被调用的函数和要改变的 this
上下文对象绑定,并返回一个新的函数,原始函数中的 this
的指向不会发生改变。
var person1 = {
name: 'John',
sayName: function() {
console.log(this.name);
}
};
var person2 = {
name: 'Mike'
};
var sayName2 = person1.sayName.bind(person2); // 绑定 sayName() 函数和 person2 对象
sayName2(); // 输出 'Mike'
需要注意的是,使用 call()
、apply()
、bind()
方法改变 this
的指向时,如果传入的 this
参数不是一个对象,JavaScript 会临时将其转换为一个对象,并且 null
和 undefined
会被转换为全局对象。因此,在使用时需要注意传入的参数是否符合要求。
箭头函数中的 this 与普通函数完全不同,也不受调用方式的影响,事实上箭头函数中并不存在 this !
1. 箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的
2.箭头函数中的this引用的就是最近作用域中的this
3.向外层作用域中,一层一层查找this,直到有this的定义
注意情况1:
在开发中【使用箭头函数前需要考虑函数中 this 的值】,事件回调函数使用箭头函数时,this 为全局的 window
因此DOM事件回调函数如果里面需要DOM对象的this,则不推荐使用箭头函数
2. apply()-理解
使用 apply 方法调用函数,同时指定被调用函数中 this 的值
语法:
fun.apply(thisArg, [argsArray])
thisArg:在fun函数运行时指定的 this 值
argsArray:传递的值,必须包含在数组里面
返回值就是函数的返回值,因为它就是调用函数
因此 apply 主要跟数组有关系,比如使用 Math.max() 求数组的最大值
fun.apply(thisArg, [argsArray])
以上归纳了普通函数和箭头函数中关于 this
默认值的情形,不仅如此 JavaScript 中还允许指定函数中 this
的指向,有 3 个方法可以动态指定普通函数中 this
的指向:
使用 call
方法调用函数,同时指定函数中 this
的值,使用方法如下代码所示:
总结:
call
方法能够在调用函数的同时指定 this
的值
使用 call
方法调用函数时,第1个参数为 this
指定的值
call
方法的其余参数会依次自动传入函数做为函数的参数
使用 call
方法调用函数,同时指定函数中 this
的值,使用方法如下代码所示:
总结:
apply
方法能够在调用函数的同时指定 this
的值
使用 apply
方法调用函数时,第1个参数为 this
指定的值
apply
方法第2个参数为数组,数组的单元值依次自动传入函数做为函数的参数
bind
方法并不会调用函数,而是创建一个指定了 this
值的新函数,使用方法如下代码所示:
注:bind
方法创建新的函数,与原函数的唯一的变化是改变了 this
的值。
节流(throttle)
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数
JavaScript性能优化有许多方法,以下是一些常见的技巧:
减少重绘和回流:重绘和回流会导致页面的重新布局和渲染,会影响性能。可以通过减少对DOM的查询、使用documentFragment、使用CSS3动画等方式来减少重绘和回流。
减少HTTP请求:减少页面资源的请求可以大大提高页面的加载速度。可以通过合并CSS和JavaScript文件、使用图片的雪碧图等方式减少HTTP请求。
使用缓存:可以使用浏览器的缓存机制来减少请求和提高加载速度。可以使用浏览器缓存或者将静态资源放在CDN上。
避免不必要的计算:在编写JavaScript代码时,应避免不必要的计算。可以使用缓存和预处理等技术来避免重复的计算。
使用事件委托:事件委托可以减少事件处理器的数量,从而提高性能。可以将事件处理器绑定在父元素上,通过事件冒泡机制来处理子元素的事件。
使用异步加载:可以使用异步加载来提高页面加载速度。可以使用异步请求、defer和async等方式来实现异步加载。
关闭循环引用:JavaScript中的循环引用会导致内存泄漏,可以使用垃圾回收器来回收不再使用的内存。
避免过度渲染:在使用JavaScript更新DOM时,应避免过度渲染。可以使用requestAnimationFrame来避免过度渲染。
节流(throttle)
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数
开发使用场景 – 小米轮播图点击效果 、 鼠标移动、页面尺寸缩放resize、滚动条滚动 就可以加节流
假如一张轮播图完成切换需要300ms, 不加节流效果,快速点击,则嗖嗖嗖的切换
加上节流效果, 不管快速点击多少次, 300ms时间内,只能切换一张图片。
防抖和节流都是为了优化JavaScript函数的性能,但两者的实现和目的略有不同。
防抖是指在一定时间内,多次触发同一事件,只执行最后一次操作,也就是抖动结束后才执行。例如在输入框输入搜索内容时,在用户连续输入时不会立即进行搜索,而是等待用户停止输入一段时间后再进行搜索。防抖可以减少函数的执行次数,避免频繁的操作。
实现方式:每次触发事件时都会清除之前的定时器,重新设置一个新的定时器。当事件停止触发一定时间后,定时器执行函数。
节流是指一定时间内,多次触发同一事件,只执行一次操作。例如在拖拽一个元素时,需要不断获取其位置,但不应该每次都进行计算,而是一段时间内只计算一次并返回计算结果。节流可以控制函数的执行频率。
实现方式:通过设置一个定时器,在一定时间内只执行一次函数。如果定时器还未执行,再次触发事件则不执行函数。
区别:
以上就是全部的关于JavaScript知识点以及案例 (有需要素材的及时联系我!!)