前端面试题

for in 和for of的区别

for in 适用于可枚举属性,例如 对象、数组、字符串

for of 适用于可迭代对象,像Array、String

for in 能遍历自身的可枚举属性 && 原型上的可枚举属性

for of 一般只能遍历自身的可枚举属性

for in 得到的是key

for of 一般得到的是value

ES6之后版本新增特性(不全)

1.Array.prototype.includes:用于检查数组是否包含某个元素返回布尔值

2.**指数运算符,用于指数运算

3.String.prototype.padStart() 和 String.prototype.padEnd() 方法用于填充字符串

4.Object.values() 和 Object.entries():返回对象的所有值或键值对数组

5.Promise.finally():无论 Promise 是成功还是失败,都会执行。 

6.异步迭代器:允许使用 for await...of 循环来异步迭代 

7.Array.prototype.flat() 和 Array.prototype.flatMap():数组扁平化

8.String.prototype.trimStart() 和 String.prototype.trimEnd():分别用于删除字符串开头和结尾的空白符。

Set和Map

Setes6新增的数据结构,类似于数组,但是成员的值都是唯一的,没有重复的值,我们一般称为集合

Set.add()增加一个set成员;Set.delete()删除一个set成员;Set.has()判断set是否有该成员;Set.clear()清除

扩展运算符和Set 结构相结合实现数组或字符串去重

Map类型是键值对的有序列表,而键和值都可以是任意类型

Map本身是一个构造函数,用来生成 Map 数据结构

map.size属性返回 Map 结构的成员总数。

中断请求

 

axios拦截器  instance.interceptors.request.use;新版本推荐使用AbortController,终止请求用AbortController.abort();

 

ajax中断请求 XMLHttpRequest.abort()

原型与原型链

每一个类(构造函数)都有一个显示原型prototype(本质就是个对象)

每一个实例都有一个隐式原型__proto__

显式原型的prototype等于其创建的实例的隐式原型__proto__例如:var arr = []; arr.__proto__ === Array.prototype

查找对象实例的方法和属性时,先在自身找,找不到则沿着__proto__向上查找,我们把__proto__形成的链条关系称原型链

 

 

继承 

原型链继承:原理: 将父类的实例(new Person())作为子类的原型对象(Student.prototype)

1.子类的构造函数指向出现错误,需要手动修改 (Student.prototype.constructor = Student)重新指回原构造函数。

2.若父类中存在引用类型的属性,继承者实例们共享该引用属性,一个修改,其他继承者的该属性值也会跟随改变。

3.子类实例对象无法向父类构造函数传参。

构造函数继承原理:在子类构造函数调用父类构造函数,并使用call/apply修改父类构造函数的this指向 此种方式摒弃原型链继承存在的实例化时无法向父类传参的问题。

1.只能访问父类实例上的属性或方法,不能够访问父类原型对象上的属性方法。

2.子类实例对象身上会出现父类实例对象的属性方法的副本,这显然是没有必要的

es6类继承原理: 封装的class,创建类,并通过extends实现继承。 语法简单,易书写

vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化

State提供唯一的公共数据源,所有共享的数据统一放到store的state进行储存,相似与data,通过this.$store.state获取

mutations : 使用它来修改数据(类似于methods),通过this.$store.commit('方法名')提交mutations中的方法来更改状 

getters: 类似于computed(计算属性,对现有的状态进行计算得到新的数据-------派生 )

actions: 发起异步请求,通过提交mutation来实现,可以包含异步操作,通过 this.$store.dispatch('方法名')分发action

modules: 模块拆分

优点:集中管理共享的数据,易于开发和后期维护;Vuex 的状态存储是响应式的,当 Vue 组件从 store中读取状态的时候,若 store 中的状态发生变化,能够触发响应式的渲染页面更新;

限定了一种可预测的方式改变数据, 避免大项目中, 数据不小心的污染

缺点:刷新浏览器,vuex中的state会重新变为初始状态 ;解决方案-插件 vuex-persistedstate

vue中为什么将数据定义在data里

集中保存有利于管理;data里的属性可以被组件中的其他模块访问;Vue的响应式系统需要监视组件的数据变化,只有data属性中的属性才会被监视。

data中的数据写在return中是因为不使用return包裹,数据是全局可见,容易造成污染,包裹后是当前组件可见。

因为vue组件可以复用,为了防止data被复用,data就被定义为了函数

vue3初始数据在setup中定义一个返回对象存放

深浅拷贝

浅拷贝:新对象与原始对象共享相同的内存地址,因此对其中一个对象进行更改会影响到另一个对象。浅拷贝仅复制对象的第一层结构,而不会递归复制嵌套的对象或数据

浅拷贝示例:扩展运算符;Object.assign();Array.concat() 方法

深拷贝:创建一个全新的对象或数据结构,其中包含原始对象完全独立的副本。新对象与原始对象具有不同的内存地址,因此彼此之间的更改是相互独立的。深拷贝会递归复制所有嵌套的对象或数据,确保整个对象及其子对象都被复制

深拷贝示例:JSON.parse(JSON.stringify());cloneDeep()

双向绑定

Vue数据双向绑定原理是通过数据劫持结合发布者-订阅者模式的方式来实现的,首先是对数据进行监听,然后当监听的属性发生变化时则告诉订阅者是否要更新,若更新就会执行对应的更新函数从而更新视图

通过Object.defineProperty()来劫持各个属性的setter, getter,在数据发生变动时通

知Vue实例,触发相应的​getter​和​setter​回调函数。

当把一个普通 Javascript 对象传给Vue 实例来作为它的 data 选项时, Vue 将遍历它的属性,用 Object.defineProperty 将

它们转为 ​getter/setter​。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化

首页白屏优化

1. 代码优化和压缩

2. 懒加载和按需加载

3. 预加载关键资源

4. 优化压缩图片和多媒体资源

5. 减少重定向和请求次数

6.适当使用缓存

posted @ 2024-09-13 20:24  就这样,  阅读(22)  评论(0编辑  收藏  举报