你不知道的N条前端面试题(四)

85 阅读2分钟

这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

  1. 手写深拷贝

    function deepClone(obj = {}) {
        if (typeof obj !== 'object' || obj == null) {
            // obj 是 null,或者不是对象和数组,直接返回
            return obj
        }
        let result // 初始化返回结果
        if (obj instanceof Array) {
            result = []
        } else {
            result = {}
        }
        for (let key in obj) {
            // 保证 key 不是原型的属性
            if (obj.hasOwnProperty(key)) {
                // 递归调用
                result[key] = deepClone(obj[key])
            }
        }
        // 返回结果
        return result
    }
    
    • Object.assign 不是深拷贝
  2. v-showv-if 的区别

    • v-show 通过 CSS display 控制显示和隐藏
    • v-if 组件是真正的渲染和销毁,而不是显示和隐藏
    • 频繁切换显示状态用 v-show,否则用 v-if
  3. v-for 为何使用 key

    • 必须用 key,且推荐不用 index 和 random
    • diff 算法中通过 tag 和 key 来判断,是否是 sameNode
    • 减少渲染次数,提升渲染性能
  4. 组件 data 为何是函数

    • 组件是用来复用的,且 JS 对象是引用关系;
    • 如果组件中 data 是一个对象,那么作用域没有隔离,子组件中的 data 属性值会相互影响;
    • 如果组件中 data 是一个函数,那么每个实例可以维护一份被返回对象的独立的拷贝,组件实例之间的 data 属性值不会相互影响;
    • new Vue 的实例是不会被复用的,因此不存在引用对象的问题;
  5. 何时使用 keep-alive

    • keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染;
    • 一般结合路由和动态组件一起使用,用于缓存组件;
    • 如多个静态 tab 页的切换;
  6. 何时需要使用 beforeDestroy

    • 解绑自定义事件 event.$off,防止内存泄漏
    • 清除定时器
    • 解绑自定义的 DOM 事件,如 window scroll
  7. Vuex 中 actionmutation 有何区别

    • action 中可以处理异步,mutation 不可以
    • mutation 做原子操作
    • action 可以整合多个 mutation
  8. Vue-router 常用的路由模式

    • hash(默认),基于 location.hash 来实现的。形如:www.word.com#search ;可以使用 hashChange 事件监听 hash 值的变化;
    • H5 history(需要服务端支持),主要有两个 API:history.pushState() history.replaceState()
  9. vue 常见性能优化

    • 合理使用 v-showv-if
    • 合理使用 computed
    • v-for 时加 key,以及避免和 v-if 同时使用
    • 自定义事件、DOM 事件及时销毁
    • 合理使用异步组件
    • 合理使用 keep-alive
    • data 层级不要太深
    • 使用 SSR 或者预渲染
    • 优化长列表、无限列表性能
    • 图片资源懒加载,路由懒加载