金秋十月,面试题

23 篇文章 0 订阅
17 篇文章 1 订阅

js中的let 和 const
let声明的变量只在let命令所在的
代码内有效。

const 声明一个只读的常量, 一旦声明, 常量的值就不能改变。

代码块内有效

let 是在代码块内有效,var 是在全局范围内有效:

判断数据类型:
typeof

instanceOf

constructor

object.prototype.toString.call()

let与const都是只在声明所在的块级作用域内有效。

let声明的变量可以改变,值和类型都可以改变,没有限制。

const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

项目中使用闭包
函数嵌套函数, 内部函数可以访问外部函数的变量,

useCallback和useMemo的参数跟useEffect一致,
他们之间的区别是
useEffect会用于 处理副作用, 而前两个hooks不能

useMemo和useCallback都会在组件第一次渲染的时候执行,
之后会在其依赖的变量发生改变时再次执行;并且这两个hooks都返回缓存的值,
useMemo返回缓存的变量,
useCallback返回缓存的函数。

  1. Javascript中的定时器有哪些?他们的区别及用法是什么?

setTimeout 只执行一次
setInterval 会一直重复执行

定义和用法
flex 属性用于设置或检索弹性盒模型对象的子元素如何分配空间。

flex 属性是 flex-grow、flex-shrink 和 flex-basis 属性的简写属性。

注意:如果元素不是弹性盒模型对象的子元素,则 flex 属性不起作用

级联组件
select 实现联动

methods: {
handleUpdate(row){
this.updateDialogVisible = true;// 把当前的弹框显示出来
// 内容相同,不同对象
this.updateBook = JSON.parse(JSON.stringify(row)); // 把当前的数据拷贝一份,避免取消的时候,污染数据
},
handleUpdateBook() {
this.axios .put(‘bookmanager-ajax/books’)
.then(resp => {
if(resp.data.stauts === ‘success’){
alert(‘更新成功’)
this.getBook(); // 调刷新列表的接口
} else {
alert(‘更新失败’)
}
}).catch(error => console.log(error))
}
}

1、防抖(debounce):触发高频事件后 n 秒内函数只会执行一次,(多次触发执行一次)
如果 n 秒内高频事件再次被触发,则重新计算时间

节流:(多次触发变成,每隔一段时间触发)

正则表达式
用来检查一个字符串是否含有某种子串、将匹配的子串做替换或者从某个字符串中取出符合某个条件的子串等

正则表达式的创建方式

元字符
代表特殊含义的元字符

\d : 0-9之间的任意一个数字 \d只占一个位置
\w : 数字,字母 ,下划线 0-9 a-z A-Z _
\s : 空格或者空白等
\D : 除了\d
\W : 除了\w
\S : 除了\s
. : 除了\n之外的任意一个字符
\ : 转义字符
| : 或者
() : 分组
\n : 匹配换行符
\b : 匹配边界 字符串的开头和结尾 空格的两边都是边界 => 不占用字符串位数
^ : 限定开始位置 => 本身不占位置
$ : 限定结束位置 => 本身不占位置
[a-z] : 任意字母 []中的表示任意一个都可以
[^a-z] : 非字母 []中^代表除了
[abc] : abc三个字母中的任何一个 [^abc]除了这三个字母中的任何一个字符

代表次数的量词元字符

  • : 0到多个
  • : 1到多个
    ? : 0次或1次 可有可无
    {n} : 正好n次;
    {n,} : n到多次
    {n,m} : n次到m次
    量词出现在元字符后面 如\d+,限定出现在前面的元字符的次数

var str = ‘1223334444’;
var reg = /\d{2}/g;
var res = str.match(reg);
console.log(res) //[“12”, “23”, “33”, “44”, “44”]

var str =’ 我是空格君 ‘;
var reg = /^\s+|\s+$/g; //匹配开头结尾空格
var res = str.replace(reg,’’);
console.log(’(’+res+’)’) //(我是空格君)
正则中的()和[]和重复子项 //拿出来单独说一下

字面量创建方式
实例创建方式
var reg = /pattern/flags
// 字面量创建方式
var reg = new RegExp(pattern,flags);
//实例创建方式

pattern:正则表达式  
flags:标识(修饰符)
标识主要包括:
1. i 忽略大小写匹配
2. m 多行匹配,即在到达一行文本末尾时还会继续寻常下一行中是否与正则匹配的项
3. g 全局匹配 模式应用于所有字符串,而非在找到第一个匹配项时停止

闭包简单说
函数嵌套函数,内部的函数可以访问外部的变量,
并调用,解决作用域的问题
一般的用途在, 轮播, 幻灯片

请写出你对闭包的理解,并列出简单的理解
使用闭包主要是 为了设计私有的方法和变量.

闭包的优点是
可以避免全局的污染,

缺点是
闭包会常驻内存, 会增大内存使用量,
使用不当很容易造成内存泄漏。

闭包有三个特性:

1.函数嵌套函数

2.函数内部可以引用外部的参数和变量

3.参数和变量不会被垃圾回收机制回收

浏览器渲染机制

大体流程如下:
HTML和CSS经过各自解析,生成DOM树和CSSOM树
合并成为渲染树
根据渲染树进行布局
最后调用GPU进行绘制,显示在屏幕上

数据类型转换:url转对象
var url = “http://www.baidu.com?a=1&b=2&c=3”
function fn(str) {
let obj ={}
let str1 = str.split(’?’)
let str2 = str1[1].split(’&’)
for(let i = 0; i < str2.length; i++){
let str3 = str2[i].split("=")
obj[str3[0]] = str3[1]
}
return obj
}
console.log( fn(url))

redux设置和使用原则

state 以单一对象存储在 store 对象中
state 只读(每次都返回一个新的对象)
使用纯函数 reducer 执行 state 更新

左侧菜单栏配置,
路由的路径也要配置
{
name: ‘通知系列’,path: ‘/notice’,icon: ‘’,
childs: [
{name: ‘警告’,path: ‘/alert’},
{name: ‘加载’,path: ‘/loading’}
]
}

//获取书
getBooks(){
// 返回loading
let loading = this.$loading({
lock: true,
text: ‘拼命加载中’,
background: ‘rgba(0,0,0,0.7)’
})
this.axios.get(’/bookmanager-ajxa/books?pageNum="+this.currentPage+"&pageSize="+this.PageSize)
.then(resp => {
this.books = resp.data.books
this.total = resp.data.total
}).catch(error => {
console.log(error)
})
// 成功后把它关闭
loading.close()
}

在数组对象中,多加一下字段, (如果字段相同,会把之前得字段给覆盖)
var arr = [
{name: ‘ls’, number: 16},
{name: ‘lsh’, number: 17},
]
arr.map((item) => {
item.name = ‘lsh1’
item.age = 20
return item
})

得到得结果是
[
{name: ‘ls’, number: 16,age: 20},
{name: ‘lsh’, number: 17,age: 20},
]

for in 是遍历键名
for in语句用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作)
for…in 语句用于对数组或者对象的属性进行循环操作。

for … in 循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作。

for…in语句以任意顺序遍历一个对象的可枚举属性。对于每个不同的属性,语句都会被执行。

for of 是遍历键值
JSON 数据的标的达方式是key:value
for…of遍历出的结果是value
for…in遍历出的结果是key

这里使用let声明变量,不要使用var,存在变量提升问题
//使用var类型遍历数组
var a=[1,2,3]
for(var i=0;i<3;i++){
setTimeout(function(){
console.log(i); // 3 3 3
},0)
}

var a=[1,2,3]
for(var i=0;i<=3;i++){
setTimeout(function(){
console.log(i); // 4 4 4 4
},0)
}

//输出结果是333
//使用let类型遍历数组
var a=[1,2,3]
for(let i=0;i<3;i++){
setTimeout(function(){
console.log(i);
},0)
}
//输出结果是123

使用for…in遍历数组
遍历结果是key,数组下标
var a=[1,2,3];
for(let i in a){
console.log(i);//0 1 2
console.log(a[i]);//1 2 3
}
使用for…of遍历数组
var a=[1,2,3];
for(let i of a){
console.log(i);//1 2 3
}

object[“property”]合objec.property说相同的

http和https
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全

谈谈react hooks的优缺点
优点
函数编程
一.更容易复用代码

二.代码风格好+代码量更少

缺点:
一. 响应式的useEffect
每调用useHook一次都会生成一份独立的状态,这个没有什么黑魔法,函数每次调用都会开辟一份独立的内存空间。
虽然状态(from useState)和副作用(useEffect)的存在依赖于组件,但它们可以在组件外部进行定义。这点是class component做不到的,你无法在外部声明state和副作用(如componentDidMount)。

二. 状态不同步

前端隐藏元素
html中通过css方式隐藏元素的方法

  1. style属性中的display: none; 不占用文档流
  2. visibility 设置为hidden后, 该元素仍然占用文档流 visibility : hidden
  3. 通过相对定位移动当前元素到屏幕左侧
    div {
    position: relative;
    left: -100%; 元素仍然占用文档流, 百分比是相对父元素的宽度和高度的,并不是相对可视区偏移的
    }

4.通过元素内文本对齐将子元素移动到父元素右侧,配合超出后不显示
.div{
text-indent: 100%;
white-space: nowrap;
overflow: hidden; 注意: 此时子元素仍占用文档流, 只是隐藏了超出部分
}

5.设置元素宽度和高度为0, 元素直接消失
.div{
width: 0px;
heigth: 0px;
}

6.设置元素透明度为0
div{
opacity: 0; 经常用来做动画变换
}

7.旋转元素, 使与当前页面垂直
div{
transform: rotateX(90deg) 注意: 这只是显示上的变换, 仍占用原元素大小和文档流
}

redux-toolkit 组织 redux 代码
react-redux

Provider组件
useSelector
useDispatch

redux
createStore
combineReducers
applyMiddleware

redux-thunk

  1. 如何进行网站性能优化

  2. 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。

  3. 从服务商角度而言,优化能够减少页面请求数、或者减小请求所占带宽,能够节省可观的资源。
      总之,恰当的优化不仅能够改善站点的用户体验并且能够节省相当的资源利用。
      前端优化的途径有很多,按粒度大致可以分为两类,第一类是页面级别的优化,例如 HTTP请求数、脚本的无阻塞加载、内联脚本的位置优化等 ;第二类则是代码级别的优化,例如 Javascript中的DOM 操作优化、CSS选择符优化、图片优化以及 HTML结构优化等等。另外,本着提高投入产出比的目的,后文提到的各种优化策略大致按照投入产出比从大到小的顺序排列。
      一、页面级优化

  4. JavaScript 压缩和模块打包

  5. 按需加载资源

  6. 在使用 DOM 操作库时用上 array-ids

  7. 缓存

  8. 启用 HTTP/2

  9. 应用性能分析

  10. 使用负载均衡方案

  11. 为了更快的启动时间考虑一下同构

  12. 使用索引加速数据库查询

  13. 使用更快的转译方案

  14. 避免或最小化 JavaScript 和 CSS 的使用而阻塞渲染

  15. 用于未来的一个建议:使用 service workers + 流

  16. 图片编码优化

  17. react和vue有哪些不同,说说你对这两个框架的看法
    相同点

· 都支持服务器端渲染

· 都有Virtual DOM,组件化开发,通过props参数进行父子组件数据的传递,都实现webComponent规范

· 数据驱动视图

· 都有支持native的方案,React的React native,Vue的weex

不同点

· React严格上只针对MVC的view层,Vue则是MVVM模式

· virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,
所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制

· 组件写法不一样, React推荐的做法是 JSX + inline style, 也就是把HTML和CSS全都写进JavaScript了,即’all in js’; Vue推荐的做法是webpack+vue-loader的单文件组件格式,即html,css,jd写在同一个文件;

· 数据绑定: vue实现了数据的双向绑定,react数据流动是单向的

· state对象在react应用中不可变的,需要使用setState方法更新状态;在vue中,state对象不是必须的,数据由data属性在vue对象中管理

浏览器是如何渲染页面的?
渲染的流程如下:

useCallback 和 useMemo
1.调用setState,就会触发组件的重新渲染,无论前后的state是否不同
2.父组件更新,子组件也会自动的更新

react自研面试
1.事件循环
eventloop

宏任务和微任务

let和const区别

props是组件的只读属性, 组件内部不能直接修改props,
想要修改props, 只能在该组件上的上层组件中修改

在 React 中,props 是上层组件传递进来的值,这个值是父类的值,
同 Vue 一样,props 的传值是单项数据流,
也就是不会让影响父类的值,如果需要改值,
可以先让 props 赋值给一个变量,在修改这个变量。

其实就是保证 React 单向数据流的设计模式,使状态可预测。

如果允许子组件修改,那么一个父组件将状态传递给好几个子组件,
这几个子组件随意修改,就完全不可预测,不知道在什么地方修改了状态

前端面试题

CSS的盒子模型
IE盒子模型,标准w3c盒子模型;
IE的content部分包含了 border 和padding

2)盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border).

CSS中 link 和@import 的区别是?
A:(1) link属于HTML标签,而@import是CSS提供的;
(2) 页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;(3) import只在IE5以上才能识别,而link是HTML标签,无兼容问题;
(4) link方式的样式的权重 高于@import的权重.

一个200 * 200 的div 在不同分辨率屏幕上左右居中对齐,用css实现
div{
position: absolute;
width: 200px;
height: 200px;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -100px;
z-index: 1000;
}

  1. 写一个左中右布局占满屏幕,其中左右两块是固定宽度200 ,中间自适应宽,要求先加载中间块,请写出结构及样式:
    <h3>实现三列宽度自适应布局</h3>  

    <div id = "left">我是左边</div>  

    <div id = "right">我是右边</div>  

    <div id = "center">我是中间</div>  
  1. 阐述清楚浮动的几种方式(常见问题)
    1.父级div定义height

2.父级div定义oveflow: hidden;

  1. 万能清楚法

4.结尾处加空div标签clear: both

html,body{ margin: 0px;width: 100%; }

h3{height: 100px;margin:20px 0 0;}

#left,#right{width: 200px;height: 200px; background-color: #ffe6b8;position: absolute;top:120px;}

#left{left:0px;}

#right{right: 0px;}

#center{margin:2px 210px ;background-color: #eee;height: 200px; }

cookies sessionStorage和localstorage区别
都存储在客户端

不同点1.存储大小

1.sessionStorage和localStorage虽然也有存储大小的限制,
但比cookie大得多, 可以到达5M或更大

2.有效时间

· localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;

· sessionStorage 数据在当前浏览器窗口关闭后自动删除。

· cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

  1. 数据与服务器之间的交互方式

· cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端

· sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

20.js有几种数据类型,其中基本数据类型有哪些
五种基本类型: Undefined、Null、Boolean、Number和String。

1中复杂的数据类型————Object,Object本质上是由一组无序的名值对组成的。

Object、Array和Function则属于引用类型

23.常见的HTTP状态码
2开头 (请求成功)表示成功处理了请求的状态代码。

200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
201 (已创建) 请求成功并且服务器创建了新的资源。
202 (已接受) 服务器已接受请求,但尚未处理。
203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。
206 (部分内容) 服务器成功处理了部分 GET 请求。

3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。

300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。

400 (错误请求) 服务器不理解请求的语法。
401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
403 (禁止) 服务器拒绝请求。
404 (未找到) 服务器找不到请求的网页。
405 (方法禁用) 禁用请求中指定的方法。
406 (不接受) 无法使用请求的内容特性响应请求的网页。
407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408 (请求超时) 服务器等候请求时发生超时。
409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求。

5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。

500 (服务器内部错误) 服务器遇到错误,无法完成请求。
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

怎么避免react hooks的常见问题
1.不要在useEffect里面太多的依赖项,
划分这些依赖项成多个单一功能的useEffect.

1.对象的合并
2.ts的原生数据类型(ts的优缺点) 多个js文件可以合并成一个ts的文件吗
3.父组件到子组件经历哪些生命周期(beforeCreate )
子传父
4.webpack的使用
5.为啥要使用axios,怎么封装axios
在项目的开发中有三个阶段
1.开发环境(dev.abc.com)
2.测试环境(text.abc.com)
3.生产环境 (abc.com)
访问接口数据时,例如:商品接口会是【域名】/api/v1/products
当环境不同时,直接修改域名就可。这就是封装请求的原因。

如何封装axios请求
首先先创建一个request.js文件
import axiox from ‘axios’

const instance =axiox.create({
baseURL:‘http://jsonplaceholder.typicode.com/’,//baseURL会在发送请求的时候拼接在url参数的前面
timeout:5000
})

//请求拦截
//所有的网络请求都会先走这个方法
// 添加请求拦截器,所有的网络请求都会先走这个方法,我们可以在它里面为请求添加一些自定义的内容
instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
console.log(‘全局请求拦截’)
console.log(config)
console.groupEnd()
config.headers.token=‘12343’
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});

// 添加响应拦截器
//此处可以根据服务器的返回状态码做响应的处理
//404 404 500
instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
console.log(‘全局响应拦截’)
console.log(response)
console.groupEnd()
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});

export function get(url,params) {
return instance.get(url,{
params
})
}

export function post(url,data) {
return instance.post(url,data)
}

export function del(url) {
return instance.delete(url)
}

export function put(url,data) {
return instance.put(url,data)
}

6.盒模型

判断一个数据的类型
async await
promise的方法
组件间的传值(更深层的组件)
event bus的原理

闭包(闭包就是有权访问另一个函数作用域遍量的函数)
形成闭包的原因: 存在上级作用域的作用
使用return返回函数
函数作为参数
IIFE 自执行函数
定时器setTimeout和自执行函数
所有的回调函数

闭包注意
容易导致内存泄漏,因为存在其他作用域的引用,过度使用闭包会导致内存占用过多

多js合并ts

深拷贝(开辟空间)和浅拷贝(地址)

proto:
// _proto_的指向取决于对象创建时的实现方式
// 创建对象的方式
var a = {}
2.构造器方式
var A = function () {}
var b = new A() // {}
console.log(b.proto)

// 3.Object.create 方式创建
var c = {}
var d= Object.create© // {}

// pre是把结构作为美化
  	         {{scope.row}}
 	

seesionStorage.setItem(name, num) // 存储数据
sessionStorage.setItem(‘value2’,119);
let dataAll=sessionStorage.valueOf();//获取全部数据
sessionStorage.removeItem(name) // 删除指定键名数据
sessionStorage.clear() // 清空缓存数据 localStorage.clear()

为什么虚拟dom会提高性能
虚拟dom相当于在js和真实dom中间加了一个缓存,
利用dom diff算法避免了没有必要的dom的操作,从而提高性能

redux三打原则
单一数据源
整个应用的state被存储在一棵object tree中,并且这个object tree 只存在
唯一一个store中

State 是只读的
唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。

使用纯函数来执行修改
为了描述 action 如何改变 state tree ,你需要编写 reducers。

for in 和 for of 的区别以及
for in 是遍历键名, for of 是遍历键值

由于for of 的这个特性

forEach()和map()的区别
一、相同点:
都是循环遍历数组中的每一项
forEach和map方法里每次执行匿名函数都支持3个参数,参数分别是item(当前每一项)、index(索引值)、arr(原数组)
匿名函数中的this都是指向window
只能遍历数组

二、区别:
1.forEach()

没有返回值。

2.map()

有返回值,可以return 出来。
var arr = [1,23,3];
arr.map(function(value,index,array){

//do something

return XXX

})

不同点:

map()

map方法返回一个新的数组,数组中的元素为原始数组调用函数处理后的值

也就是map()进行处理之后返回一个新的数组

⚠️注意:map()方法不会对空数组进行检测

map方法不会改变原始数组

var arr = [0,2,4,6,8];
var str = arr.map(function(item,index,arr){
console.log(this); //Window
console.log(this);
console.log(item);
console.log(‘原数组arr:’,arr); // 会执行五次
return item/2;},this);console.log(str); //[0,1,2,3,4]

forEach

var声明的变量会挂到window上,而let和const不会
var声明的变量存在变量提升,而let和const不会
let声明的变量可以改变,值和类型都可以改变,没有限制。
let和const声明形成块作用域,只能在块作用域里访问,不能跨块访问,也不能跨函数访问
同一作用域下let和const不能声明同名变量,而var可以
暂时性死区,let和const声明的变量不能在声明前被使用

less和sass styus三者的区别
Sass声明必须是$开头,后面紧跟变量名和变量值
less声明@开头

1.编译环境不一样
Sass是在服务端处理的,
以前是Ruby, 现在是Drat-sass 或 Node-Sass
而Less 是需要引入Less.js来处理代码输出Css到浏览器
,也可以在开发服务器将Less语法编译成css文件,
输出CSS文件到生产包目录,有npm less, Less.app、SimpleLess、CodeKit.app这样的工具,也有在线编译地址。

解决异步回调地狱
promise generator async/await

antd的select选择器滚动条修改
前端
订阅专栏
.ant-select-dropdown-menu::-webkit-scrollbar {
/滚动条整体样式/
width: 6px;
background: #041c34;
}
.ant-select-dropdown-menu::-webkit-scrollbar-thumb {
/滚动条里面小方块/
border-radius: 3px;
height: 50px;
background-color: #007acc;
}

async await 为了解决回调地狱的问题
async/await 的优势:可以很好地处理 then 链

对于单一的 Promise 链其实并不能发现 async/await 的优势,当需要处理由多个 Promise 组成的 then 链的时候,优势就能体现出来了,

forEach方法用于调用数组的每个元素,将元素传给回调函数

⚠️注意: forEach对于空数组是不会调用回调函数的 ,

没有返回一个新数组&没有返回值

应用场景:为一些相同的元素,绑定事件处理器!

细说浏览器输入URL后发生了什么

本文摘要:
1.DNS域名解析;
2.建立TCP连接;
3.发送HTTP请求;
4.服务器处理请求;
5.返回响应结果;
6.关闭TCP连接;
7.浏览器解析HTML;
8.浏览器布局渲染;

移动端1px像素问题

不可链式调用

var arr = [0,2,4,6,8]

var sum =0;

var str = arr.forEach(item,index.arr){sum+= item;console.log(“sum的值为:”,sum);})

数组去重
const arr = [10,20,100,200,20]
new Set(arr)

三、利用数组的indexOf方法去重
注: array.indexOf(item, start) 返回数组中某个指定的元素的位置,
没有则返回-1
var arr = [1, -5, 0, -4, 7, 7, 3]
function unique(arr){
var arr1 = []; // 新建一个数组存放arr中的值
for(var i=0, i < arr.length; i++){
if(arr1.indexOf(arr[i]) === -1 ){
arr1.push(arr[i]);
}
}
return arr1;
}
console.log(unique(arr)) // 1, -5, 0, -4, 7, 3

// 数组去重多种结果

解决antd的select下拉框因为数据量太大造成卡顿的问题
https://blog.csdn.net/liuyuhua666/article/details/103703478

shouldComponentUpdate 的作用

一个页面输入URL到页面加载显示完成,这个过程发生了什么?
1)查找浏览器缓存
2)DNS解析,查找该域名对应的IP地址,重定向,发出第二个get请求
3)进行HTTP协议会话
4)客户端发送请求报头(请求报头)
5)服务器回馈报头(响应报头)
6)html文档开始下载
7)文档树建立,
8)文件显示

Vue中visibility display v-if v-show比较
display: none
给一个元素设置了display: none后,该元素及其后代元素均会被隐藏。且重写后代元素的display属性无效。
该元素及其后代元素均不占用原空间,隐藏后的元素无法点击。
visibility:hidden
给元素设置visibility: hidden后,该元素隐藏。其子元素默认继承父元素visibility属性,但子元素若重写属性,则不受父级影响。
该元素隐藏后,仍保持占位。隐藏部分无法点击,可见的子元素可以点击。
display: none和visibility:hidden区别
visibility:hidden保持占位;display: none不保持占位
visibility:hidden设置后,其子元素可通过设置visibility:visible来单独控制子元素显示; display: none设置后,其子元素重写display属性无效,均隐藏。
display: none和visibility:hidden共同点
对应的标签仍存在DOM结构中,均可控制显隐
v-if和v-show区别
初始值为false时,v-if不会编译,v-show会编译并设置display:none
v-show只编译一次,通过控制display:none来控制显隐,始终可以在DOM中获取对应标签;
v-if的显隐切换则是通过动态的向DOM树内添加或者删除DOM元素,所以v-if="false"时,无法在DOM中获取该标签。

react中类组件和函数式组件中有什么不同?
纯函数式定义的无状态组件
纯函数组件的特点:
组件不会被实例化,整体渲染性能得到提升
组件不能访问this对象
组件无法访问生命周期的方法
无状态组件只能访问输入的props,无副作用

js面向对象编程
面向对象的三大特征:
封装,继承,多态
1.封装
把一段功能的代码在好多地方重复使用的时候,单独封装成一个功能的方法
2.继承
子类继承父类
继承会继承父类的实例属性和实例方法,并不会继承静态属性和方法,并且静态方法只能通过类名取调用
3.多态
多态的具体表现为方法重载和方法重写:

方法重载:重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数

方法重写:重写(也叫覆盖)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。
即函数名和参数都一样,只是函数的实现体不一样

三大特征的优点:

封装:封装的优势在于定义只可以在类内部进行对属性的操作,外部无法对这些属性指手画脚,要想修改,
也只能通过你定义的封装方法;

继承:继承减少了代码的冗余,省略了很多重复代码,开发者可以从父类底层定义所有子类必须有的属性和方法,以达到耦合的目的;

多态:多态实现了方法的个性化,不同的子类根据具体状况可以实现不同的方法,
光有父类定义的方法不够灵活,遇见特殊状况就捉襟见肘了

vue的核心是数据驱动

优选网
webApp
app嵌套在h5中

split()方法
用于把一个字符串分割成字符串数组

apply call 和bind的区别
1.都是用来改变函数的this对象的指向的
2.第一个参数都是this要指向的对象
3.都可以利用后续参数传参

call和apply都是对函数的直接调用,
而bind方法返回的仍然是一个函数,
因此后面还需要()来进行调用
apply的第二数组

call方法使用一个指定的this值和单独给出的一个或者多个参数来调用一个函数

Object是引用数据类型,如果不用function返回,每个组件的data都是内存的同一个地址,一个数据改变了其他也改变了;

vue和react的diff算法的区别
vue diff时调动patch函数,参数是vnode和oldVnode,分别代表新就节点
2.vue的列表比对,采用从量端到中间的比对方式,而react则采用从左到右依次,
而react则采用从左到右依次

项目优化
代码的压缩
删除项目中
按需加载
一般不需要考虑到代码分块,往往在打包的项目中就已经包含全部的state和reducers
const AsyncHome = asyncComponent(() => import("./containers/Home"));

该函数接受一个异步函数()=>import(componentURL)作为参数,并返回一个AsyncComponent组件。

1、React 中 keys 的作用是什么?
2.生命周期函数
3.react性能优化是哪个周期函数
4.谈谈虚拟dom
5.react性能优化方案
6.好像还有redux吧

使用箭头函数应注意什么?
1、用了箭头函数,this就不是指向window,而是父级(指向是可变的)
2、不能够使用arguments对象
3、不能用作构造函数,这就是说不能够使用new命令,否则会抛出一个错误
4、不可以使用yield命令,因此箭头函数不能用作 Generator 函数

箭头函数相对于匿名函数, 并且简化了函数的定义.
箭头
函数内部的this是词法作用域,由上下文确定.

深入理解JavaScript事件循环机制
js是单线程的

js的Event Loop是JS的执行机制。

  1. JS为什么是单线程的? 为什么需要异步? 单线程又是如何实现异步的呢?

(2) JS为什么需要异步?

数组去重还是排列来着

react的项目优化
react-loadable
const AsyncHome = Loadable({
loader: () => import("./containers/Home"),
loading: MyLoadingComponent
});

异步加载组件
react-loadable这个高级组件,要做到实现按需加载
使用异步组件:我们将使用asyncComponent动态导入我们想要的组件。
const AsyncHome = asyncComponent(() => import("./containers/Home"));
webpack + es6 的 import(采用的是this.props.children为回调函数的方式)

Vue子组件调用父组件的方法
在子组件中通过this.$parent.event来调用父组件的方法

父组件

子组件

第二种方法是在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了。

父组件

子组件

关于this. r o u t e r . p u s h 、 r e p l a c e 、 g o 的 区 别 t h i s . router.push、replace、go的区别 this. router.pushreplacegothis.router.push:跳转到指定url路径,并在history栈中添加一个记录,点击后退会返回到上一个页面。
this. r o u t e r . r e p l a c e : 跳 转 到 指 定 u r l 路 径 , 但 是 h i s t o r y 栈 中 不 会 有 记 录 , 点 击 返 回 会 跳 转 到 上 上 个 页 面 。 h i s . router.replace:跳转到指定url路径,但是history栈中不会有记录,点击返回会跳转到上上个页面。 his. router.replaceurlhistoryhis.router.go(n):向前或者向后跳转n个页面,n可为正整数或负整数。
如果n为0的话,将刷新当前页面。

var arr = [1,5,2,10,15];
//var arr = [‘a’,‘g’,‘f’,‘s’,‘c’];
//var arr = [‘hao’,‘an’,‘you’,‘to’,‘happly’,‘hot’];
function compare(value1,value2){
if(value1 < value2){
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0;
}
}
arr.sort(compare);
console.log(arr);

第四种:优化的遍历数组法
1 var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2, 8]
2 var newArr = []
3 for (var i = 0; i < arr.length; i++) {
4 for (var j = i + 1; j < arr.length; j++) {
5 if (arr[i] === arr[j]) {
6 i++
7 j = i
8 }
9 }
10 newArr.push(arr[i])
11 }
12 console.log(newArr) // 结果:[0, 5, 6, 7, 2, 8]

react的写法

// 定义一个函数组件,组件名大写 function Welcome(props) { return

Hello, world, {props.name}

} const element =

ReactDom.render( element, document.getElementById('root') )

在master的分支上拉一个新的分支
测试完后把当前的分支与mater合并
用master分支发布上线

把mater的分支合并后,把各自的分支合并到master

上线把maters分支更新

ES6 assigin()的用法
Object.assigin()方法用于将 所有可枚举属性的值
从一个或 多个源对象分配到目标对象。
它将返回目标对象。
const target = {a:1, b: 2}
const source = {b:4, c: 5}
const returnTagret = Object.assign(target, source)
// 指从target 枚举对比source,有重复的属性从source的值为准
console.log(target) {a: 1,b: 4, c: 5}

可用于 对多层的对象或数组变量 如:
let stuList = {
stu: [
{age: 18, name: ‘小ko’ }
]
}
let obj = Object.assgin({}, stuList.stu)
// 创建了一个obj的空对象 用于存储 stuList.stu
let arr = Object.assigin([], stuList.stu)
// 创建了一个arr 的空数组对象,用于存储stuList.stu

async/await的用法
同步代码编写方式:
Promise使用then函数进行链式调用, 一直点点,是一种从左向右的横向写法;

多个参数传递:

同步代码和异步代码可以一起编写:

async/await 是对Promise的优化:

asyn函数类型为Promise对象:

因为 HTTP 协议有一个缺陷:通信只能由客户端发起

react中用style {{}}
类名用 className

style={{display: ‘none’}}
react中第三包往上靠
自己的往下靠
样式放在最后

li {
list-style: none;
height: 36px;
line-height: 36px;
padding: 0 5px;
border-bottom: 1px solid #ddd;
}
li label {
float: left;
cursor: pointer;
}

li label li input {
vertical-align: middel;
margin-right: 6px;
position: relative;
top: -1px;
}

li button {
float: right;
display: none;
margin-top: 3px;
}

li:before {
content: initial;
}
li:last-child{
border-bottom: none;
}

状态的数据驱动页面的展示

把里面的指定属性改一下
up

// App是所有组件的父组件
import React, {Components} from ‘react’
import Header from ‘./components/Header’
import List from ‘./components/List’
import Footer from ‘./components/Footer’
export default class App extends Component {
// 初始化状态
state = {todos: [
{id: ‘001’, name: ‘好饭’, done: true},
{id: ‘001’, name: ‘睡觉’, done: true},
{id: ‘003’, name: ‘打代码’, done: false}
]}
// todoObj是 todos的对象
// addTodo 用于添加一个todo, 接收的参数是todo对象
addTodo = (todoObj)=>{
// 获取原todos
const { todos } = this.state
// 追加一个todo
const newTodos = [todoObj, …todos]
// 更新状态
this.setState({todos: newTodos})
console.log(‘App’,data)
}

// updateTodo用于更新一个todo对象
updateTodo =  (id,done)=>{
   // 获取状态的todos
   const {todos} = this.state
   // 匹配处理数据
   const newTodos = todos.map((todoObj)=>{
       if(todoObj.id === id) return {...todoObj, done} // if(todoObj.id === id) return {...todoObj, done: done}
       else return todoObj
   })
      this.setState({todos: newTodos})			
 }

render() {
const {todos} = this.state
return (

Header和List是兄弟的关系
// App和item是祖孙关系

)
}
}

Header组件
import React,{Componet} from ‘react’
import PropTypes from ‘prop-types’ // 下载类型检测 yarn add prop-types
import {nanoid} from ‘nanoid’ // 生成字符串
import ‘./index.css’
export default class Header extends Component{
// 对接受的props进行: 类型,必要性的限制
static propTypes = {
addTodo: PropTypes.func.isRequired
}
constructor(props){
super(props)
this.state = {
val: ‘’
}
}
const handleKeyUp = (event) =>{
// 解构赋值获取keyCode,target
const {keyCode, target} =event
// 判断是否是回车按键
if(keyCode !== 13) return
// 准备好一个todo名字不能为空 Date.now()时间戳 npm i uuid 或者npm i nanoid
if(target.value.trim() === ‘’){
alert(‘输入不能为空’)
return // 后面的事情不执行
}
// 准备好一个todo对象
const todoObj = {id: Date.now(), name: target.value,done:false}
// 将todoObj传递给App
this.props.aFun(todoObj)
// 清空input中的value的值
target.value= ‘’
// 判断键盘的事件是否为13
if(event.keyCode === 13){
val: event.target.value
}// 回车键的键值为13
event.keyCode !== 13 return
}
render(){
return (




)
}

}

List组件(文件)
import React from ‘react’
import PropTypes from ‘prop-types’
import Item from ‘item’
import ‘./index.css’

export default class List extends Component{
// 对接受的props进行: 类型,必要性的限制
static propTypes = {
todos: PropTypes.array.isRequired,
updateTodo: PropTypes.func.isRequired,
}
render() {
const { todosArr, updateTodo } =this.props
return(


  • {
    todosArr.map((todo)=>{
    // this.updateTodo 从外面接过来的updateTodo,所以不需要加updateTodo
    // 或者批量传递<Item key={todo.id} {…todo} updateTodo={this.updateTodo}/> updateTodo不需要this来获取
    return
    })
    }

)
}
}

Item组件(文件)
import React,{ Component } from ‘react’
import ‘./index.css’
export default class Item extends Componet{
state = {mouse: false} // 标识鼠标移入,移出下·
// 鼠标移入,移出的回调
handleMouse = (flag) => {
return () =>{
this.setState({mouse: flag})
}
}
// 勾选,取消勾选某一个todo的回调
handleCheck = (id)=>{
// 高阶函数 因为给那个input绑定了onChange事件,所以是有event获取value值
return (event)=> {
console.log(id, event.target.value) // 因为它的类型为checkbox,所以不能通过这种获取它的value值 event.target.value
// 在item里面去通知,最外面APP更新指定的id的todo
this.props.updateTodo(id, event.target.checked) // event.target.checked是否勾选
}
}

render() {
const {id,name,done}  = this.props
const { mouse  } = this.state
return (
    {/*鼠标的移入和移出事件  this.handleMouse(false)鼠标移出*/}
    <li   style={{backgroundColor: mouse ?  '#ddd' : 'white' }}  onMouseLeave={this.handleMouse(false)} onMouseEnter={this.handleMouse(true)}>
	<label>
		{/*	
		     使用defaultChecked,勾选后可以改吧
		     如果使用checked="true",就必须使用onChange
		     checked={done}
		*/}
		// 由于你的type改成checkbox,获取不到value值
	             <input type="checkbox" defaultChecked={done } onChange={this.handleCheck(id)}/>
	             <span>{name}</span>
	</label>
	<button className="btn btn-danger" style={{display: mouse ? 'block' : 'none'}}>删除</button>
    </li>
)
}

}

list的是读取app中的状态数据,才展示列表

Header(子)中的值,传给App(父),App的值传给List(子)

子传(给)父
子给父
父给(传)子一个函数
子给父(传递数据的时候,调这个函数)

//解构赋值可以把重复的值代替掉
let obj = {a: 1, b: 2}
let obj2 ={…obj, b:3}
console.log(obj2) // { a: 1, b: 3 }

状态的在哪里,操作状态的方法在哪里

App和item是祖孙关系
App先给list传一个函数
list在传给item,item调用影响app的变化

// 状态在哪里方法在哪里

鼠标放在哪个身上,就高亮

给每一个list添加鼠标入和移出事件

index.js:1 Warning: Each child in a list should have a unique “key” prop.
没有加rowKey

{return record.key}} dataSource={data&&data.map((item)=>{return item.dataTable})} />

React.createRef()
引用(Refs)提供了一个获得DOM节点或创建在render方法中的React元素的方法:

创建Refs:
可以通过React.createRef()创建refs并通过ref属性联系到react组件。
Refs通常当组件被创建时被分配给实例变量,这样他们就能在组件被引用。
class MyComponent extends React.Component{
constructor(props){
super(props);
this.myRef = React.createRef();
}
render(){
return


}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值