0


前端高频面试题 Day03

1. Vue computed 和 watch 区别

对于Computed:

● 它支持缓存,只有依赖的数据发生了变化,才会重新计算

不支持异步,当Computed中有异步操作时,无法监听数据的变化

● computed的值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data声明过, 或者父组件传递过来的props中的数据进行计算的。

● 如果一个属性是由其他属性计算而来的,这个属性依赖其他的属性,-般会使用computed

● 如果computed属性的属性值是函数,那么默认使用get方法,函数的返回值就是属性的属性值;在computed中,属性有一个get方法和一个set方法,当数据发生变化时,会调用set方法。

对于Watch:

● 它不支持缓存,数据变化时,它就会触发相应的操作

● 支持异步监听

● 监听的函数接收两个参数,第一个参数是最新的值,第二个是变化之前的值

● 当一个属性发生变化时,就需要执行相应的操作

● 监听数据必须是data中声明的或者父组件传递过来的props中的数据, 当发生变化时,会触发其他操作,函数有两个的参数:

  1. immediate: 组件加载立即触发回调函数
  2. deep: 深度监听,发现数据内部的变化,在复杂数据类型中使用,例如数组中的对象发生变化。需要注意的是,deep无法监听到数组和对象内部的变化。

当想要执行异步或者昂贵的操作以响应不断的变化时,就需要使用watch。

总结:

●computed计算属性:依赖其它属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,下一次获取computed的值时才会重新计算computed的值。

.●watch侦听器:更多的是观察的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。

运用场景:

●当需要进行数值计算,并且依赖于其它数据时,应该使用computed, 因为可以利用computed的缓存特性,避免每次获取值时都要重新计算。

●当需要在数据变化时执行异步或开销较大的操作时,应该使用watch, 使用watch选项允许执行异步操作(访问一个API),限制执行该操作的频率,并在得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

2. Computed和Methods的区别

可以将同一函数定义为一个method或者一个计算属性。对于最终的结果,两种方式是相同的
不同点:
●computed:计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值;
●method调用总会执行该函数。

3. for…in 和 for…of 的区别

key 和 value

for…in 遍历 key , for…of 遍历 value

const arr =[10,20,30]for(let n of arr){
    console.log(n)}const str ='abc'for(let s of str){
    console.log(s)}
functionfn(){for(let argument of arguments){
        console.log(argument)// for...of 可以获取 value ,而 for...in 获取 key}}fn(10,20,30)const pList = document.querySelectorAll('p')for(let p of pList){
    console.log(p)// for...of 可以获取 value ,而 for...in 获取 key}

遍历对象

for…in 可以遍历对象,for…of 不可以

遍历 Map/Set

for…of 可以遍历 Map/Set ,for…in 不可以

const set1 =newSet([10,20,30])for(let n of set1){
    console.log(n)}let map1 =newMap([['x',10],['y',20],['z',3]])for(let n of map1){
    console.log(n)}

遍历 generator

for…of 可遍历 generator ,for…in 不可以

function*foo(){yield10yield20yield30}for(let o offoo()){
  console.log(o)}

对象的可枚举属性

for…in 遍历一个对象的可枚举属性。

使用

Object.getOwnPropertyDescriptors(obj)

可以获取对象的所有属性描述,看

 enumerable: true

来判断该属性是否可枚举。

对象,数组,字符传

可迭代对象

for…of 遍历一个可迭代对象。

其实就是迭代器模式,通过一个

next

方法返回下一个元素。

该对象要实现一个

[Symbol.iterator]

方法,其中返回一个

next

函数,用于返回下一个 value(不是 key)。

可以执行

arr[Symbol.iterator]()

看一下。

JS 中内置迭代器的类型有

String
Array
arguments
NodeList
Map
Set
generator

等。

答案

  • for…in 遍历一个对象的可枚举属性,如对象、数组、字符串。针对属性,所以获得 key
  • for…of 遍历一个可迭代对象,如数组、字符串、Map/Set 。针对一个迭代对象,所以获得 value

划重点

“枚举” “迭代” 都是计算机语言的一些基础术语,目前搞不懂也没关系。

但请一定记住 for…of 和 for…in 的不同表现。

连环问:for await…of

用于遍历异步请求的可迭代对象。

// 像定义一个创建 promise 的函数functioncreateTimeoutPromise(val){returnnewPromise(resolve=>{setTimeout(()=>{resolve(val)},1000)})}

如果你明确知道有几个 promise 对象,那直接处理即可

(asyncfunction(){const p1 =createTimeoutPromise(10)const p2 =createTimeoutPromise(20)const v1 =await p1
    console.log(v1)const v2 =await p2
    console.log(v2)})()

如果你有一个对象,里面有 N 个 promise 对象,你可以这样处理

(asyncfunction(){const list =[createTimeoutPromise(10),createTimeoutPromise(20)]// 第一,使用 Promise.all 执行
    Promise.all(list).then(res=> console.log(res))// 第二,使用 for await ... of 遍历执行forawait(let p of list){
        console.log(p)}// 注意,如果用 for...of 只能遍历出各个 promise 对象,而不能触发 await 执行})()

【注意】如果你想顺序执行,只能延迟创建 promise 对象,而不能及早创建。

即,你创建了 promise 对象,它就立刻开始执行逻辑。

(asyncfunction(){const v1 =awaitcreateTimeoutPromise(10)
    console.log(v1)const v2 =awaitcreateTimeoutPromise(20)
    console.log(v2)for(let n of[100,200]){const v =awaitcreateTimeoutPromise(n)
        console.log('v', v)}})()

4. Vue 组件通讯

props / $emit

适用于父子组件。

  • 父组件向子组件传递 props 和事件
  • 子组件接收 props ,使用 this.$emit 调用事件

自定义事件

适用于兄弟组件,或者“距离”较远的组件。

常用 API

  • 绑定事件 event.on(key, fn)event.once(key, fn)
  • 触发事件 event.emit(key, data)
  • 解绑事件 event.off(key, fn)

Vue 版本的区别

【注意】组件销毁时记得

off

事件,否则可能会造成内存泄漏

$attrs

$attrs

存储是父组件中传递过来的,且未在

props

emits

中定义的属性和事件。

相当于

props

emits

的一个补充。

继续向下级传递,可以使用

v-bind="$attrs"

。这会在下级组件中渲染 DOM 属性,可以用

inheritAttrs: false

避免。

【注意】Vue3 中移除了

$listeners

,合并到了

$attrs

中。

$parent

通过

this.$parent

可以获取父组件,并可以继续获取属性、调用方法等。

【注意】Vue3 中移除了

$children

,建议使用

$refs

$refs

通过

this.$refs.xxx

可以获取某个子组件,前提是模板中要设置

ref="xxx"

【注意】要在

mounted

中获取

this.$refs

,不能在

created

中获取。

provide / inject

父子组件通讯方式非常多。如果是多层级的上下级组件通讯,可以使用 provide 和 inject 。

在上级组件定一个 provide ,下级组件即可通过 inject 接收。

  • 传递静态数据直接使用 provide: { x: 10 } 形式
  • 传递组件数据需要使用 provide() { return { x: this.xx } } 形式,但做不到响应式
  • 响应式需要借助 computed 来支持

Vuex

Vuex 全局数据管理

答案

  • 父子组件通讯 - props``````emits``````this.$emit- $attrs (也可以通过 v-bind="$attrs" 向下级传递)- $parent``````$refs
  • 多级组件上下级 - provide``````inject
  • 跨级、全局 - 自定义事件- Vuex

5 v-if和v-show的区别

● 手段: v-if是动态的向DOM树内添加或者删除DOM元素; v-show是通过设 置DOM元素的display样式属性控制显隐;

● 编译过程: v-ift切换有- - 个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;

● 编译条件: v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一 次变为真时才开始局部编译;v-show是在任何条件下,无论首次条件是否为真,都被编译,然后被缓存,而且DOM元素保留;

● 性能消耗: v-i有更高的切换消耗; v-show有更高的初始渲染消耗;

● 使用场景: v-i适合运营条件不大可能改变; v-show适合频繁切换。


本文转载自: https://blog.csdn.net/qq_63299825/article/details/132436227
版权归原作者 ~black- 所有, 如有侵权,请联系我们删除。

“前端高频面试题 Day03”的评论:

还没有评论