面试准备 2023.04.17

1.深拷贝:1.JSON.parse(JSON.stringify(obj)) 有缺陷  2.递归拷贝完美  deepCode 

浅拷贝:1. b = Object.assign({}, a); 2.for  in 3.拓展运算符(...) 

2.原型和原型链,作用域和作用域链

5fde253b315049babbf5e0fd87013b2d.png

3.前端性能优化

 a. 减少重绘和回流、缓存DOM选择与计算、尽量使用事件代理、尽量使用id选择器、touch事件优化  b.延迟加载、懒加载技术 c.减少了http请求数 d.设置合理的http缓存 e.压缩代码,并在服务器端设置GZip

    react性能优化是哪个周期函数? shouldComponentUpdate()

4.防抖和节流

防抖就是防止抖动,避免事件的重复触发

节流控制事件触发的频率

5.回流和重绘

重绘:不会影响页面布局,但是颜色或背景变了,就会重新渲染页面

回流:当增加或删除dom节点,或者给元素修改宽高时,会改变页面布局,那么就会重新构造dom树然后再次进行渲染

  • 重绘不会引起dom结构和页面布局的变化,只是样式的变化,有重绘不一定有回流。
  • 回流则是会引起dom结构和页面布局的变化,有回流就一定有重绘。
    不管怎么说都是会影响性能。

怎么进行优化或减少?
1.多个属性尽量使用简写,例如:boder可以代替boder-width、boder-color、boder-style
2.创建多个dom节点时,使用documentfragment创建
3.避免使用table布局
4.避免设置多层内联样式,避免节点层级过多
5.避免使用css表达式
6.将频繁重绘或回流的节点设置为图层,图层能够阻止该节点的渲染行为影响到别的节点(例:will-change\video\iframe等标签),浏览器会自动将该节点变为图层

6.es6新增特性

1.新增了块级作用域(let,const)
2.提供了定义类的语法糖(class)
3.新增了一种基本数据类型(Symbol
4.新增了变量的解构赋值
5.函数参数允许设置默认值,引入了rest参数,新增了箭头函数
6.数组新增了一些API,如isArray / from / of 方法;数组实例新增了 entries(),keys() 和 values() 等方法。
7.对象和数组新增了扩展运算符
8.ES6新增了模块化(import / export)
9.ES6新增了Set和Map数据结构。
10.ES6原生提供Proxy构造函数,用来生成Proxy实例
11.ES6新增了生成器(Generator)和遍历器(Iterator)

7.闭包

函数嵌套函数,内部函数可以引用外部函数的参数和变量。参数和变量不会被垃圾回收机制收回。

缺点:相较于普通函数要消耗内存,容易内存泄漏;

优点:

1.可以让一个变量长期在内存中不被释放

2.避免全局变量的污染,和全局变量不同,闭包中的变量无法被外部使用

3.私有成员的存在,无法被外部调用,只能直接内部调用

垃圾回收机制有两种:1.标记清除, 2.引用计数

8.虚拟dom的理解

  • 虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象
  • 状态变更时,记录新树和旧树的差异
  • 最后把差异更新到真正的dom中

  优势

  • 操作 DOM 前对数据进行对比,只有数据变化的时候才去操作 DOM;
  • 会整合 DOM 操作,可以减少 DOM 操作,提升性能;
  • 便于和其他平台集成,虚拟 DOM 可以映射成 Web DOM,Android 控件,IOS 控件;

react diff算法的3个策略

  • Web UI 中DOM节点跨层级的移动操作特别少,可以忽略不计
  • 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。
  • 对于同一层级的一组子节点,它们可以通过唯一id进行区分。

9.websocket的底层协议

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。

过程:首先,客户端发起http请求,经过3次握手后,建立起TCP连接;http请求里存放WebSocket支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等;
然后,服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据;
最后,客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工通信。

10.redux的工作流程

75e02503f8374e88a1678083336f0d71.png

1)首先我们要确定我们要做什么
2)让Action Creators创建action(也就是你要做的事情)
3)通过dispatch将action分发出去
4)store对要使用的reducer进行绑定,然后将action分发到对应的reducer上
5)在reducer上进行相应的action操作并返回结果给store
6)组件就可以通过store的API像store进行获取操作返回的结果

11.箭头函数

箭头函数没有原型prototype,因此箭头函数没有this指向。它会捕获自己定义所处的外层执行环境,并且继承这个this值。箭头函数的this指向在被定义的时候就确定了,之后永远都不会改变。

12.内存泄露是什么,怎么导致的

内存泄漏指任何对象在不再拥有或需要它之后却仍然存在。JavaScript中的内存泄漏大部分是由不合理的引用导致的。

1.意外声明全局变量 2.定时器导致的泄露 3.闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环),

如何避免:可以在 JavaScript 文件开头添加 “use strict”,使用严格模式;

在变量声明前面加上var、let或const关键字;

使用this关键字;

使用完之后,对其赋值为null或者重新分配

13.react 生命周期

[1]挂载阶段 constructor、componentWillMount、render、componnetDidMount

[2]更新阶段 shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate

[3]卸载阶段 componentWillUnMount

【一个特殊的声明周期】shouldComponentUpdate

14.父组件获取子组件:ref;React.findDomNode();React.Children.map()

15.js的基本类型和引用类型:

1.基本类型:number、boolean、string、undefined、 null

2.引用类型:array、object、function、regexp…

16.hash模式 # 和history模式区别

路由器默认的工作模式是hash模式

  • HashRouter原理:

window.onhashchange监听,{ Provider, Consumer } = React.createContext()来传递,window.location对象中的属性,hash,state。
该模式下:window.location.hash,页面只会加载对应的组件。

hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。

  • BrowserRouter原理:

window.history API,只有点击前进回退按钮,或者api触发history.go(),history.goBack(),history.forward()可以触发window.onpopstate事件;该模式下使用window.location.pathname/window.location.href()修改路径(或者原路径),页面都会重新加载渲染。
该模式下:浏览器中触发前进、后退按钮页面不会重新加载,只会加载对应的组件

利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)。
这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。

17. async 和await 

异步方法同步调用。

async 函数(包含函数语句、函数表达式、Lambda表达式)会返回一个 Promise 对象,如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象

await 命令后面的 Promise 对象,运行结果可能是 rejected,所以最好把 await 命令放在 try...catch 代码块中。

18.事件循环 event loop ---宏任务微任务

宏任务是由宿主(浏览器、Node)发起的,而微任务由 JS 自身发起

19.ajax

AJAX 就是异步的 JS 和 XML 的缩写,目前我们一般用 JSON 代替 XML。

AJAX 主要用于在不刷新页面的情况下向浏览器发起请求并接受响应,最后局部更新页面。

该技术最核心概念是 XMLHttpRequest 对象,该对象可发起 HTTP 请求,我们可以监听其 readystate 的变化获得响应。

优点是无刷新请求。缺点是被浏览器限制不能跨

20 .数组去重

a.sort 排序   b.双重for循环  c.for循环加上indexOf   d.map  e.set ...

21.call 和 apply 和bind

相同点:call、apply和bind都是JS函数的公有的内部方法,他们都是重置函数的this,改变函数的执行环节。

不同点:bind是创建一个新的函数,而call和aplay是用来调用函数;call和apply作用一样,只不过call为函数提供的参数是一个个的,而apply为函数提供的参数是一个数组。

22.webpack

打包流程:

  1. 初始化参数阶段。
    这一步会从我们配置的webpack.config.js中读取到对应的配置参数和shell命令中传入的参数进行合并得到最终打包配置参数。

  2. 开始编译准备阶段
    这一步我们会通过调用webpack()方法返回一个compiler方法,创建我们的compiler对象,并且注册各个Webpack Plugin。找到配置入口中的entry代码,调用compiler.run()方法进行编译。

  3. 模块编译阶段
    从入口模块进行分析,调用匹配文件的loaders对文件进行处理。同时分析模块依赖的模块,递归进行模块编译工作。

  4. 完成编译阶段
    在递归完成后,每个引用模块通过loaders处理完成同时得到模块之间的相互依赖关系。

  5. 输出文件阶段
    整理模块依赖关系,同时将处理后的文件输出到ouput的磁盘目录中。

loader:

webpack需要loader预处理,因为它只认识Js。 所以loader就是个搞预处理工作的,它的职业是人类世界的翻译官。

es6-es5需要用babel-loader处理。

23.ts会考什么呢

ts:ts 是 js 的超集,即在原有的js语法基础上,添加强类型并切换为基于类的面向对象语言。

  优点:编译时,主动发现并纠正错误;强类型语言,支持动态和静态的类型检测

  复杂特性:模块化、接口、泛型

泛型:泛型是指在定义函数、接口或类的时候,不预先指定具体的类型,使用时再去指定类型的一种特性。可以把泛型理解为代表类型的参数

方法重写:子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写

never和void:void 表示没有任何类型(可以被赋值为 null 和 undefined)。
never 表示一个不包含值的类型,即表示永远不存在的值。
拥有 void 返回值类型的函数能正常运行。拥有 never 返回值类型的函数无法正常返回,无法终止,或会抛出异常。

24.BFC-块级格式化上下文

将BFC看成是一种属性,当拥有该属性的元素就相当于一块独立的区域

实现bfc属性的方法

1.浮动元素,float 除 none 以外的值
2. 定位元素,position的值不是static或者relative。
3. display 为 inline-block 、table-cell、table-caption、table、table-row、table-row-group、
  table-header-group、table-footer-group、inline-table、flow-root、flex或 inline-flex、grid或 inline-grid
 4. overflow 除了 visible 以外的值(hidden,auto,scroll)
 5. 根元素<html> 就是一个 BFC

作用:避免外边距重叠(放置margin塌陷);清除浮动

25. var let const

1.var声明的变量是函数变量(全局变量和局部变量),会有变量提升的风险,可以先使用再声明,尽量少用。

2:let声明的变量具有块级作用域的特性,即只能在声明的代码块中使用,只能先声明之后才能使用。

3:const声明的变量是常量,常量的值不允许更改,如果常量是引用类型(对象或者数组),那么可以更改常量内部属性的值。

26.跨域

跨域:当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。跨域问题出现的基本原因是浏览器的同源策略

解决方法:jsonp 构建script传送,返回json数据的包装;cors 响应头部Access-Control-Allow-Headers:'*';websocket;nginx反向代理

27.cookie、localstorage、sessionstorage

e23d847f297e400ebe01deb6f10fab51.png

28.get 与 post 

4ead40774f8f46618e2cb856d779d389.png

29.类组件和函数组件

类组件:在里面可以写入状态、生命周期、构造函数
写法:继承React.componnent

函数组件:只能实现非常简单的渲染功能。只是进行页面的展示和数据的渲染。没有逻辑的处理。也就是组件的内部是没有自己的数据和状态的。它是无状态组件。
通常仅是接受外部传来的数据进行展示,不涉及state,只根据props,不用this.props

30.判断变量类型

1.typeof判断基本类型,返回类型(不能判断null、array、function、object类型,会返回object)。typeof对于丰富的对象实例,只能返回object,导致有时候得不到真实的数据类型。

2.instanceof instanceof用来判断对象,代码形式(obj1 instanceof obj2)(判断obj1是否为obj2的实例),obj2必须为对象,否则会报错。返回的是布尔值。
instanceof可以对不同的实例对象进行判断,判断方法是根据对象的原型链依次向下查询,如果obj2的原型属性存在于obj1的原型链上,(obj1 instanceof obj2)值为true。

3.Object.prototype.toString.call()

可以判断所有类型,但是不能准确判断personPerson类的实例,返回如下:

**正则表达式**
var reg = /[hbc]at/gi;
Object.prototype.toString.call(reg); // "[object RegExp]"

31.react 特性

1.虚拟dom 2.jsx语法 3.组件开发模式 4.函数式编程 5.react独立架构(flux架构)(核心是单向数据流)(响应式框架)

优点:引入了虚拟DOM的概念,运行速度快;提供了标准化的API,解决了跨浏览器问题、兼容性更好;代码更加模块化,重用代码更容易,可维护性高。

32.受控组件和非受控组件

1.受控组件,简单来讲,就是受我们控制的组件,组件的状态全程响应外部数据

2.非受控组件,简单来讲,就是不受我们控制的组件

一般情况是在初始化的时候接受外部数据,然后自己在内部存储其自身状态

c0fc73c7ace54bdab33fe088f969b073.png

33.面向对象

面向对象是一种编程思想。

面相过程的思维方式,它更加注重这个事情的每一个步骤以及顺序。他比较直接高效,需要做什么可以直接开始干。

面向对象的思维方式,它更加注重事情有哪些参与者,需求里面有哪些对象,这些对象各自需要做些什么事情。将其拆解成一个个模块和对象,这样会更易于维护和拓展。

面向对象三大特性:封装、继承和多态

多态:多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作。

存在的需要有三个必要条件:继承、重写、父类引用指向子类对象。

封装:通过访问修饰符(如 private)来修饰成员变量和成员方法,将不需要对外提供的内容都隐藏起来,提供公共方法对其访问。

封装的好处是:

  1. 隐藏实现细节,提供公共的访问方式

  2. 提高了代码的复用性

  3. 提高安全性

继承:主要用途是将子类存在共性的东西,把它抽取出来放到父类里面,比如将共同拥有的属性和方法抽取出来放到父类里面。

继承的好处:

想要使用这些属性和方法的时候,可以直接去使用父类的,而不需要自己再重新去定义,更大程度的实现代码复用。

我们不需要写很多的冗余的代码,把共性的全部抽到父类,可以直接调用,如果需要个性化自定义子类的方法时,去重写父类的方法即可。

34.JSX的本质

JSX 元素本质是调用 React.createElement(component, props, ...children) 的语法糖。

React 不强制使用 JSX,也可以直接调用 React.createElement

 特点:JSX 是一种 JS 扩展的表达式;
JSX 是带有逻辑的标记语法,有别于 HTML 模版;
JSX 支持样式、逻辑表达式和事件。

35.react组件之间的通讯方法

父组件 => 子组件:

1.Props       

2.ref

子组件 => 父组件:

1.回调函数-子组件通过调用父组件传来的回调函数,从而将数据传给父组件

2.事件冒泡机制

3.ref

兄弟组件之间:

通过父组件当作中间层

不太相关的组件之间:

Context------React.createContext (组件层级很深的)

Portals

Global Variables

Observer Pattern(观察者模式)

Redux等

36.封装组件时会注意什么

  1. 尽可能低耦合,组件之间的依赖越小越好
    比如不要直接修改父组件状态。
  2. 最好从父级传入所需信息,不要在公共组件中请求数据
  3. 传入数据添加校验
  4. 处理事件的方法写在父组件中
  • 易用性
  • 拓展性
  • 可维护性
  • 可重用性

37.写一个搜索引擎(seo)时需要注意什么

1.合理的title、description、keywords:搜索对着三项的权重逐个减小,title值强调重点即可,重要关键词出现不要超过2次,而且要靠前,不同页面title要有所不同;description把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面description有所不同;keywords列举出重要关键词即可
2. 语义化的HTML代码,符合W3C规范:语义化代码让搜索引擎容易理解网页
3. 重要内容HTML代码放在最前:搜索引擎抓取HTML顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容一定会被抓取
4. 重要内容不要用js输出:爬虫不会执行js获取内容
5.少用iframe:搜索引擎不会抓取iframe中的内容
6.非装饰性图片必须加alt
7. 提高网站速度:网站速度是搜索引擎排序的一个重要指标

react优化:React应用程序的SEO优化是实现在线业务成功的关键一步。通过使用React SSR、React Helmet、确保链接可被搜索引擎检索、优化代码大小和加载速度以及使用Google Analytics等工具来跟踪SEO表现等技巧

38.useEffect 冷门知识

 useEffect方法的第一个参数是一个函数,函数可以return一个方法,这个方法就是在组件销毁的时候会被调用

第二个参数可以是监听器数组,也可以是消除副作用函数

39.useMemo和useCallback

useCallback 和 useMemo 都是react可用于性能优化的内置hooks,避免非必要的re-render 。

 两者的区别在于:useCallback缓存的是一个函数,而useMemo缓存的是计算结果。

usecallback用来避免父组件每次re-render时,传递给子组件的函数props也重新创建造成子组件不必要的re-render。

useMemo 优化1.需要大量时间执行的函数;2.引用类型的变量。

40.浏览器兼容和适配

1.不同浏览器默认的margin,padding不同:在css文件中重置margin和padding为0

2.ie9以下不能使用opacity

3.图片默认有边距:使用float浮动

4.min-height是个不兼容的css属性:设置一个最小的height

5.时间的格式

等等

41.响应式布局

响应式布局指的是同一页面在不同屏幕尺寸下有不同的布局。

媒体查询;rem;百分比;flex;vh/vw

42.flex布局

在父元素上,我们经常会用到的有关弹性布局的属性主要有 flex-direction , flex-wrap , justify-content , align-items , align-content ,这几个属性分别从 主轴的方向、是否换行、项目在主轴上的对齐方式、项目在交叉轴上的对齐方式、项目在多根轴线上的对齐方式来规范了项目在父元素中的弹性。

在子元素上,我们经常会用到的有关弹性布局的属性主要有 order , flex-grow , flex-shrink ,flex-basis , align-self ,这几个属性分别从 项目的排序、项目放大比例、项目缩小比例、项目占据主轴空间、单个项目在交叉轴上的对齐方式来规范了项目自身的弹性。

43.标准盒模型和怪异盒模型

在标准的盒模型中一个盒子的宽度是:margin(左右外边距)+padding(左右内边距)+border(左右边框)+内容的(width).

怪异盒模型中:一个盒子的宽度=内容的(width)+margin(左右)(这里的内容width包含了padding(左右内边距)+border(左右边框))。

两种模式的转换(通过box-sizing的方法)
box-sizing中比较常用的两个属性值为 content-box 和 border-box ,它可以改变盒子模型的解析计算模式。

当设置box-sizing:content-box时,采用标准模式进行计算,默认就是这种模式;
当设置box-sizing:border-box时,采用怪异模式进行计算;

44.margin塌陷问题

在垂直方向如果有两个元素的外边距有相遇,在浏览器中加载的真正的外边距不是两个间距的加和,而是两个边距中值比较大的,边距小的塌陷到了边距值大的值内部。

45.JavaScript关于事件的兼容性问题及解决方法

1、事件对象本身
标准浏览器是发生时自动给方法传一个实参,IE是全局的window.event
解决方法:e = e || window.event

2、事件源
标准浏览器是e.target,IE下是e.srcElement,
解决办法是:let target = e.target || e.srcElement

3.dom二级事件绑定

标准浏览器是element.addEventListener,IE下是element.attachEvent,解决办法是通过if判断

4、阻止事件传播
标准浏览器是e.stopPropagation,IE是e.cancelBubble = true这个属性

5、阻止默认行为
标准浏览器是e.preventDefault() 方法,IE是e.returnValue = false

6、相对于文档的鼠标坐标
标准浏览器是e.pageX,e.pageY,但IE不支持这两个属性,但都支持clientX,clientY,这是相对于浏览器的鼠标坐标,可以通过scrollTop+clientY来实现。

46.强制缓存和协商缓存

强制缓存:根据Expires(response header里的过期时间)判断,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存,并不会向服务端发起请求,展示为200状态。

协商缓存:客户端向服务端发送带有If-None-Match和If-Modified-Since的请求进行协商判断,如果资源没有变化继续使用本地缓存,记录为304状态(请求已执行,但文件没变化);如果资源发生变化,服务端响应数据,记录为200状态。

 47.setState

setState不是真异步,而是看上去是异步的,在源码中通过isBacthingPudates判断真异步还是同步。
异步更新:在生命周期,react合成事件中
同步更新:原生事件中,如addEventListener, setTimeout setInterval

48.promise.all 和promise.race

promise.all():该方法用于将多个Promise实例,包装成一个新的Promise实例。

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

Promise.race()是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败

 使用场景: Promise.all和Promise.race都是有使用场景的。 有些时候我们做一个操作可能得同时需要不同的接口返回的数据,这时我们就可以使用Promise.all; 有时我们比如说有好几个服务器的好几个接口都提供同样的服务,我们不知道哪个接口更快,就可以使用Promise.race,哪个接口的数据先回来我们就用哪个接口的数据。

49.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值