JavaScript常问面试题

css

1.HTML5新增了哪些内容

  • 语义化更好的内容标签(header,footer,main,nav,aside,article,section)
  • 音频 ,视频标签(audio, video)
  • 画布(canvas)
  • 表单控件 calendar , date , time , email , url , search , tel , file , number
  • 地理位置API(geolocation)
  • 拖拽释放API(Drap and drop)
  • WebAPI:localStorage、sessionStorage、webworker、websocket

2.CSS3新增了哪些内容

  • 颜色: 新增 RGBA , HSLA 模式
  • 文字阴影(text-shadow)
  • 边框: 圆角(border-radius) 边框阴影 : box-shadow
  • 盒子模型: box-sizing
  • 背景:background-size background-origin background-clip
  • 渐变: linear-gradient , radial-gradient
  • 过渡 : transition 可实现属性的渐变
  • 自定义动画 animate @keyfrom
  • 媒体查询 多栏布局 @media screen and (width:800px) {…}
  • border-image 图片边框
  • 2D 转换/3D 转换;transform: translate(x,y) rotate(x,y) skew(x,y) scale(x,y)
  • 字体图标 iconfont/icomoon
  • 弹性布局 flex

3.什么是HTML语义化

  • HTML语义化是指使用合适的HTML标签做合适的事,既是不使用css属性也可以将网页内容以文档的形式展现出来。
  • 有助于提高网站的可访问性和搜索引擎优化(SEO),便于浏览器、搜索引擎以及其他设备(如屏幕阅读器)解析和理解网站内容。

4.常见的布局方式

  • 表格布局:由 <table> 标签定义。每个表格均有若干行( <tr>),每行被分割为若干单元格(<td>)。
  • 浮动布局:通过float属性创建浮动元素,实现浮动布局。浮动布局会脱离文档流,容易造成父元素高度塌陷问题。
  • 定位布局:通过postion属性创建定位元素,以精确控制网页对象的显示位置,布局精准,不会出现错行和误差问题;缺点是缺乏灵活性,栏目之间不能够协同变化,还会存在叠加等风险。
  • 流动布局:流动布局是HTML默认的布局方式,通过百分比控制元素尺寸,随文档流自上而下按顺序动态分布。
  • 弹性布局:和浮动一样都用于网页布局,但flex比浮动要更强大。flex不会产生脱标现象,布局网页更灵活、更简单
  • 栅格布局:与弹性布局相似,栅格系统也是由栅格容器包裹栅格元素进行使用。对于栅格布局来说,它的思想实际上非常简单,将一块区域绘制成格子,然后将元素填进去即可

5.弹性布局和栅格布局

  • Flex布局 Flexible Box的缩写,也称为弹性布局W3C于2009年提出。是一种以轴线为标准的一种布局方式。
  • Grid布局Grid 布局又称为网格布局,微软于 2010 年提出。是一种将容器划分为单元格的布局形式。
  • 总结:布局的操作性和复杂度上来看,Grid布局要比Flex布局强大,但是Grid会有一些浏览器兼容性、响应式设计、性能优化等问题

6.圣杯布局和双飞翼布局

  • 最终效果相同,两侧宽度固定,中间宽度自适应(三栏布局)
  • 圣杯布局代码结构上更加自然和直观,在平时的开发中更容易形成这样的布局结构;
  • 双飞翼布局由于不使用定位,所以代码更加简洁,允许页面的最小宽度小于圣杯布局。

7.px、em、rem、vwwh、%

  • px:表示计算机的像素单位,1像素就是1px
  • em:相对于元素font-size大小的单位
  • rem:相对于根元素font-size大小的单位
  • vwvh:相对于浏览器可视窗口尺寸的单位
  • %:相对于父元素尺寸的单位
  • calc()方法可以进行不同单位之间的运算

8.媒体查询

  • 媒体查询允许根据不同的设备或屏幕尺寸和分辨率应用不同的样式。是创建响应式页面的关键。
  • 媒体查询的组成:
    • @media:创建媒体查询
    • 媒体类型:定义了媒体查询适用的设备类型。例如,all适用于所有设备,print用于打印机和打印预览模式,screen用于电脑屏幕、平板和智能手机等,speech适用于基于语音识别的设备。
    • 媒体特性:在媒体查询中使用的条件,如宽度(width)、高度(height)和颜色等,用于限制样式的应用条件。

9.css盒模型

  • 盒子模型分为两种: 
    • W3C 标准的盒子模型(标准盒模型)可以通过box-sizing:content-box来设置;
    • IE 标准的盒子模型(怪异盒模型)可以通过box-sizing:border-box来设置;
  • 标准盒模型与怪异盒模型的表现效果的区别之处:
    • 标准盒模型下盒子的大小 = content + border + padding + margin
    • 怪异盒模型下盒子的大小=width(content + border + padding) + margin

10.css选择器权重

        !Important > 行内样式 > ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性

11.如何实现一个元素水平居中

  • 块级元素
    • postion:abslute;
      top:50%;
      left:50%;
      transform:translate(-50%,-50%);
    • display:flex;
      justify-content:center;
      align-items:center;
    • display: grid;
      place-items: center;
  • 行内元素
    • text-align:center;
      line-height:20px;

12.css中哪些属性是可以继承的、哪些是不可以继承的

  • 能继承的属性
    • 字体系列属性:font、font-size、font-weight、font-family、font-style; 
    • 文本系列属性: 
      • 内联元素:color、line-height、text-align
      • 块级元素:text-align、text-indent; 
      • 元素可见性:visibility
  • 不能继承的属性
    • 盒子模型的属性:display、overflow、width、height、min-width、min-height、max-width、max-height、margin、padding、border; 
    • 背景属性:background、background-color、background-image; 
    • 定位属性:float、clear、position、top、right、bottom、left;

13.Input元素type属性值

  • text 默认。定义单行输入字段,用户可在其中输入文本。默认是 20 个字符;
  • password 定义密码字段。字段中的字符会被遮蔽;
  • search 定义用于搜索的文本字段;
  • number 定义带有 spinner 控件的数字字段;
  • email 定义用于 e-mail 地址的文本字段;
  • url 定义用于 URL 的文本字段;
  • radio 定义单选按钮。
  • checkbox 定义复选框。
  • button 定义可点击的按钮(大多与 JavaScript 使用来启动脚本)
  • reset 重置按钮,用于重置表单数据。
  • submit 定义提交按钮。提交按钮向服务器发送数据。
  • range 滑动条,用于选择一个范围内的值
  • color 定义拾色器。
  • image 定义图像作为提交按钮;
  • file 定义输入字段和 "浏览..." 按钮,供文件上传
  • date 定义日期字段(带有 calendar 控件)
  • month 定义日期字段的月(带有 calendar 控件)
  • time 定义日期字段的时、分、秒(带有 time 控件)

14.display和visibility的区别

  • dispaly:none 设置该属性后,该元素下的元素都会隐藏,占据的空间消失;visibility:hidden 设置该元素后,元素虽然不可见了,但是依然占据空间的位置
  • visibility 具有继承性,其子元素也会继承此属性。
  • display:none 会引起回流(重排)和重绘 visibility:hidden 会引起重绘。

15.BFC模式

  • BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域, 只有 Block-level box 参与,它规定了内部的 Block-level Box 如何布局,并且与这个区域 外部毫不相干。
  • 哪些元素会生成 BFC:
    • 元素变为浮动元素,即加float样式(非none)
    • 元素变为定位元素,即加position样式(值为absolute或fixed)
    • 元素变为弹性元素,即加display:flex
    • 给父级元素设置 overflow:hidden 或 overflow:auto
    • 元素变为行内块显示模式

16.如何清除浮动

  • 方案1 BFC模式:让标准流中父容器变为BFC模式,这样就可以保证父容器中子元素渲染不会影响外界了(即:不会引起父容器高度变化)
  • 方案2 clear:利用clear样式来清除浮动引起的父容器高度塌陷。在浮动元素后添加一个元素,并设置其clear属性为both。这会使得该元素下移,直到其顶部在所有前面的左浮动和右浮动元素下面。
  • 方案3 伪元素:在父元素中添加一个伪元素(::before,::after),并设置其clear属性为both。这种方法的优点是不需要添加额外的HTML元素。

17.如何解决margin塌陷问题

  • **第一种情况:**两个同级元素,垂直排列,上面的盒子给 margin-bottom 下面的盒子给margin-top,那么他们两个的间距会重叠,以大的那个计算。
    • 解决方法:两个外边距不同时出现
  • **第二种情况:**两个父子元素,内部的盒子给 margin-top,其父级也会受到影响,同时产生上边距,父子元素会进行粘连。解决方案:
    • 为父盒子设置 border
    • 为父盒子设定 padding 值
    • 为父盒子添加 overflow:hidden;
    • 为父盒子添加 position:fixed;
    • 为父盒子添加 display:table;

18.伪类和伪元素

  • 伪类
    • :target 选择器可用于选取当前活动的目标元素。
    • :checked 选中 单选框或复选框被选中 的元素
    • :disabled 选中禁用状态下的表单控件
    • :hover 鼠标悬浮状态下
    • :first-child 匹配第一个子元素。
    • :last-child 匹配最后一个子元素。
    • :nth-child(n) 选择属于其父元素的第 n 个子元素并且必须是<p>元素
    • :nth-last-child(n) 选择属于其父元素的倒数第 n 个子元素并且必须是<p>元素
    • :nth-of-type(n) 选择属于其父元素第 n 个<p>元素
    • :nth-last-of-type(n) 选择属于其父元素倒数第 n 个<p>元素
  • 伪元素
    • ::before 在元素前插入一个伪元素
    • ::after 在元素后面插入一个伪元素
    • ::first-letter匹配元素中文本的首字母。
    • ::first-line匹配元素中第一行的文本(只能在块元素中使用)。
    • ::selection匹配被用户选中的部分。

19.伪类和伪元素的区别

  • 伪类存在的意义是为了通过选择器,格式化DOM树以外的信息以及不能被常规CSS选择器获取到的信息。伪元素可以创建一些文档语言无法创建的虚拟元素。
  • 伪类用单冒号:表示;而伪元素用双冒号::表示。
  • 一个选择器可以同时使用多个伪类(但有的伪类会互斥);而一个选择器只能同时使用一个伪元素(未来的版本可能会支持多伪元素)。

20.使用css如何让浏览器支持比12px小的字体,比如10px

针对谷歌浏览器内核,加 webkit 前缀,用 transform:scale()这个属性进行缩放!
p span{
    display:block;
    font-size:10px;
    -webkit-transform:scale(0.8); //缩放

21.为什么要使用less、sass

  • 嵌套:允许子选择器嵌套在父选择器内,提高样式的可读性,缓解css命名冲突问题;
  • 变量:允许定义和重复使用样式中的值,轻松管理颜色、字体大小等属性;
  • 混合(Minxins):可以创建样式块,实现样式的重用;
  • 继承:允许选择器继承另一个选择器的样式,以提高代码的复用性;
  • 函数:允许自定义函数,以便执行各种操作。

22.less和sass的区别

lesssass
实现方式基于JavaScript,是在客户端进行处理的基于Ruby,是在服务器端进行处理的
语法大括号缩进
定义变量@$
变量作用域全局、局部全局(可以通过在变量后跟!default改变变量的属性值)
混合(Mixins)直接命名、直接通过命名调用通过@mixin定义、通过@include引入
继承

.a { &:extend(.b) }

.a { @extend .b }
解析方式Less可以向上/向下解析Sass只能向上解析
其他@if、@else、@for、@while、@each、@function、扩展scss




JavaScript

1.js的数据类型有哪些

  • 基本类型:null,undfiend,boolean,number,string,symbol,bigin
  • 引用类型:Object(包含Object,Array,Function)

2.ES6新增了哪些内容

        let块级作用域声明方式、const声明常量、箭头函数、模版字符串、解构赋值、展开运算符、模块、class类、Set、Map、Promise

3.常用的运行算符

  • 算术运算符:+  -  *  /  %  ++  --  **
  • 比较运算符:==  ===  !=  !==  >  <  >=  <=
  • 逻辑运算符:&&  ||  !
  • 展开运算符
  • 三元运算符

4.运算符的优先级(从高到低)

  • 小括号 ()

  • 一元运算符 delete ++ -- !

  • 算术运算符 先乘除 * / % 后加减  -

  • 移位运算符 << >>

  • 比较运算符 先大小 > < >= <= 后相等 == !=

  • 按位运算符   |

  • 逻辑运算符 && ||

  • 三元运算符

  • 赋值 = += -= *= /= %= &= |= ^= <<= >>= >>>=

5.说一下innerHTML 与 innerText的作用与区别?

  1. 作用:都可以获取或者设置元素的内容
  2. 区别:innerHTML可以解析内容中的html标签
  3. innerText不能解析内容中的html标签

6.JavaScript 由以下三部分组成:

  • ECMAScript:是JavaScript的核心,描述了语言的基本语法和数据类型。它是一套标准,定义了一种语言的规范,规定了基本语法、数据类型、关键字等的设计规范,也是解析引擎设计的参考标准,但与具体实现无关。
  • DOM(文档对象模型):是一套操作页面元素的API,可以把HTML看做是文档树,通过DOM提供的API可以对树上的节点进行操作,从而改变页面的内容和结构。
  • BOM(浏览器对象模型):是一套操作浏览器功能的API,通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等,与浏览器交互的部分功能都是通过BOM来实现的。

7.介绍 JS 有哪些内置对象?

  • 数据封装类对象:Object、Array、Boolean、Number、String
  • 其他对象:Function、Arguments、Math、Date、RegExp、Error
  • ES6 新增对象:Symbol、Map、Set、Promises、Proxy、Reflect

8.说几条写 JavaScript 书写的基本规范?

  • 代码一定要正确缩进,建议使用"二个或者四个空格"缩进
  • 语句结束使用分号;
  • 规范定义 JSON 对象,补全双引号
  • 用{}和[]声明对象和数组
  • 变量和函数在使用前进行声明
  • 以大写字母开头命名构造函数,全大写命名常量
  • 代码段使用花括号{}包裹
  • 还有要书写正确的标识标签

9.什么是标识符?

  • 在JS中,可以自定义命名的东西都属性标识符;
  • 比如变量名,函数名,参数名都是标识符

10.offsetWidth,clientWidth,scrollWidth的区别?

  • offsetWidth返回值包含 content + padding + border + 包含滚动条;
  • clientWidth返回值只包含 content + padding,不包含滚动条;
  • scrollWidth返回值包含 content + padding + 溢出内容的尺寸;

11.解释什么是Json

  • json是一种轻量级的数据交换格式,一般用于数据传递
  • 里边只允许出现双引号
  • JSON的语法表示三种类型值,简单值(字符串,数值,布尔值,null), 数组,对象

12.检测数据类型的方法有哪些

  • typeof:基本类型检测;
  • instanceof:判断a是否是b的实例;
  • Object.prototype.toString.call() :使用call把Object对象的toString方法指向value,获取value的原生构造函数名;
  • constructor:属性可能会被改写,导致检测结果不准确;

13.为什么typeof检测null等于object

       null 其实属于自己的类型 Null,而不属于Object类型。因为JavaScript 数据类型在底层是以二进制的形式表示的,二进制的前三位为 0 会被 typeof 判断为对象类型,null 的二进制位恰好都是 0 ,因此,null 被误判断为 Object 类型。 属于javascript历史遗留问题。

14.为什么typeof检测Array等于object

       在JavaScript里 array 的原型是object.prototype,所以array会显示object

15.为什么typeof检测函数不等于object

        如果一个对象实现了[[call]]方法就是function,否则为object。

16.null和undfiend的区别

  • null。表示一个空的对象指针,通常用于表示一个变量不包含任何对象。在JavaScript中,null被视为一个空值或缺少值的对象指针,它是一个被明确赋予的值,用来表示没有有效的对象引用。转化为数值是0
  • undefined。表示一个未初始化(未定义)的值,通常用于表示尚未赋值的变量。在JavaScript中,undefined是一个全局变量,在没有被赋值的情况下,默认的初始值就是undefined。当你尝试使用一个未初始化的变量时,JavaScript引擎会返回undefined。转化为数值是NAN。

17.其他类型转化成数值

  • null 转换之后是 0
  • undefined 转换之后是 NaN
  • Object 转换之后是 NaN
  • String
    • 如果字符串中都是数值, 那么就可以正常转换
    • 如果字符串是一个空串 "" / " ", 那么转换之后就是 0
    • 如果字符串中不仅仅是数字, 那么转换之后是 NaN
  • Boolean
    • true 转换之后是 1
    • false 转换之后是 0
  • Array
    • 空数组,当将其转换成number时,得到的结果为0;
    • 只有一个数字成员的数组,得到的结果是该数字;
    • 多个数字成员的数组,得到的结果为NaN;

18.介绍一下symbol?怎么迭代symbol描述的键?

  • symbol是js为了解决命名冲突而引入的一种ES6新的基本数据类型,表示独一无表示独一无二的值。
    • 独一无二性:每个 Symbol 值都是唯一的,无法通过简单的值比较相等。
    • 不可变性:Symbol 值一旦创建,就不能被修改。
    • 隐藏性:使用 Symbol 作为属性键,这些属性对于常规的对象遍历和操作是不可见的。
    • 作为属性键:Symbol 可以作为对象的属性键,用于创建对象的私有属性或隐藏属性,以避免命名冲突。
  • symbol常用的的方法
    • Symbol.for() 全局符号注册表
    • Symbol.keyFor() 查询全局注册表
    • Object.getOwnPropertySymbols() 获取对象内部symbol命名的key
    • Reflect.ownKeys() 获取对象内部所有的key

19.介绍一下bigint?为什么会出现bigint

  • bigint是js为了解决数值过大导致的精度失真问题而引入的一种ES6新的基本数据类型,表示表示任意长度的整数。
  • bigint不能直接和普通数据类型进行运算,必须保证参与运算的值都是bigint类型
  • 创建bigint的方式有两种
    • 在一个整数字面量后面添加一个字母n,如9007199254740991n
    • 使用BigInt()函数将普通整数值转换为BigInt类型,如BigInt(9007199254740991)

20.var、let、const的作用

  • var :变量声明方式,声明的变量具有变量提升,一般情况下会提升到全局,但是在函数内部会形成局部变量。支持重复声明,支持修改。
  • let:块级作用域声明方式,不具备变量提升。不支持重复声明,支持修改。
  • const:常量声明方式,不具备变量提升。不支持重复声明,不支持修改。

21.const声明的引用类型数据可以修改吗

        因为const只能浅层检测引用类型数据指针(地址),所以不能直接修改引用类型数据的指针(地址),但是可以修改引用类型数据内部的元素。

22.Math常用的方法

  • min、max、abs绝对值、PI、pow幂、sqrt平方根、sell向上取整、floor向下取整、trunc保留整数位、round四舍五入、random随机数

23.数值常用的方法

  • toFixed(digits):将数字转换为指定小数位数的字符串。
  • toPrecision(precision):将数字转换为指定有效位数的字符串。
  • isNaN(value):检查一个值是否为 NaN(非数字)
  • isFinite(value):检查一个值是否是有限数。
  • parseInt(string, radix):将字符串解析为整数。
  • parseFloat(string):将字符串解析为浮点数。
  • Number()将其他类型数据转化成数值

24.字符串常用的方法

  • 不改变原字符串:trim、toLowerCase、toUpperCase、chartAt、includes、indexOf、lastIndexOf、search、match、startsWith、endsWith、silce、substr、substring、replace、replaceAll、concat、repeat、split。

25.函数常用的方法

  • call、apply、bind

25.对象常用的方法

  • 不改变原对象:Object.keys、Object.values、Object.entries、Object.isFrozen、obj.hasOwnProperty、key in obj
  • 改变原对象:Ovject.create、Object.assign、Object.freeze、Object.defineProperty、Object.defineProperties

26.数组常用的方法

  • 改变原数组:push、pop、unshift、shift、store、reverse、splice、fill;
  • 不改变原数组:at、includes、indexOf、lastIndexOf、slice、concat、flat(Infinity)、toString、join、some、every、find、findindex、forEach、Map、flatMap、filter、reduce、reduceRight

27.伪数组

  • 伪数组的特征
    • 具有length属性;
    • 按索引方式存储数据;
    • 不具有数组的方法.
  • 伪数组转数组的方法
    • Array.from()
    • Array.prototype.slice.call()
    • 展开运算符(...)
  • 常见的伪数组
    • new Set()
    • arguments
    • document.getElementsByClassName('div')

28.循环语句

  • while:while 语句只要指定条件为 true,就会执行循环
    • 参数1:必须。定义执行循环的条件
  • do/while:先执行一次代码块,再检查条件是否为真,为真就继续循环
    • 参数1:必须。定义执行循环的条件
  • for:可以指定代码块循环的次数
    • 参数1:可选,初始化的变量,也可以指定多个;
    • 参数2:可选,条件判断语句;
    • 参数3:可选,每次循环后执行的语句;
  • for/of:用于遍历数组
    • 参数1:必须。数组的元素。
    • 参数2:必须。指定遍历的数组。
  • for in:用于迭代对象或者数组
    • 参数1:必须。对象的键或数组的索引。
    • 参数2:必须。指定迭代的的对象或者数组。
  • forEach:遍历数组
    • 参数1:对数组元素执行的回调函数
    • 参数2:this指向
    • forEach没有返回值

29.forEach、for中断循环、跳出循环?

  • forEach:中断循环try/catch/throw;跳出当前循环return;
  • for:中断循环break;跳出当前循环continue;

30.for of为什么不可以遍历对象

       对象是不可迭代的。es6中引入了iterator接口,只有提供了iterator接口的数据类型才可以使用“for-of”来循环遍历;而普通对象默认没有提供iterator接口,因此无法用“for-of”来进行遍历。

31.字符串slice和substring的区别

  • 都可以从字符串中指定起止位置提取并返回一个新的字符串,且不修改原数组。
  • 两者第二个参数都可以省略(默认提取到字符串末尾)。
  • slice如果参数是负数,则表示从字符串的尾部开始计数,。
  • substring如果任一参数是负数,它会被视为0。

32.数组去重的方法有哪些

  • Array.from(new Set())
  • arr.filter((item, index) => arr.indexOf(item) === index);
  • arr.reduce((total, item) => (total?.includes(item) ? total : [...total, item]) , []);

33.数组拍平的方法有哪些

  • arr.flat(Infinity)
  • arr.toString().split(',').map((item) => Number(item));
  • arr.reduce((total, item) => (Array.isArray(item) ? [...total, ...flat(item)] : [...total, item]),[],);

34.arguments

  •  在JavaScript函数内部,arguments对象是一个类数组对象,它存储了函数被调用时传递的所有参数。
  • 动态参数列表:arguments对象可以接受任意数量的参数。这意味着你可以在调用函数时传递任意数量的参数,而不需要在函数定义中明确指定形式参数的个数。
  • 通过索引访问参数:可以通过arguments对象的索引来访问函数的参数。例如,arguments[0]表示第一个参数,arguments[1]表示第二个参数,以此类推。
  • 类数组对象:虽然arguments对象看起来像一个数组,但它并不是一个真正的数组。它没有数组特有的方法,如push()和pop(),但可以通过length属性获取参数的数量。

35.什么是纯函数

  • 返回值取决于参数
  • 不依赖于外部状态,也不改变外部状态的函数

36.匿名函数(IIFN)

  • 匿名函数,即没有名称的函数
  • 如果单独只写一个匿名函数,此时是不符合语法要求的 会报错。需要给 匿名函数包裹一个括号,使之成为表达式。
  • 被小括号包裹的内容会被js识别为一个函数表达式

37.什么是闭包函数

  • 在函数内部声明一个函数,并且使用了外部函数的变量,被称为闭包函数
  • 闭包函数的优点:实现私有属性和方法,减少对外界的污染;
  • 闭包函数的缺点:外部函数执行完之后,内部函数不会被销毁,造成变量长期贮存,占用内存空间
  • 解决闭包:使用call,apply,bind改变内部函数的this指向;内部函数改用箭头函数
  • 使用场景:防抖、节流、缓存、封装私有变量、函数柯里化等

38.函数柯里化

        概念:把一个接收多个参数的函数变成接收单一参数 并且返回能够接收新参数的函数

39.什么是递归函数

  • 一个函数直接或间接地调用自身,称为递归。
  • 常用场景:遍历属性结构、生成斐波那契数列、深拷贝

40.什么是回调函数

  • 在javascript中,回调函数指的是一个被作为参数传递给另一个函数的函数;
  • 回调函数本身不是异步的,但是可以通过异步机制(例如事件循环、Promises、async/await)来实现异步行为,例如定时器、延时器、axios请求、hooks、事件

41.箭头函数和普通函数的区别

  • this指向。箭头函数的this在定义时就已经确定,不会在运行时改变,它继承自外围作用域的this值;普通函数的this在运行时确定,可以通过call、apply、bind方法改变。
  • 原型属性。箭头函数没有原型属性;普通函数有原型属性
  • 构造函数。箭头函数不能作为构造函数使用,不能通过new关键字调用;普通函数可以作为构造函数使用。
  • 语法形式。箭头函数使用=>符号定义,而普通函数使用function关键字定义
  • 函数体语法。箭头函数的函数体可以省略括号,但有一定的限制。如果箭头函数的函数体只有一行语句,则可以省略大括号和return关键字;如果箭头函数的函数体多于一行语句,则必须使用大括号和return关键字;普通函数的函数体必须使用大括号。
  • arguments对象。箭头函数不绑定arguments对象,但可以通过剩余参数代替;普通函数有arguments对象,用于存储所有传递的参数
  • Generator函数。箭头函数不能作为Generator函数使用,不能使用yield关键字;普通函数可以作为Generator函数。

42.Generator函数

  • Generator函数是一种特殊类型的函数,它可以在执行过程中暂停并在需要时恢复执行。当Generator函数被调用时,它并不会立即执行,而是返回一个遍历器对象(Iterator),这个对象可以逐步遍历Generator函数的内部状态。
  • Generator函数使用步骤
    • Generator 函数使用 function* 声明,通过 yield 关键字产生一个值,并挂起函数的执行。
    • 可以通过调用 iterator.next() 方法逐一遍历迭代器对象,也可以为其传参,执行后标记为未完成。
    • 当运行到 iterator.return() 语句时,迭代器对象会被标记为“完成”,不再产生新的值。
  • iterator对象的方法:
    • next()逐一遍历迭代器对象
    • return()返回return的对象同时停止迭代
    • throw()中断迭代
  • 主要用途包括:解决回调地狱、迭代和生成无限序列、替代回调函数。

function* generator() {

  yield 'one';

  yield 'two';

  return 'done';

}

const iterator = generator(); //返回一个遍历器对象

console.log(iterator.next()); //{ value: 'one', done: false }

console.log(iterator.next()); //{ value: 'two', done: false }

console.log(iterator.next()); //{ value: 'done', done: true }

43.防抖和节流

  • 防抖(debounce)和节流(throttle)是性能优化中常用的两种技术,用以控制函数执行的频率,以减少计算资源的使用。
  • 防抖:指的是在一定时间内,对于频繁触发的事件,重新计算时间,只让其最后一次触发时执行。例如搜索框、页面改变大小。
  • 节流:指的是在一定时间内,对于频繁触发的事件,只让其执行一次,例如:触底加载、页鼠标不断点击时。

44.引用类型和值类型的区别

值类型基本数据类型
存储位置栈(stack)指针存放在 栈(stack)、实体存放在 堆(heap)
数据大小固定不固定
占用空间
存取速度
数据类型简单

复杂、可嵌套

访问方式按值访问按指针访问

45.什么是深拷贝和浅拷贝

  • 深拷贝。只复制对象内容,不复制对象的指针,拷贝出来的对象是一个全新的对象,修改这个新对象的时候,不会影响源对象。
  • 浅拷贝。只复制对象的指针,不复制对象的内容,拷贝出来的新对象指针还是指向原来的对象。修改这个新对象时,原来的对象也会被修改。引用类型的数据,默认都是浅拷贝。

46.深拷贝的方法

  • JSON.stringfy(JSON.parse())
    • 取不到值为 undefined 的 key;
    • 如果对象里有函数,函数无法被拷贝下来;
    • 无法拷贝copyObj对象原型链上的属性和方法;
  • 展开运算符:只能进行浅层的拷贝
  • Object.assign :只能进行浅层的拷贝
  • 递归实现深拷贝
    • 在递归过程中,需要记录已经遍历过的对象。
    • 需要处理不同数据类型(如数组和对象)。
  • 使用插件实现
    • lodash的cloneDeep函数
    • Immutable.js生成不可变数组或对象(Map不可变对象 List不可变数组)

47.什么是同步任务和异步任务

  • js是一门单线程语言,单线程意味着所有任务都需要排队,只有前一个任务执行完之后,才能执行下一个任务。这种情况显然是不合理的,比如说我挂起一个30秒的延时器,那么后面的任务就会被阻塞,导致cpu空闲且无法执行其他任务。针对这一情况,javascript把这些阻塞进程的任务统一放在了异步任务队列中等待执行,任务队列通知主线程某个异步任务可以执行了,这个异步任务就会被放在主线程中按顺序执行。
  • 同步任务(synchronous)就是主线程中的任务,按照顺序一个个的执行,比如:普通函数、new Promise()、console.log()等等
  • 异步任务 (asynchronous) 就是任务队列中的、会阻塞到进程的任务,只有“任务队列”通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。比如:DOM 事件回调、定时器回调、网络请求的回调、promise.then()、promise.catch()的回调。异步任务又分为宏任务和微任务:
    • 宏列队 macrotask queue:用来保存待执行的宏任务(回调),比如:DOM 事件回调、定时器回调、网络请求的回调
    • 微列队 microtask queue:用来保存待执行的微任务(回调),优先级高于宏任务,比如:promise.then()、promise.catch()、MutationObserver 、queueMiscrotask()

48.宏任务和微任务的区别

  • 执行优先级不同。宏任务的优先级相对较低,而微任务的优先级较高。
  • 执行时机不同。宏任务会被添加到事件队列中,在每个事件循环中执行一次;微任务会在当前宏任务执行完毕后立即执行,而不会添加到事件队列中,微任务的执行时机是在当前宏任务的末尾,在下一个宏任务之前。
  • 用途不同。宏任务通常包括定时器任务(如setTimeout、setInterval)、网络请求、用户交互事件(如点击、滚动等),这些是相对较大的任务,需要等待一定时间或特定的触发条件才会执行;微任务通常包括Promise回调、DOM变动观察器等,这些是相对较小的任务,适合在当前宏任务执行完毕后立即执行。
  • 总结:宏任务是事件循环中的较大任务,通常处理用户交互、渲染等任务;微任务是较小的任务,通常用于处理异步操作的结果,由于微任务具有较高的优先级,它们可以在用户交互之前或渲染之前得到及时处理。

49.Promise的作用

  • Promise的主要作用是处理异步操作。它允许你以更同步的方式编写异步代码,提高了代码的可读性和可维护性。
  • 处理异步任务结果。Promise区分成功(resolve)和失败(reject)的状态,使得错误处理更加明确和直接。
  • 避免回调地狱。Promise对象可以链式调用,减少嵌套回调的使用,避免代码过于复杂和难以管理。
  • 支持并发操作。例如,使用Promise.all()可以并行执行多个操作,等待所有操作完成后执行某些逻辑。
  • 便于代码的模块化和复用。通过将异步操作封装成Promise对象,可以提高代码的复用性和模块化程度。

50.promise的三种状态?怎么改变promise的状态

  • 等待中(Pending)。这是Promise的初始状态,表示异步操作尚未开始或结果尚未确定。
  • 已完成(Fulfilled)。当异步操作成功完成并返回结果时,Promise的状态变为Fulfilled。
  • 已拒绝(Rejected)。当异步操作执行失败时,Promise的状态变为Rejected。

51.Promise.then和Promise.catch

  • Promise函数有两个参数resolve和reject,当我们调用resolve()时,Promise函数会从等待状态变为成功状态,当我们调用reject()时,Promise函数会从等待状态变为失败状态。
  • .then():在promise函数中调用resolve()后执行的函数,用于处理执行成功的结果。可以通过resolve(参数)获得参数。
  • .catch():在promise函数中调用reject()后执行的函数,用于处理执行失败的结果。可以通过reject(参数)获得参数。
  • .then和.catch都属于异步任务中的微任务。

52.promise.all和promise.race的区别

  • Promise.allPromise.race都是用于处理多个Promise实例的方法,但它们的行为和用途有所不同。
  • Promise.all。接收一个Promise数组作为参数。只有所有结果都执行成功或失败的时候,才会变为成功状态或者失败状态,否则仍然会处于等待状态。如果所有Promise都执行成功,则返回所有执行成功的结果。如果有一个执行失败,就会返回第一个执行失败的结果。
  • Promise.race。接收一个Promise数组作为参数,返回的第一个执行成功的Promise结果。
  • romise.all适用于需要等待所有异步操作完成再进行下一步处理的场景,例如并行下载多个文件并将它们合并为一个文件;Promise.race适用于需要在多个异步操作中获取最先完成的结果的场景,例如设置超时机制或不知道哪个接口响应更快的情形。

53.proimse是同步还是异步

        Promise本身是同步的Promise是一个用于异步编程的对象,它允许你以同步的方式编写异步代码,但Promise对象本身在创建时立即执行,不会造成主线程的阻塞。然而,Promise的回调函数,如then()和catch(),是异步执行的,它们会在当前脚本的所有同步任务执行完毕后调用。

54.promise.then的交替执行

        如果是单个promise实例,即使有多个then,仍然会按照顺序执行。如果是多个promise实例同时调用.then,then会出现交替执行的情况。这个是编译器做的优化,主要是为了避免某一个promise占用的时间太长。

55.怎么解决回调地狱

  • promise实现链式调用
  • generator函数
  • async/await

56.不使用promise能否把请求数据返回出来?

  • async/await
  • generator函数
  • 回调函数(类似于react中的子父传值)

57.async和await

  • asyncawait是ECMAScript 2017 (ES8)标准引入的新特性,用于简化异步操作。
  • async:用于修饰一个异步操作的函数,该函数返回一个Promise对象。如果函数中没有返回值,会默认返回一个Promise对象。如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象;
  • await:用来等待一个异步方法执行完成。后面await如果是一个 Promise 对象,返回该Promise执行成功或者失败的结果。如果不是 Promise 对象,就直接返回对应的值。注意await 只能出现在 async 函数中,await会阻塞进程。

58.原型和原型链

  • 每个对象都有一个prototype属性,表示对象的原型(prototype也是一个对象)。
  • prototype作为对象的内部属性,是不能被直接访问的,但是可以通过__proto__来访问。
  • 原型链,当访问对象的属性或方法时,首先对象会从自身去找,找不到就会往原型(prototype)中去找,如果原型(prototype)中找不到,就会往原型后面的原型上去找,这样就形成了链式的结构,称为原型链。
  • 原型链的最顶层是Object,在往上就是null。

59.this指向问题

  • 全局作用域中的函数:非严格模式下其内部this指向window
  • 对象内部的函数:其内部this指向对象本身:
  • 构造函数:其内部this指向生成的实例:
  • 由apply、call、bind改造的函数:其this指向第一个参数:
  • 箭头函数:箭头函数没有自己的this,看其外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window。(函数定义时的this,而不是调用时this)

60.怎么改变this指向?

  • call():在改变this指向的同时会调用函数
  • apply():在改变this指向的同时会调用函数,第二个参数接收的是一个数组。
  • bind():在改变this指向的同时不会调用原来的函数,而使生成并调用一个新的已经改变过this指向的函数

61.new做了什么

  • 在内存创建一个新对象
  • 把构造函数中this指向新建的对象
  • 会在新对象上添加一个__proto__属性,指向函数的原型对象prototype
  • 判断函数返回值,如果值是引用类型就直接返回值;否则返回this(创建的新对象)

62.构造函数

  • 什么是构造函数:JS中的任何一个普通函数,当用new关键字来调用时,它就是构造函数。构造函数与函数定义无关,与调用方法有关。构造函数一般首字母大写。
  • 构造函数的目的:在JavaScript中,构造函数是用来初始化新创建的对象的函数。构造函数的主要目的是在创建对象时初始化对象的属性。
  • 构造函数的意义:使用对象字面量创建一系列同一类型的对象时,这些对象可能具有一些相似的属性和方法,此时会产生很多重复的代码,把这些重复性的特征和属性抽象出来,做成构造函数,可以实现代码复用。
  • 构造函数的作用:构造新对象,设置对象的属性和方法。创建对象时完成初始化,当我们在new一个对象并传入参数的时候,会自动调用构造函数并完成参数的初始化。
  • 常见的构造函数:Object、Array、String、Boolean、Number、Date等。
  • 构造函数的this指向:
    • 当以函数的形式调用时,this是window
    • 当以方法的形式调用时,谁调用方法this就是谁
    • 当以构造函数的形式调用时,this就是新创建的那个对象
  • 自定义构造函数:
    • 首字母大写
    • 通过new创建实例对象
    • 创建构造函数时,里面的属性和方法前必须加this,this就表示当前运行时的对象
  • 返回值
    • 不写return,返回一个this对象
    • return一个基本数据类型,返回一个this对象
    • return一个复杂数据类型,返回一个复杂数据类型,比如对象、数组

63.构造函数和普通函数的区别

  • 普通函数是小驼峰的名命方式,而构造函数是大驼峰的名命方式(行业规范)。
  • 我们知道普通函数的this指向是指向全局对象的,而构造函数内部的this指向当前对象的实例。
  • 使用的方式不同,普通函数直接调用,构造函数必须使用new 来调用,通过 new.target 来判断调用的方式是不是构造函数。
  • 任何函数只要使用new操作符调用就是构造函数,而不使用new操作符调用的函数就是普通函数

63.es6class类

  • 类(class)是ES6新的基础性语法糖结构,用于创建对象的模板。可以看成构造函数的另一种写法,这种写法可以让对象原型的写法更加清晰、更像面向对象编程的语法而已。
  • 类必须使用new调用,否则会报错。普通构造函数使用new创建的是实例化对象,不使用new则执行的是普通函数的调用。
  • 类的数据类型就是函数,类本身就指向构造函数。
  • 函数受函数作用域限制,而类受块作用域限制。

64.constructor

  • constructor 方法是一个特殊的方法,用于创建和初始化一个由class创建的对象。通过 new 关键字生成对象实例时,自动会调用该方法。
  • 一个类只能拥有一个名为"constructor"构造函数,不能出现多个,如果定义了多个"constructor"构造函数,则将抛出 一个SyntaxError错误。
  • 如果没有定义"constructor"构造函数,class 会默认添加一个空的"constructor"构造函数。

65.super

  • super代表的是父类的构造函数。super可以用来调用父类的属性和方法,也可以用来调用父类的构造函数。
  • super继承。
    • ES6 class 可以通过extends关键字实现继承,同时子类必须在constructor中调用super,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象,只有调用super之后,才可以使用this关键字。
    • 子类如果没有定义constructor方法,super方法会被默认添加。
  • super方法。
    • super作为函数调用时,代表父类的构造函数。
    • super虽然代表了父类的构造函数,但是返回的是子类的实例,即super内部的this指的是子类的实例,因此super()在这里相当于A.prototype.constructor.call(this)
  • super对象。
    • 在普通方法中,指向父类的原型对象。由于super指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的。ES6 规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例。由于this指向子类实例,所以如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性。
    • 在静态方法中(statrc修饰的方法),指向父类。如果super作为对象,用在静态方法之中,这时super将指向父类,而不是父类的原型对象。在子类的静态方法中通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例。

66.构造器constructor为什么要使用super

        因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象,只有调用super之后,才可以使用this关键字。

67.继承

  • 实例继承:将子构造函数的 prototype 指向父构造函数的一个实例
  • 原型继承:将子构造函数的 prototype 指向父构造函数的 prototype
  • 构造函数绑定:使用 call 或 apply 方法,将父对象的构造函数绑定在子对象上
  • 拷贝继承:如果把父对象的所有属性和方法,拷贝进子对象
  • ES6 语法 extends:class ColorPoint extends Point {} 并在子类的构造器中调用super函数

68.什么是js严格模式

        严格模式(Strict Mode)是一种在代码中启用的特殊模式,用于提供更严格的语法和错误检查,以改善代码质量和增强安全性。使用严格模式可以帮助大家避免一些常见的错误,并禁用一些不推荐使用的特性。

  • 变量必须先声明后使用:在严格模式下,变量必须通过 var、let 或 const 关键字进行声明,否则会抛出 ReferenceError。在非严格模式下,未声明的变量会被隐式创建,并被添加到全局对象(比如浏览器环境中的 window 对象)中。
  • 禁止删除变量、函数或函数参数:在严格模式下,使用 delete 操作符删除变量、函数或函数参数会抛出 SyntaxError。
  • 禁止对只读属性进行赋值:在严格模式下,对只读属性(通过 const 关键字声明的常量)进行赋值会抛出 TypeError。
  • 禁止使用八进制字面量:在严格模式下,以 0 开头的数字会被视为八进制字面量,这在非严格模式下是允许的。严格模式下,使用八进制字面量会抛出 SyntaxError。
  • 限制 this 值:在严格模式下,函数内部的 this 值不再是全局对象(比如浏览器环境中的 window 对象),而是undefined,除非通过 call()、apply() 或 bind() 明确指定。
  • 禁止使用重复的函数参数名:在严格模式下,函数参数名不能重复。在非严格模式下,重复的函数参数名会被忽略。
  • 禁止使用 with 语句:在严格模式下,使用 with 语句会抛出 SyntaxError。with 语句在非严格模式下允许将对象的属性添加到作用域链中,但这被认为是不推荐使用的特性,因为它可能导致代码可读性和性能问题。
  • 限制 eval 和 arguments 的赋值:在严格模式下,无法对 eval 和 arguments 进行赋值。在非严格模式下,这种赋值是允许的。

69.怎么阻止表单提交默认行为

  • e.preventDefault()
  • οnsubmit事件中return false

70.js事件流是什么?怎么修改事件传播机制?怎么阻止事件传播?

  • 捕获阶段:从外向里依次查找元素
  • 目标阶段:从当前事件源本身的操作
  • 冒泡阶段:从内到外依次触发相关的行为
  • addEventListener事件监听器的第三个参数设置成true捕获false冒泡
  • event.stopPropagation() 阻止事件传播

71.dom事件委托原理,有什么优缺点

  • 事件委托原理
    • 利用事件冒泡机制,将事件监听器设置在其父节点上,通过event.target.nodeName判断是否是子节点来实现控制子节点。
  • 优点
    • 可以大量节省内存占用,减少事件注册
    • 可以实现当新增子对象时,无需再对其进行事件绑定
  • 缺点
    • 如果把所有事件都用事件代理,可能会出现事件误判

72.栈内存和堆内存

  • 在JavaScript中,数据是分为两类存储的:基本类型和对象类型。基本类型值指的是那些保存在栈内存(Stack)中的数据,而对象类型值则被保存在堆内存(Heap)中。
  • 栈内存是一种后进先出(LIFO)的数据结构,主要用于存储函数的局部变量、临时数据、书签等。当你创建一个基本类型的变量时,它会被存储在栈内存中,并且占据一块连续的空间。
  • 堆内存是用来存储对象的地方,对象可以包含多个值,大小不固定,可以动态地增加或减少。当你创建一个对象类型的变量时,这个对象会被存储在堆内存中。

73.主线程和任务队列

  • JavaScript 中的主线程和任务队列是浏览器的 JavaScript 引擎如何工作的基本概念。
  • 主线程:主线程是 JavaScript 引擎用来执行执行代码的地方。当 JavaScript 引擎开始执行代码时,程序的主线程就会被创建。
  • 任务队列:JavaScript 是单线程的,这意味着它只有一个主线程来执行代码。但是,JavaScript 引擎还有其他的任务队列,如微任务队列和宏任务队列。

74.执行栈和调用栈

        执行栈和调用栈通常是指程序在执行过程中的两种不同的数据结构。

  • 执行栈(Execution Stack):在JavaScript中,执行栈是用来存储执行上下文(Execution Context)的数据结构。每当一个函数被调用时,就会为这个函数创建一个新的执行上下文并将其推入执行栈。执行栈是后进先出(LIFO)的数据结构。当函数执行完毕,它的执行上下文就会从栈中移除。
  • 调用栈(Call Stack):调用栈是一个系统级的数据结构,用于存储一个个正在被执行的函数的地址。当一个函数调用另一个函数时,被调用的函数的地址会被添加到调用栈顶部。当这个函数执行完毕,它的地址会从调用栈顶部移除。在JavaScript中,调用栈是由JavaScript引擎管理的,开发者可以通过错误栈跟踪(stack trace)来查看调用栈的状态。

75.js事件循环机制(底层原理)

        因为js引擎存在monitoring process进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数。

        整体会把所有代码分为两个部分:‘同步任务’,‘异步任务’。所有同步任务都在主线程上执行,形成一个执行栈。主线程之外还存在一个任务队列,专门存放异步任务(宏任务和微任务)。

  • 宏任务进入到事件表(Event Table)中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到事件队列(Event Queue)中
  • 微任务也会进入到另一个事件表(Event Table)中,并在里面注册回调函数,每当指定的事件完成时,事件表(Event Table)会将这个函数移到事件队列(Event Queue)中
  • 整体script作为第一个宏任务进入主线程,当主线程的任务执行完毕,主线程为空时,会检查微任务的事件队列(Event Queue),如果有任务,就会全部执行,如果没有就执行下一个宏任务
  • 主线程不断重复上面的步骤,这就是Event Loop事件循环,只要主线程空了,就会去读取"任务队列"。这个过程会不断重复。

76.target 和 currentTarget 区别

  • 都是事件对象上的属性
  • event.target:返回触发事件的元素
  • event.currentTarget:返回绑定事件的元素(相当于事件中this)

77.浮点数精度失真

  • 计算机内部使用二进制浮点数表示法,而不是十进制。这种二进制表示法在某些情况下无法准确地表示某些十进制小数,从而导致精度丢失。
  • 解决方法
    • 保留指定位数的小数
    • 获取最大小数位,根据最大小数位乘以10的倍数
    • 使用decimal.js


浏览器

20.浏览器兼容性问题

23.什么是同源策略

24.什么是跨域请求,怎样解决跨域

25.axios发送请求无法携带token是什么原因,如何解决?

26.axios常用的api有哪些?

27.谈一下你对token验证机制的理解

28.怎样解决token过期(双token机制、请求拦截器)

25.localStorage

26.sessionStorage

27.localStorage和sessionStorage的区别

26.localStorage能储存多少数据量?数据量过大会导致什么?如何解决?

27.localstorage怎么实现跨域储存

27.session

28.cookie

26.cookie和session的区别

28.webWorker

29.webSocket

27.webpack的功能

32.http无状态协议

30.http和https的区别

31.如何优化网页打开速度

31.浏览器输入一个地址,敲下回车键

33.什么是mvc和mvvm

34.XSS攻击、CSRF攻击




react

  1. react的优缺点
    1. 优点
      • 虚拟DOM:减少对真实DOM的操作,提高性能。

      • 组件化:将代码分成一个个小的、可复用的组件,利于管理、维护。

      • 使用JSX:在React中可以嵌入HTML和JavaScript。

      • 单向数据流:React的单向数据流使得应用的状态更改时,可以更容易地追踪和调试。

    2. 缺点
      • react主要关注UI构建,并不算是一个完整的框架,基本都需要加上reactrouter和flux/redux才能写大型应用。
      • 较高的入门曲线,需要理解组件、状态、属性、状态管理等概念。

  2. vue和react有什么区别
    1. 数据流不同。Vue支持双向数据绑定,而React提倡单向数据流,即数据从父组件流向子组件,子组件不能直接修改父组件的数据。
    2. 性能优化不同。Vue通过其响应式系统和虚拟DOM自动优化性能,而React则需要开发者手动优化性能,例如通过使用shouldComponentUpdatePureComponent
    3. 状态管理不同。Vue通常使用Vuex进行状态管理,而React则更多使用Redux或Context API进行状态管理。
    4. 设计理念和架构不同。Vue最初是基于MVVM模式设计的,而React则更多地基于函数式编程和组件化思想;Vue提供了指令系统,使得模板更加易于编写和理解,而React则推荐使用JSX,它允许在JavaScript中编写类似HTML的模板语法。
  3. 单向数据流
    1. 单向数据流是一种数据流动模式,数据只能从父组件流向子组件,子组件不能直接修改父组件的数据。这种模式有助于简化状态的管理和维护,降低了组件之间的耦合度,提高代码的可维护性和可预测性。
  4. diff算法
    1. diff 算法是一种用于比较虚拟 DOM 树的两个版本之间差异的算法。这使得 React 可以高效地更新真实 DOM,只应用必要的更改,而不是重新渲染整个组件树。

      1. Tree Diff: DOM树对比,逐层对比。

      2. Component Diff: 组件对比,比较同一层级的相同组件类型间的差异。

      3. Element Diff: 标签对比,对比标签名、标签属性、标签内容。

  5. 什么是虚拟dom
    1. 虚拟DOM(Virtual DOM)是一种抽象层,它使用普通的JavaScript对象(JS对象)来描述DOM(文档对象模型)结构。
    2. 虚拟DOM对象通常包含标签名、属性和标签内容等信息,这些信息与真实的DOM树结构相对应,但虚拟DOM不是真实的DOM节点,因此被称为“虚拟”。
    3. 虚拟DOM的实现基于一种设计思想,即通过比较新旧虚拟DOM树的差异,从而最小化对真实DOM进行的操作,以提高性能和效率。
  6. react渲染dom的流程
    1. 首先使用JSX创建react元素结构,这个元素结构就是后期生成虚拟dom的模版;

    2. babel会把这些元素结构编译成react.createElement()

    3. React.createElement()会将这些元素转化成虚拟dom

    4. 最终render函数会将这些虚拟dom渲染成真实dom,插入文档中。

    5. 如果后续数据发生变化,React就会生成新的虚拟dom,通过diff算法同层对比新旧dom,重新渲染发生变化的dom。

  7. react中key的作用
    1. key是列表通过map循环时给循环标签添加的属性,用于标记每一个循环元素。
    2. 在列表数据更新时,react可以通过key可以判断元素是新创建的还是被移动的元素,从而减少不必要的元素渲染。
    3. 如果使用index作为key值,当我们改变列表元素的顺序时,就会导致该元素后面的所有元素的key发生变化,元素也会重新渲染,
  8. 什么是受控组件和非受控组件
    1. 受控组件:指的是受react状态控制的表单控件,通过setState来驱动数据变化,需要绑定onChange和value属性。
    2. 非受控组件:指的是不受react状态控制的组件,表单数据由dom本身处理。非受控组件可以通过ref访问dom获得表单的值。
  9. 有状态组件和无状态组件
    1. 有状态组件:也被称为类组件,通过class类定义,拥有自己的状态数据,生命周期函数,适用于处理各种业务逻辑。
    2. 无状态组件:也被称为函数组件,没有自己的状态数据,生命周期函数,渲染结果由props决定,一般仅用于展示数据。
  10. 组件之间的通讯方式有哪些
    1. 父子传值
    2. 子父传值
    3. Context上下文传值
    4. redux
  11. 路由跳转时如何传递数据
    1. 通过url的?传值,可以通过useSearchParams.get()或者location.query获取
    2. 通过url的/传值,可以通过useParams()获取
    3. 通过query对象传值,可以通过useLocation.query获取
    4. 通过state传值,可以通过useLocation.state获取
  12. 什么是高阶组件(HOC)
    1. 接受一个组件作为参数,可以对这个组件进行操作,最终返回一个增强的组件。
  13. 高阶组件有哪些实现方式
  14. 什么是渲染劫持
    1. ​​​​​​​根据条件判断是否对组件渲染进行拦截
  15. react严格模式
  16. 什么是jsx?jsx的特点
    1. ​​​​​​​jsx中可以使用html、css、js
  17. 使用jsx有哪些注意事项
  18. 组件懒加载
  19. Fragment的作用
    1. ​​​​​​​空标签,既有标签容器的作用又不会生成额外的标签元素

  1. 说一说你对类组件的理解
  2. 类组件中常用的生命周期函数
  3. state和props的区别
    1. ​​​​​​​state是组件的状态,可以任意修改。
    2. props是外部传递给组件的参数,不能直接修改。
  4. shouldComponentUpdate()
    1. ​​​​​​​是否允许组件更新
  5. getDerivedStateFromProps()
    1. ​​​​​​​根据props更新state
  6. PureComponent类
  7. forceupdata()
    1. ​​​​​​​强制渲染页面
  8. this.setState如何获取修改后的最新值
    1. ​​​​​​​从第二个参数回调函数中获取
  9. state中的数据可以不用this.setState修改
    1. ​​​​​​​使用this.setState修改会生成虚拟dom,重新渲染页面。
    2. 不使用则不会重新渲染页面
  10. this.setState是同步的还是异步的
    1. ​​​​​​​在受react控制的情况下是异步的;
    2. 在不受react控制的方法中是同步的,比如说setTimeout
  11. 类组件对于引用类型数据如何进行渲染优化
    1. ​​​​​​​转化成字符串进行对比;
    2. 对比引用类型数据里面的属性
  12. 类组件中声明数据的方式
    1. ​​​​​​​在state中声明
    2. 在组件中直接声明

  1. 说一说你对hooks组件的理解
  2. hooks组件中常用的hooks
  3. useState和useReducer的区别
  4. useCallBack和useMemo的区别
  5. React.memo
  6. hooks为什么只能在组件最上层使用​​​​​​​
    1. hooks的实现就是基于fiber的。每个组件都会生成一个 FiberNode(节点),组件内使用的 hook 会以链表的形式挂在 FiberNode 的 memoizedState 上面。各个 FiberNode 汇聚起来会变成一颗 Fiber 树,React 每次会以固定的顺序遍历这棵树,这样就把整个页面的 hook 都串联起来了。
    2. react按照固定的顺序来执行hooks的,在循环、判断、嵌套中使用,就会打乱hooks的 调用的顺序,就会导致 react 无法区分出对应的 hook
  7. 自定义hooks
    1. 自定义 Hooks 是 React 中一种重用逻辑的方式。它们允许我们将组件逻辑提取到可重用的函数中,以便在多个组件中共享。自定义 Hooks 通常以"use"开头;​​​​​​​​​​​​​​
    2. 应用场景:管理Table分页器状态。

  1. 介绍redux
  2. RTK(Redux Tool Kit)
  3. redux和RTK的区别
  4. redux如何处理异步action
  5. redux异步action的作用




脚手架相关

1.yarn和npm的区别

2.yarn常用指令

3.npm常用指令

4.nvm

2.webpack

3.webpack打包流程

4.webpack常见的loader

5.tree shaking

6.tree shaking工作原理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/3332.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI-数学-高中-44导数的运算法则

原作者视频&#xff1a;【导数】【一数辞典】3导数的运算法则&#xff08;略难&#xff09;_哔哩哔哩_bilibili 三种求导表达方式一样的&#xff0c;中间的比较常用&#xff1a; 链式法则&#xff1a;从外向内&#xff1a;

Redis学习(三)| Redis高可用和容错机制详解

文章目录 高可用性主从复制&#xff08;Master-Slave Replication&#xff09;哨兵&#xff08;Sentinel&#xff09; 容错性数据持久化哨兵&#xff08;Sentinel&#xff09; 高可用vs容错性概念关联 结论 Redis&#xff08;Remote Dictionary Server&#xff09;是一种高性能…

如何部署Tensorrtx

因为模型跑起来太慢了&#xff0c;所以想要运用tensorrtx进行加速。但是这个是有难度的&#xff0c;且网络上的教程大多写的不是很好。我将以一个新人的视角&#xff0c;从头开始部署基于yolov5的tensorrtx加速。 知识补充&#xff1a;TensorRT和TensorRTX的区别 tensorRT是英…

Leaflet加载geowebcache的WMTS服务

方法1&#xff1a;leaflet.TileLayer.WMTS插件 插件地址https://github.com/alexandre-melard/leaflet.TileLayer.WMTS 用法示例https://hanbo.blog.csdn.net/article/details/80768710 我的示例代码 <!DOCTYPE html> <html lang"zh"> <head><…

【C++】117 填充每个节点的下一个右侧结点指针

给定一个二叉树&#xff1a; struct Node { int val; Node *left; Node *right; Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将 next 指针设置为 NULL 。 初始状态下&#xff0c;所有 next 指…

统一SQL 支持Oracle cast函数转换

统一SQL介绍 https://www.light-pg.com/docs/LTSQL/current/index.html 源和目标 源数据库&#xff1a;Oracle 目标数据库&#xff1a;Postgresql&#xff0c;TDSQL-MySQL&#xff0c;达梦8&#xff0c;LightDB-Oracle 操作目标 在Oracle中&#xff0c;cast函数允许将一种…

yolov8 区域声光报警+计数

yolov8 区域报警计数 1. 基础2. 报警功能2. 1声音报警代码2. 2画面显示报警代码 3. 完整代码4. 源码 1. 基础 本项目是在 yolov8 区域多类别计数 的基础上实现的&#xff0c;具体区域计数原理可见上边文章 2. 报警功能 设置一个区域region_points&#xff0c;当行人这一类别…

XiaodiSec day028 Learn Note 小迪安全学习笔记

XiaodiSec day028 Learn Note 小迪安全学习笔记 记录得比较凌乱&#xff0c;不尽详细 day 28 还是 sql 注入 知识点 提交方式的注入 在 php, spring boot, flask 都有相关的提交方式 提交方式的注入 数据以某种方式提交到后端 数据大小和数据类型和提交方式有关 如身份…

链栈的基本操作(c语言实现)

栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 栈的结构 定义栈…

【JAVA】503.下一个更大元素II | 42. 接雨水 | 84.柱状图中最大的矩形

class Solution {public int[] nextGreaterElements(int[] nums) {int len nums.length;int[] res new int[len];Deque<Integer> stack new LinkedList<>();Arrays.fill(res,-1);for(int i 0 ;i<len*2; i){//循环数用取模的方式int j i % len;while(!stack…

JVM虚拟机监控及性能调优实战

目录 jvisualvm介绍 1. jvisualvm是JDK自带的可以远程监控内存&#xff0c;跟踪垃圾回收&#xff0c;执行时内存&#xff0c;CPU/线程分析&#xff0c;生成堆快照等的工具。 2. jvisualvm是从JDK1.6开始被继承到JDK中的。jvisualvm使用 jvisualvm监控远程服务器 开启远程监控…

C#参数修饰符params

C#参数修饰符params params 关键字允许在 C# 中指定一个方法参数&#xff0c;该参数接受可变数量的参数。这意味着你可以传递一个由指定类型的参数组成的逗号分隔的列表&#xff0c;编译器会将它们打包成一个数组。 示例 : using System;class Program {static void Main(st…

智能家居—ESP32开发环境搭建

相关文章 毕业设计——基于ESP32的智能家居系统(语音识别、APP控制) 智能家居—ESP32开发环境搭建 一、下载安装二、验证三、资料获取 一、下载安装 下载安装 vscode 安装插件 创建工程 二、验证 写一个简单的函数来验证一下功能 void setup() {// put your setup c…

SpringMVC笔记——SpringMVC基础Tomcat环境配置

Tomcat安装配置 下载Apache Tomcat 进入官网https://tomcat.apache.org/&#xff0c;选择tomcat 9 这边使用idea开发&#xff0c;建议直接下载压缩包 无法访问下载的可以直接用我的下载链接&#xff1a;https://cloudreve.zxbdwy.online/s/6nSA 提取码&#xff1a;w1pwk3将压…

婚姻情感 20

婚姻情感 20 怎么和异性聊天&#xff1f;1. 第一步&#xff1a;判断关系2. 第二步&#xff1a;适应状态3. 第三步&#xff1a;信号识别4. 第四步&#xff1a;反应判断5. 第五步&#xff1a;深层控制6. 第六步&#xff1a;复盘定局7. 第七步&#xff1a;破局操控场景描述 怎么和…

【Java并发知识总结 | 第七篇】Java并发相关概念总结(程序/进程/线程、并行/并发、同步/异步、死锁/避免、线程安全/三大特性)

文章目录 7.并发相关概念总结&#xff08;程序/进程/线程、并行/并发、同步/异步、死锁/避免、线程安全/三大特性&#xff09;7.1程序、进程与线程7.2并行和并发7.3同步和异步7.4什么是死锁&#xff1f;如何避免&#xff1f;7.5何为线程安全&#xff1f;以及三大特性 7.并发相关…

java多线程-并发和并行

进程 并发 进程中的线程是由CPU进行调度的&#xff0c;但是CPU能够处理的进程数量有限为了保证所有的线程都在运行&#xff0c;CPU会快速切换&#xff0c;给外界的感觉就是所有的线程都在运行&#xff0c;这就是并发。 并行

【毕设绝技】基于 SpringCloud 的在线交易平台商城的设计与实现(一)

毕业设计是每个大学生的困扰&#xff0c;让毕设绝技带你走出低谷迎来希望&#xff01; 基于 SpringCloud 的在线交易平台商城的设计与实现 一、摘 要 随着互联网的快速发展&#xff0c;人们对商品经济的消费和思考不再停留在传统的经济模式上&#xff0c;网上购物商城是企业与…

安卓手机APP开发__媒体开发部分__常见问题答疑解惑

安卓手机APP开发__媒体开发部分__常见问题答疑解惑 目录 1.修复"Cleartext HTTP traffic not permitted"错误 2.修复"SSLHandshakeException", "CertPathValidatorException" 和 "ERR_CERT_AUTHORITY_INVALID" 错误 3.为什么一些媒…

vue3第二十三节(全局属性方法应用)

vue2 与 vue3 的全局属性使用方法区别 1、globalProperties getcurrentinstace vue3 中已经移除对外暴露 getcurrentinstace,建议使用下面两种 2、provide | inject 3、mitt 事件总线程 1、vue2 通过 prototype 实例上挂载属性/方法,用于全局调用 // main.js import Vue from…