前端八股文

289 阅读8分钟

前端八股文

BFC及其触发条件
  1. bfc的理解(块级格式化上下文)
    可以看作是隔离了的独立容器,内部元素的布局,不会影响外部元素。
  2. 触发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,键名):

image.png (2) Reflect.has(obj, property)

image.png 关于 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')

image.png

遍历数组的方法有哪些?
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]

注意:

  1. for...in 拿到的是数组下标,for...of 拿到的是数组的值;
  2. for...in 能遍历对象,拿到的是对象的keyfor...of 不能遍历对象,会报错 obj is not iterable 不可迭代。

说说for...infor...of的区别?
在对数组或对象进行遍历时,我们经常会使用到两种方法:for infor 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属性拿到这个字符串,只要里面包含mobiandroidiphone等关键字,就可以认定是移动设备。

 
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中的两种函数定义方式,

  1. 语法简洁性: 箭头函数的语法相对于普通函数更加简洁。箭头函数可以使用箭头(=>)来定义,省略了function关键字和花括号,可以直接定义函数的参数和返回值
  2. this指向的不同: 在普通函数中,this的值是在函数被调用时确定的,它指向调用该函数的对象。而在箭头函数中,this的值是在函数定义时确定的,它指向定义箭头函数的上下文。这意味着箭头函数没有自己的this,它继承父级作用域的this。
  3. 不适用于构造函数: 箭头函数不能用作构造函数,不能通过new关键字来实例化对象。而普通函数可以用作构造函数,可以通过new关键字来创建对象实例
  4. 无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 的渲染引擎都有所改进,但具体细节未在搜索结果中提及。
  1. 组件API:
  • Vue 3 引入了全新的 Composition API,这是一种组合式的 API 风格,提供了更多的自定义钩子的灵活性,使得生命周期之间的关联更加清晰,也给用户提供了更好的逻辑组织方式。12

  • Vue 2 主要使用的是 Options API,而 Vue 3 则转向了 Composition API,这种新的 API 可以更好地组织组件逻辑。

  1. 数据双向绑定原理:
  • Vue 2 使用的是 ES5 的 Object.defineProperty 方法来劫持数据,实现双边数据绑定。而 Vue 3 中使用了 ES6 的 proxy API 来处理数据,这种方式的优势在于可以实现对整个对象的监听,以及不需要使用 for in 和闭包等方式来提升效率。
  1. 代码组织方式:
  • Vue 3 新增了一个名为 setup 的入口函数,将 Watch 等方法作为参数传递给这个函数。这与 Vue 2 中 Watch 作为 Vue 对象属性导出的方式有所不同。
  1. 其他差异:
  • Vue 3 支持碎片(Fragments),这意味着它可以拥有多个根节点,而 Vue 2 只能有一个根节点。

  • Vue 3 还引入了 TypeScript 支持,并对核心库进行了优化以提供更好的类型支持。

综上所述,Vue 3 与 Vue 2 在性能优化、组件API、数据双向绑定原理、代码组织方式和对于 TypeScript 的支持等方面存在显著差异。