前端 易混淆知识点梳理

server/2024/11/18 11:50:32/

目录

一、严格模式与非严格模式

二、双等于三等的区别

三、防抖和节流

四、原型和原型链

五、页面重绘和回流

六、script标签async和defer

七、普通函数和箭头函数的区别

八、JS闭包

1、闭包特点

2、闭包作用

3、闭包风险

4、运用场景

1)常见闭包

2)实现模块化

3)缓存函数

4)封装私有变量

5)实现函数柯里化

7)防抖和节流


一、严格模式与非严格模式

在代码前加

"use strict"

或在class类里书写都会开启严格模式。

开启严格模式后,JS有以下变化:

变量

1、变量使用前必须声明 (此时,不声明就使用会直接报错)

2、不能直接用delete删除变量  (非严格模式的静默失败->严格模式的直接报错)

对象:

(非严格模式静默失败->严格模式的直接报错)(enumerable 不会报错)

1、对象的属性也不能直接使用delete来进行删除了

函数:

1、参数必须唯一   (非严格模式支持参数重复)

2、实参和形参不再具有映射关系  (非严格模式的arguments实参被修改,形参也会对应更改;在严格模式下,这两种参数一方被修改,另一方不会被一起更改)

3、不能使用argument的callee方法和caller

4、eval、agument类似这样的关键词名不得作为标识符,包括变量名、函数名等

5、不允许使用eval()、with()这两个方法  (这两个方法可能带来风险)

6、不允许出现八机制数  (因为八机制数开头是0会有歧义)

7、普通函数在全局里的this变成了undefined  (非严格模式时,普通函数在全局里的this指向window)

二、双等于三等的区别

1、“==”表示:equality -> 等同的意思,“==”两个等号使用时,若两边值的类型不同时,系统会先进行类型转换,再进行比较;

2、“==”表示:identity -> 恒等的意思,“===”三个等号使用时,系统不会进行类型转换,若类型不同,就表示一定不等的;

3. 简单说明使用三个等号(===)的判断规则:

(1)如果类型不同,就一定不相等

(2)如果两个都是数值,并且是同一个值,那么相等;如果其中至少一个是NaN,那么不相等。(判断一个值是否是NaN,只能使用isNaN( ) 来判断)

(3)如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等。

(4)如果两个值都是true,或是false,那么相等

(5)如果两个值都引用同一个对象或是函数,那么相等,否则不相等

(6)如果两个值都是null,或是undefined,那么相等

4. 简单说明使用两个等号(==)的判断规则:

(1)如果两个值类型相同,再进行三个等号(===)的比较

(2)如果两个值类型不同,也有可能相等,需根据以下规则进行类型转换在比较:

1)如果一个是null,一个是undefined,那么相等

2)如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较

3)另外两个NaN是不相等的。

三、防抖和节流

防抖:单位时间内,频繁触发事件,只执行最后一次

常见场景:输入框输入

若频繁监听可能会出现抖动情况,解决方案有二,一是在输入结束后再点击触发事件,而是通过防抖操作解决。利用定时器可以实现防抖的功能,每次触发先清掉以前的定时器。

节流:单位时间内,频繁触发事件,只触发一次

常见场景:高频事件、快速点击、鼠标滑动监听、resize事件、scroll事件

类比场景:火箭发射

代码实现:利用定时器,定时器执行完毕,再开启定时器(不要打断)

第三方库也可实现,lodash库,利用里面的debounce(防抖)和throttle(节流)来做。

代码实现,见文章最后部分,闭包的7里的代码。

四、原型和原型链

原型:

每个普通函数都有prototype属性,称为原型。因为这个属性的值是一个对象,所以也叫原型对象。

作用:

1、存放一些属性和方法,共享给实例对象使用

2、在JavaScript中实现继承

如:

    function Person(name, age) {this.name = namethis.age = age}function Male() {}Male.prototype = new Person() //实现继承const man=new Male() console.log(man)

__proto__:

每个对象都有__proto__属性

作用:

这个属性指向它的原型对象

原型链:

对象都有__proto__属性,这个属性指向它的原型对象,原型对象也是对象,也有__proto__属性。原型对象的__proto__指向原型对象的原型对象,这样一层层形成的链式结构称为原型链。最顶层Object的prototype的__proto__指向null, 到null结束。

常见场景:调用某个对象的方法,若在对象的最近一级有该方法就直接调用,若没有,就继续往上一级查找,找到后调用。

案例:

function Person() {
}
const person=new Person()
person.__proto__===Person.prototype   //true
person.__proto__.constructor===Person.prototype.constructor  //true
person.constructor===Person   //true
Person.prototype.constructor===person.constructor  //true

更多关于prototype见这篇:前端 JS面向对象 原型 prototype-CSDN博客

五、页面重绘和回流

重绘:

当元素的视觉效果发生变化,但几何属性(如位置和大小)没有改变时,浏览器会重新绘制元素。这包括改变元素的背景色、边框色、字体颜色等‌。

回流:

当元素的布局属性发生变化时,浏览器需要重新计算元素的位置和大小,并更新页面布局。这包括添加、删除或重新排列DOM节点,修改元素的尺寸、位置或样式等‌。

回流是一个相对昂贵的操作,因为它涉及到大量的计算和重新布局,频繁触发回流会导致性能问题,尤其是在处理复杂或大型的DOM结构时‌。

何时引起重绘?

1、视觉属性变化时:如颜色、背景、边框色、阴影色、文字内容颜色等发生改变时;

2、元素尺寸和位置不变时:重绘发生在元素尺寸和位置不变的情况下,只改变元素的外观属性,如背景颜色、字体颜色等;

3、元素隐藏时:将元素的visibility属性设置为hidden时,虽然会触发重排,但不会影响布局,只会触发重绘。

何时会引起回流?

1、添加或删除可见的Dom元素;

2、元素位置发生变化;

3、元素尺寸发生变化 (包括外边距、内边距、边距大小、高度和宽度等);

4、内容发送变化,比如文本变化或图片被另一个不同尺寸的图片代替;

5、浏览器窗口尺寸发生变化(因为回流是根据视口大小来元素位置和大小的)

回流和重绘的联系?

回流一定引起重绘,而重绘不一定会回流。

六、script标签async和defer

script 标签JS 执行顺序是否阻塞解析 HTMLDOMContentLoaded回调
<script>依次等待
<script async>先下载完先执行DOM未解析完时阻塞不等待
<script defer>先下载完所有defer再依次执行等待

1、默认情况下,遇到script标签会阻塞下面HTML的解析,先解析完成script标签里的内容,再继续执行解析。(同步解析,依次进行)

2、async情况下,遇到script标签系统不会阻塞HTML的解析,而是创建一个异步路径来进行async脚本的解析。一边解析HTML一遍解析async,当async解析完毕后,系统才会阻塞HTML的解析并立即执行async script里的内容。(解析时不阻塞HTML解析,解析完毕执行时才阻塞HTML,两个解析相互独立进行)

3、defer情况下,不会阻塞HTML解析,直到HTML解析完毕后,defer在最后执行。(DOM元素渲染完毕后执行)

使用情景:

1、默认情况适合一般脚本的顺序执行;

2、async情况适合处理一些无需阻塞并且与DOM元素无关的操作。

(注:这种情况下,执行DOM元素的操作是不稳定的。当DOM元素很少时,可能async有时会比HTML晚解析慢,从而后执行,有时执行正常有时执行失败。但当DOM元素过大需要更多时间解析时,很可能async都已经开始执行了,但DOM还未解析完毕,当async里的代码操作DOM元素时,就可能出现获取不到DOM元素的情况)

3、defer情况适合需要在页面加载完毕后的代码执行,如需要操作DOM的脚本执行。

七、普通函数和箭头函数的区别

1、this绑定:

箭头函数:没有自己的this上下文,而是继承父类的this; (不能使用apply、bind、call来修改this指向)(箭头函数的this在定义时就已确定,之后不得修改)

普通函数:this取决于函数的调用方式。(补充:在全局状态下,非严格模式this是window,严格模式下this是undefined)

2、arguments实参对象

箭头:不包含arguments;

普通:包含arguments对象 (补充:非严格模式下,实参arguments是和形参进行映射的,修改其中一个对应都会改变;严格模式下,并未有映射,修改其一不会修改另一个对应)

3、作用域和闭包

箭头:遵循作用域规则 (块级作用域)

普通:形成闭包

八、JS闭包

JavaScript的普通函数就是一个闭包。

1、闭包特点

1)函数嵌套函数

2)内层函数可以访问外层函数的变量和参数

2、闭包作用

1、防止变量和参数被垃圾回收机制回收(变量持久化)

2、防止变量和参数被外部污染 (变量只在内部可访问)

3、闭包风险

滥用可能会造成内存泄漏。

4、运用场景
1)常见闭包
    function makeCounter() {let counter = 0return function () {counter++console.log(counter)}}const counter = makeCounter()counter()  //1counter()  //2counter()  //3
2)实现模块化
    const myModule=(function () {let count=0function increment(){count++}function reset(){count=0}function getCount(){return count}return {increment,reset,getCount}})()myModule.increment()console.log(myModule.getCount())  // 1myModule.reset()console.log(myModule.getCount())  // 0
3)缓存函数
     function memorize(fn) {const cache = {}return function (arg) {if (arg in cache) {console.log("已调用缓存数据")return cache[arg]} else {const result = fn(arg)cache[arg] = resultreturn result}}}function expensiveCalculation(num) {console.log("正在计算" + num + "的阶乘...")let result = 1for (let i = 2; i <= num; i++) {result *= i}return result}const memorizedCalculation = memorize(expensiveCalculation)console.log(memorizedCalculation(5))  //正在计算5的阶乘...  120console.log(memorizedCalculation(5))  //已调用缓存数据    120
4)封装私有变量
     function createPerson(name, age) {let privateName = namelet privateAge = agefunction getName() {return privateName}function setName(newName) {privateName = newName}function getAge() {return privateAge}function setAge(newAge) {privateAge = newAge}return {getName,setName,getAge,setAge}}const person = createPerson("张三", 18)console.log(person.getName())  //张三console.log(person.getAge())   //18person.setName("李四")person.setAge(20)console.log(person.getName())   //李四console.log(person.getAge())    //20
5)实现函数柯里化
    function add(a, b, c, d) {return a + b + c + d}function curry(fn) {return function curried(...args) {if (args.length >= fn.length) {return fn.apply(this, args)} else {return function (...moreArgs) {return curried.apply(this, args.concat(moreArgs))}}}}const curriedAdd = curry(add)console.log(curriedAdd(1)(2)(3)(4))   //10console.log(curriedAdd(1, 2)(3, 4))   //10console.log(curriedAdd(1, 2, 3, 4))   //10
7)防抖和节流
     function debounce(fn, wait) {let timeoutIdreturn function (...args) {clearTimeout(timeoutId)timeoutId = setTimeout(() => {fn.apply(this, args)}, wait)}}function throttle(fn, wait) {let isThrottled = falsereturn function (...args) {if (!isThrottled) {isThrottled = truesetTimeout(() => {fn.apply(this, args)isThrottled = false}, wait)}}}function handleInput() {console.log("input changed")}const debouncedHandleInput = debounce(handleInput, 500)const throttleHandleInput = throttle(handleInput, 500)document.querySelector("input").addEventListener("input", debouncedHandleInput)document.querySelector("button").addEventListener("click", throttleHandleInput)

总结到此!


http://www.ppmy.cn/server/142902.html

相关文章

引入了JUnit框架 却报错找不到:java.lang.ClassNotFoundException

完整报错如下&#xff1a; Internal Error occurred. org.junit.platform.commons.JUnitException: TestEngine with ID junit-jupiter failed to discover tests at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrc…

NotePad++中安装XML Tools插件

一、概述 作为开发人员&#xff0c;日常开发中大部的数据是标准的json格式&#xff0c;但是对于一些古老的应用&#xff0c;例如webservice接口&#xff0c;由于其响应结果是xml&#xff0c;那么我们拿到xml格式的数据后&#xff0c;常常会对其进行格式化&#xff0c;以便阅读。…

Cloudflare代理后的https连接的建立还是从源客户端到服务器端握手协商的连接吗

在 Cloudflare 代理的 HTTPS 连接中&#xff0c;连接的建立过程涉及多个步骤&#xff0c;具体如下&#xff1a; 客户端与 Cloudflare 的连接 初始连接&#xff1a;当客户端发起 HTTPS 请求时&#xff0c;它首先与 Cloudflare 的边缘服务器建立连接。这个连接会进行 TLS 握手&a…

docker 安装nacos

docker 安装开发环境配置 nacos安装 docker拉取镜像 docker pull nacos/nacos-server:1.2.0创建容器 docker run --env MODEstandalone --name nacos --restartalways -d -p 8848:8848 nacos/nacos-server:1.2.0

#Swift Automatic Initializer Inheritance

在Swift中&#xff0c;**自动初始化器继承&#xff08;Automatic Initializer Inheritance&#xff09;**是一种机制&#xff0c;用于简化类的初始化器继承规则。它决定了在什么条件下子类可以自动继承父类的初始化器&#xff0c;而无需手动实现或重写。自动继承初始化器的机制…

23 种设计模式详解

设计模式的分类 总体来说设计模式分为三大类&#xff1a; 创建型模式&#xff0c;共五种&#xff1a;单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。 结构型模式&#xff0c;共七种&#xff1a;适配器模式、装饰器模式、代理模式、外观模式、桥接模式、 组合模…

计算机视觉中的双边滤波:经典案例与Python代码解析

&#x1f31f; 计算机视觉中的双边滤波&#xff1a;经典案例与Python代码解析 &#x1f680; Hey小伙伴们&#xff01;今天我们要聊的是计算机视觉中的一个重要技术——双边滤波。双边滤波是一种非线性滤波方法&#xff0c;主要用于图像去噪和平滑&#xff0c;同时保留图像的边…

OceansGallerie趣味游戏:带领Web2用户无缝融入Web3世界

引言 随着区块链技术的飞速发展&#xff0c;Web3生态正在逐渐成为数字世界的核心。然而&#xff0c;对于全球10亿Web2用户来说&#xff0c;区块链和Web3的概念依然晦涩难懂。OceansGallerie平台通过设计一个趣味性和奖励性的休闲游戏模块&#xff0c;旨在为这些用户提供一个简…