前端八股文
BFC及其触发条件
- bfc的理解(块级格式化上下文)
可以看作是隔离了的独立容器,内部元素的布局,不会影响外部元素。 - 触发bfc的方式
定位、浮动、overflow: hidden、display 的多种。
(1)position:absolute或fixed;
(2)float:left/right;
(3)overflow:hidden; 不为visible, 常用方式;
(4)display:inline-block; flow-root, table-cell, table-caption, flex, inline-flex等。
** 如何判断对象具有某属性?**
(1) in 运算符
如:let obj={name:'zhangsan',age:21}
有以下方法 ( property 为属性名的变量,实际上是key,键名):
(2)
Reflect.has(obj, property)
关于 Reflect:
① 它是JS的一个内置对象,无构造函数,可以用它遍历对象的key,如:Reflect.ownKeys(obj) // ['name', 'age'];
② 也可以用它给对象添加一个属性,如:Reflect.set(obj, 'hobby', ['singing','reading']), 返回值是true/false
③无论是自有属性还是原型上有该属性,Reflect.has(obj,property)方法都会返回 true。
(3)obj.hasOwnProperty(property)
可以判断是否是对象的自有属性,若有,返回true,否则返回 false(原型链上的返回false)。
所有继承了 Object 的对象都会继承到 hasOwnProperty 方法。用来检测一个对象是否含有特定的自身属性;和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
(4)Object.prototype.hasOwnProperty.call 方法判断自有属性:
Object.prototype.hasOwnProperty.call(obj2, 'studentId')
遍历数组的方法有哪些?
for,for...in,for...of,forEach,map, reduce, filter, some, every, indexOf, includes等等
其中 forEach 会改变原数组,map 会返回一个新的数组,得到的结果赋值给一个新的变量接收
const arr=[1, 2];
const result = arr.map((item, index)=>{
return item + 1;
})
// result:[2,3] arr还是[1,2]
注意:
for...in拿到的是数组下标,for...of拿到的是数组的值;for...in能遍历对象,拿到的是对象的key;for...of不能遍历对象,会报错 obj is not iterable 不可迭代。
说说for...in和 for...of的区别?
在对数组或对象进行遍历时,我们经常会使用到两种方法:for in和for of,
那么这两种方法之间的区别就是它们两者都可以用于遍历,
不过for in遍历的是数组的索引(index),
而for of遍历的是数组元素值(value)
for in更适合遍历对象,当然也可以遍历数组,但是会存在一些问题。
for in 可以遍历对象,for of 不能遍历对象,只能遍历带有iterator接口的,例如Set,Map,String,Array
区别:
(1)for in 和 for of 都可以循环数组,for in 输出的是数组的index下标,而for of 输出的是数组的每一项的值。
(2)for in 可以遍历对象,for of 不能遍历对象,只能遍历带有iterator接口的,例如Set,Map,String,Array
for in适合遍历对象,for of适合遍历数组。for in遍历的是数组的索引,对象的属性,以及原型链上的属性。
数组乱序怎么实现?
数组怎么去重?
HTTP协议 的理解。
TypeScript——泛型
Axios和Ajax的区别是什么
Ajax 和 axios 都是用于前端向后端发送请求并获取数据的工具。它们之间的区别在于以下几点:
1.实现方式:Ajax 是原生的 JavaScript 技术,通过 XMLHttpRequest 对象向后端发送请求并获取数据。而 axios 是基于 Promise 的 HTTP 客户端,使用更加简洁方便,支持浏览器和 Node.js 环境。
2.跨域限制:由于浏览器的同源策略限制,使用 Ajax 进行跨域请求时需要进行一定的处理(如 JSONP、CORS 等)。而 axios 内置了可以解决跨域问题的配置选项,使用起来更加方便。
3.拦截器:axios 提供了拦截器功能,可以在发送请求或响应数据时对其进行拦截和处理。这使得我们能够更加灵活地控制请求和响应,并对其进行一些全局性的处理(如添加请求头、统一处理错误等)。
4.功能扩展:axios 可以通过插件来扩展其功能,例如可以使用 qs 插件来构建查询字符串、使用 redux-axios-middleware 将 axios 与 Redux 集成等。这些扩展能够提高我们的开发效率并为项目提供更强大的功能。
如何判断是手机端还是PC端
1.工具包 推荐 react-device-detect
import {isMobile} from 'react-device-detect';
if (isMobile) {
// 当前设备是移动设备
}
2.navigator.userAgent
最简单的方法就是分析浏览器的 user agent 字符串,它包含了设备信息。
JS 通过navigator.userAgent属性拿到这个字符串,只要里面包含mobi、android、iphone等关键字,就可以认定是移动设备。
if (/Mobi|Android|iPhone/i.test(navigator.userAgent)) {
// 当前设备是移动设备
}
// 另一种写法
if (
navigator.userAgent.match(/Mobi/i) ||
navigator.userAgent.match(/Android/i) ||
navigator.userAgent.match(/iPhone/i)
) {
// 当前设备是移动设备
}
这种方法的优点是简单方便,缺点是不可靠,因为用户可以修改这个字符串,让手机浏览器伪装成桌面浏览器。
移动端适配怎么做?
H5 与手机是如何通信的
1.h5调用原生App的方法合集 window.webkit.messageHandlers 桥方法名称(uploadFileTrade),可自由定义
/**
* 上传文件
* @callback 必填上传文件完成后的回调
* */
export function uploadFileTrade(params: any, UploadFile_Callback?: any) {
const {
uploadFileCallback = '_callback',
type,
orderNo,
reqSeq,
mgrCode,
maxCount,
custName,
showType,
} = params;
const paramsStr = `{\"callback\":\"${uploadFileCallback}\",\"type\":\"${type}\",
\"orderNo\":\"${orderNo}\",\"reqSeq\":\"${reqSeq}\",\"mgrCode\":\"${mgrCode}\",
\"maxCount\":\"${maxCount}\",\"custName\":\"${custName}\",\"showType\":\"${showType}\"}`;
try {
if (store.state.isIos) {
(window as any).top.webkit.messageHandlers.uploadFileTrade.postMessage(paramsStr);
} else {
(window as any).top.android_app.uploadFileTrade(paramsStr);
}
//暴露回调
(window as any)[uploadFileCallback] = UploadFile_Callback;
} catch (error: any) {
console.warn('uploadFileTrade桥方法调用异常', error);
}
}
箭头函数与普通函数的区别?本质区别是什么?
箭头函数(Arrow Function)和普通函数(Regular Function)是JavaScript中的两种函数定义方式,
- 语法简洁性: 箭头函数的语法相对于普通函数更加简洁。箭头函数可以使用箭头(=>)来定义,省略了function关键字和花括号,可以直接定义函数的参数和返回值
- this指向的不同: 在普通函数中,this的值是在函数被调用时确定的,它指向调用该函数的对象。而在箭头函数中,this的值是在函数定义时确定的,它指向定义箭头函数的上下文。这意味着箭头函数没有自己的this,它继承父级作用域的this。
- 不适用于构造函数: 箭头函数不能用作构造函数,不能通过new关键字来实例化对象。而普通函数可以用作构造函数,可以通过new关键字来创建对象实例
- 无arguments对象: 在普通函数中,可以使用arguments对象来访问所有传入的参数,它是一个类数组对象。而箭头函数没有自己的arguments对象,它继承父级作用域中的arguments对象
总结来说,箭头函数和普通函数在语法上的区别主要体现在简洁性和this指向上。箭头函数的语法更加简洁,但不能用作构造函数,并且没有自己的this和arguments对象。普通函数的语法相对复杂一些,但可以用作构造函数,并且有自己的this和arguments对象。在实际使用中,我们可以根据具体的需求选择合适的函数定义方式。
vue2和vue3的区别
Vue 2 和 Vue 3 的区别可以从多个角度来看:
1.性能优化:
- Vue 3 使用了 Proxy 来提高响应式系统的性能,并且引入了 Tree Shaking 技术,能够剔除不必要的代码,从而减小打包后的文件大小。
- Vue 2 和 Vue 3 的渲染引擎都有所改进,但具体细节未在搜索结果中提及。
- 组件API:
-
Vue 3 引入了全新的 Composition API,这是一种组合式的 API 风格,提供了更多的自定义钩子的灵活性,使得生命周期之间的关联更加清晰,也给用户提供了更好的逻辑组织方式。12
-
Vue 2 主要使用的是 Options API,而 Vue 3 则转向了 Composition API,这种新的 API 可以更好地组织组件逻辑。
- 数据双向绑定原理:
- Vue 2 使用的是 ES5 的 Object.defineProperty 方法来劫持数据,实现双边数据绑定。而 Vue 3 中使用了 ES6 的 proxy API 来处理数据,这种方式的优势在于可以实现对整个对象的监听,以及不需要使用 for in 和闭包等方式来提升效率。
- 代码组织方式:
- Vue 3 新增了一个名为
setup的入口函数,将 Watch 等方法作为参数传递给这个函数。这与 Vue 2 中 Watch 作为 Vue 对象属性导出的方式有所不同。
- 其他差异:
-
Vue 3 支持碎片(Fragments),这意味着它可以拥有多个根节点,而 Vue 2 只能有一个根节点。
-
Vue 3 还引入了 TypeScript 支持,并对核心库进行了优化以提供更好的类型支持。
综上所述,Vue 3 与 Vue 2 在性能优化、组件API、数据双向绑定原理、代码组织方式和对于 TypeScript 的支持等方面存在显著差异。