记录一次面试过程,还有一些笔试题,挺简单的,排序,去重,this指向,深浅拷贝,微任务的执行顺序,变量提升等。
Array.from
: 将两类对象转为真正的数组:let arrayLike = {
"0":"a",
"1":"b",
"2":"c",
length:3
}
let arr2 = Array.form(arrayLike); //["a","b","c"]
//还可以将arguments的对象转化成数组
function foo (){
let args = Array.from(arguments)
}
// 只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组,字符串和 Set 结构都具有 Iterator 接口
Array.from("hello");
//["h","e","l","l","o"]
let namesSet = new Set(["a","b"]);
Array.from(namesSet) //["a","b"]
console.log(...[1,2,3])
// 123
Array.of
:将一组值来转化成数组。Array.of(3,11,8)//[3,11,8]
copyWithin()
:将指定位置的元素复制到目标位置(会覆盖掉原有的值)。Array.prototype.copyWithin(target,start = 0,end = this.length);
//它接受三个参数
1.target (必需要):从该位置开始替换数据,如果为负值,表示倒数。
2.start(可选): 从该位置开始读取数据,默认为0。如果表示负值,则表示从末尾开始计算。
3.end(可选): 到该位置前停止读取数据,默认等于等于数组的长度,如果为负值,表示从末尾开始计算。
find()
:用来找出第一个符合条件的数组元素,它的参数是一个回调函数,所有的数组元素依次执行该回调函数,直到找到符合要求的元素[1, 4, -5, 10].find((n) => n < 0) // -5
findIndex()
:用来寻找符合条件的元素的下标[1,2,5,10,11].findIndex(function(value,index,arr){
return value > 9;
}) //2
["a","b","c"].fill(7);
//[7,7,7]
//方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。
["a","b","c"].fill(7);
//['a', 7, 'c']
`entries()``
``keys()`
values()
:这三个数组用来遍历数组,它们都返回一个遍历器对象,可以用for … of 循环进行遍历。
for (let index of ["a","b"].keys()){
console.log(index)
}
//0
//1
for(let elem of ["a","b"].values()){
console.log(elem)
}
// "a"
// "b"
for(let [index,elem] of ["a","b"].entries()){
console.log(index,elem)
}
//0 "a"
// 1 "b"
// for...of循环,可以手动调用遍历器对象的next方法,进行遍历。
[1,2,3].includes(2) // true
[1,2,3].includes(4) //false
// [1, [2, [3]]].flat(Infinity) // 参数代表要嵌套的次数。
// [1, 2, 3]
flatMap()
方法对原数组的每个成员执行一个函数,然后对返回值组成的数组执行flat()
方法。该方法返回一个新数组,不改变原数组。[2,3,4].flatMap((x)=>[x,x*2])
// 2,3,4, 6,4,8
//然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组。
[1, 2, 3, 4].flatMap(x => [[x * 2]])
// [[2], [4], [6], [8]]
默认排序顺序是在将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列时构建的
const array1 = [1, 30, 4, 21, 100000];
array1.sort(); //1, 100000, 21, 30, 4
reduce如何使用
for … in 循环可以遍历一个对象的所有可以枚举的属性,包括自身属性,和原型链上的属性。
语法:
let obj = {name:"Li",age:18}
for (let key in obj){
if(obj.hasOwnProperty(key)){
console.log(obj[key])
}
}
其中,obj
为要遍历的对象,key
为当前属性的名称。
注意事项:在使用for… in 遍历对象的时候,应该使用hasOwnProperty
方法来判断属性是否为对象本身的属性,而非原型链上的属性。
Object.keys
方法()Object.keys()
方法:可以返回一个对象所有自身的可枚举属性的名称组成的数组。
代码:
let obj = {name:"Li",age:18}
let keys = Object.keys(obj);
console.log(keys) //[name, age]
obj为要遍历的对象,keys
为返回的属性名称数组。
Object.values()
方法Object.values()
方法可以返回一个对象所有自身的可枚举属性的值组成的数组。
代码:
let obj = {name:"Li",age:18};
let values = Object.values(obj);
console.log(values) //['Li', 18]
Object.entries
()方法可以返回一个对象所有自身的可枚举的属性的名称和值组成的数组。代码:
let obj = {name:"Li",age:18};
let values = Object.values(obj);
console.log(values) // ['Li', 18]
for...of
循环可以用于遍历数组。在for...of
循环中,每次迭代会返回数组的一个元素值,循环将继续直到所有的元素都被迭代。
const arr = [1, 2, 3];
for (const item of arr) {
console.log(item); // 1 2 3
}
for...of
循环只能遍历可迭代对象,而数组是一种可迭代对象,有迭代器的属性。
答: for … of本身 不可以遍历对象只可以遍历可迭代对象,如果非要迭代可以这样来模拟。
const obj = {a: 1, b: 2, c: 3};
for (const [key, value] of Object.entries(obj)) {
console.log(`${key}: ${value}`); //a:1,b:2,c:3
}
object.values
object.keys
object.entirys
主线程是:js
从上向下执行的顺序叫做主线程。
宏任务:异步任务如,定时器是宏任务。
微任务:promise,async,await,nexttick
这些都是微任务
vue2的生命周期分为8个阶段,按顺序依次是:
beforeCreate
:实例被创建之前调用,此时数据和初始化都没有开始。created
:实例已经完成数据加载,属性和方法的运算也已经结束,这个阶段可以对数据进行预处理操作。beforeMount
:在挂载之前被调用,相关render函数首次被调用。mounted
:实例被挂在到DOM上后调用,可以在这里访问到DOM节点。beforeUpdate
:数据更新时调用,但是此时虚拟DOM还没有重新渲染,所以这里不能操作DOM。beforeDestory
:实例销毁之前调用,在这里可以进行一些清理工作,比如取消定时器、解绑时间等。destroyed
:实例销毁之后调用,这个时候实例上的所有绑定和事件监听已经被解除,子实例也被销毁。在vue2中,父组件和子组件的加载顺序是先父后子,就是父组件会在子组件之前被创建和加载,因为vue
会先解析父组件的模板,因此父组件的生命周期钩子函数会在子组件之前被调用。
具体的加载顺序如下
beforeCreate
和created。beforeCreate
,和created
在vue
中,当父组件销毁时,子组件也会随之销毁。销毁的执行顺序是先子组件再父组件。
具体来说,vue
会在销毁父组件之前,先递归销毁其所有子组件,这个过程Vue会按照有深入浅的顺序进行销毁,
也就是先销毁最深层级的子组件,然后逐步向上层级进行销毁,最后才会销毁父组件。
vue-router
,跳转方法区别,路由首位等。编程式导航
this.$router.push("/path")
:会在浏览器留下历史记录,浏览器的后退按钮会返回到上一个页面。可以触发路由守卫。this.$router.replace("/path"):
不会在浏览器留下历史记录,点击后退按钮不会返回到上个页面this.$router.push
两种传参方式
params对象传参 :仅仅可以传基本类型数据,不能传对象,必须要用name来引入路由。
this.$router.push({
name:'Detail',
params:{
id:id
}
})
query传参:使用query传参的时候,参数会被编码成url的查询字符串,参数表现在地址栏上,query可以传递对象等复杂的数据类型,刷新页面不会丢失数据。
this.$router.push({
path:'/detail/:id',
query:{
id:id
}
})
在 Vuex
中,命名空间可以将 store 模块化,避免命名冲突和对全局状态的过度依赖。在命名空间下,可以使用相对命名访问模块的 action、mutation 和 getter。
const store = new Vuex.Store({
modules: {
user: {
namespaced: true, // 开启命名空间
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
}
})
//在开启命名空间之后,就可以使用 namespaced 属性值作为前缀访问模块的 action、mutation 和 getter。例如:
// 访问模块的 state
store.state.user.xxx
// 访问模块的 getter
store.getters['user/xxx']
// 调用模块的 action
store.dispatch('user/xxx', payload)
// 调用模块的 mutation
store.commit('user/xxx', payload)
mixin
的理解mixin
可以将组件相同的属性和方法抽离出来形成一个单独的mixin
对象,混入到需要用的组件中去,减少代码的重复操作。mixin
会将mixin
的属性和方法与组建的属性方法合并,mixin的优先级更高。export const myMixin = {
data() {
return {
message: 'Hello, World!'
}
},
methods: {
greet() {
console.log(this.message);
}
}
}
//组件中引入
import { myMixin } from './myMixin.js'
export default {
mixins: [myMixin],
mounted() {
this.greet(); // 输出:Hello, World!
}
}
如果data的选项是一个对象,不同的组件实例共享同一个对象就会造成交叉感染。
而使用函数就可以保证每个组件实例都有自己独立的数据对象。
data是一个函数,用来动态生成组件实例中的初始数据,当组件实例化时,vuejs
会调用data函数,将返回的对象作为组件的初始数据,全部可以return 出去,renturn
出去的数据才是一个响应式的数据。
echarts
中vue
那个生命周期初始化。通常在mounted
生命周期中初始化Echarts
实例,因为在mounted
生命周期中,Vue已经成功地将组件挂载到DOM上,这时我们可以获取到组件对应的DOM元素。
keep-alive 里面如何用的
addRouters
Echarts
大屏如何适配呢。echarts
的容器元素中设置宽高比例,让他与设计稿相同。echarts
中的options中设置图表样式。适应不同的分辨率。Vue.js 中的自定义指令(Custom Directive)是一种扩展 HTML 标签的能力,它可以在标签渲染时通过指令来操作 DOM 元素.
使用场景
<template>
<div v-my-directive></div>
</template>
<script>
export default {
directives: {
'my-directive': {
// 指令选项
bind: function (el, binding) {
// 绑定时的处理逻辑
},
inserted: function (el, binding) {
// 插入到 DOM 中时的处理逻辑
},
update: function (el, binding) {
// 更新 DOM 中的节点时的处理逻辑
},
componentUpdated: function (el, binding) {
// 更新组件 VNode 时的处理逻辑
},
unbind: function (el, binding) {
// 解绑时的处理逻辑
}
}
}
}
</script>
我们定义了一个名为 my-directive
的自定义指令,并在组件模板中使用它。在组件定义的 directives
属性中,我们可以为自定义指令指定一系列钩子函数来处理不同的操作。
bind
:只调用一次,在指令第一次绑定到元素上时调用,可以在这里进行一些初始化设置。inserted
:在指令所在的元素插入到 DOM 中时调用。update
:当指令所在的元素更新时调用,但是可能在其子元素更新前调用。componentUpdated
:当指令所在的组件的 VNode 更新后调用。unbind
:只调用一次,在指令与元素解绑时调用,可以在这里进行一些清理工作。在每个钩子函数中,我们都可以获取到绑定指令的元素 el
和指令绑定时的参数 binding
。通过 binding
参数,我们可以获取到指令的名称、绑定的值、修饰符等信息。
通过自定义指令,我们可以轻松地扩展 Vue.js 的功能,实现一些强大的交互效果和业务逻辑。