前端面试题

一.如何实现深拷贝

  1. 使用json.stringify() 在使用json.parse()

  2. 使用递归

function deepClone(obj){

    let objClone = Array.isArray(obj)?[]:{};

    if(obj && typeof obj==="object"){

        for(key in obj){

            if(obj.hasOwnProperty(key)){//hasOwnProperty检测对象是否有自身属性

                //判断obj子元素是否为对象,如果是,递归复制

                if(obj[key]&&typeof obj[key] ==="object"){

                    objClone[key] = deepClone(obj[key]);

                }else{

                    //如果不是,简单复制

                    objClone[key] = obj[key];

                }

            }

        }

    }

    return objClone;

}    

let a=[1,2,3,4],

b=deepClone(a);

a[0]=2;

console.log(a,b);

3.函数库lodash的.cloneDeep

var _ = require('lodash')

var obj = {

  a: {

    c: 2,

    d: [9, 8, 7]

  },

  b: 4

}



var obj1 = _.cloneDeep(obj)

console.log(obj === obj1);//false

4.通过jQuery的extend方法

let $ = require('jquery');

let obj1 = {

   a: 1,

   b: {

     f: {

       g: 1

     }

   },

   c: [1, 2, 3]

};

let obj2 = $.extend(true, {}, obj1);

二.computed与watch的区别

1、功能上:computed是计算属性,watch是监听一个值的变化,然后执行对应的回调。

2、是否调用缓存:computed中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而watch在每次监听的值发生变化的时候都会执行回调。

3、是否调用return:computed中的函数必须要用return返回,watch中的函数不是必须要用return。

4、computed默认第一次加载的时候就开始监听;watch默认第一次加载不做监听,如果需要第一次加载做监听,添加immediate属性,设置为true(immediate:true)

5,computed具有多个属性只影响某一条数据,watch 一条数据影响多条数据

6、使用场景:computed----当一个属性受多个属性影响的时候,使用computed-----购物车商品结算。watch–当一条数据影响多条数据的时候,使用watch-----搜索框.

三.Vue的渲染方式

1、用原有模板语法,挂载渲染;

        原有模板语法,挂载渲染,即html的方式做渲染。当页面返回时html中的v-model等属性并没有被渲染,保持不变发给客户端,客户端直到加载了Vue,创建了实例之后才会将这些标识渲染出来。

2、用render属性、createElement函数直接渲染;

        使用render属性,createElement函数直接渲染:原本无html,通过JavaScript 的完全编程的能力生成页面。特点是只适合一些细节渲染,虽完全控制输出,但不够直观,实现复杂。

3、用render属性,配合组件的template属性、createElement函数渲染;

        使用render属性,配合组件的template属性,createElement函数渲染。

        相比于上一个方式,加入组件,利用template属性,更为直观,同样是原本无html,通过render函数渲染。

4、使用render属性,配合单文件组件渲染。

        使用render属性,配合单文件组件,createElement函数渲染

四.什么是宏任务和微任务

        宏任务:当前调用栈中执行的代码成为宏任务。(主代码块,定时器等等)。
        微任务: 当前(此次事件循环中)宏任务执行完,在下一个宏任务开始之前需要执行的任务,可以理解为回调事件。(promise.then,promise.nextTick(用于将回调延迟到下次DOM更新周期之后执行)等等)。

五 vuex的五个核心

每一个 Vuex 应用的核心就是 store(仓库),它包含着你的应用中大部分的状态 (state)。 状态管理有5个核心:state、getter、mutation、action、module。

State

        1、单一状态树,定义应用状态的默认初始值,页面显示所需的数据从该对象中进行读取。         2、Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态。它便作为一个“唯一数据源”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。

        3、单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

        4、不可直接对 state 进行更改,需要通过 Mutation 方法来更改。

        5、由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态:

Getter

        1、可以认为是 store 的计算属性,对 state 的加工,是派生出来的数据。

        2、就像 computed 计算属性一样,getter 返回的值会根据它的依赖被缓存起来,且只有当它的依赖值发生改变才会被重新计算。

        3、可以在多组件中共享 getter 函数,这样做还可以提高运行效率。

        4、在 store 上注册 getter,getter 方法接受以下参数: state, 如果在模块中定义则为模块的局部状态

        5、getters, 等同于 store.getters

Mutation

        1、Vuex中store数据改变的唯一方法就是mutation

        2、通俗的理解,mutations 里面装着改变数据的方法集合,处理数据逻辑的方法全部放在 mutations 里,使数据和视图分离。

Action action 类似于 mutation ,不同在于:

        1、action 提交的是 mutation,通过 mutation 来改变 state ,而不是直接变更状态。

        2、action 可以包含任意异步操作。

Module

        1、由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

        2、为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割

        1.state:Vuex的基本数据

        2.getters:对state的变量进行过滤

        3.mutation:提交同步更新的数据方法

        4.action:是用来修改mutation并提交的,可以包含任意异步操作

        5.modules:可以让模块有自己的属性state ,getters ,mutation ,action使结构更清晰

六JS 数组的去重方式有哪些?

方法一

 let arr = [1, 2, 2, 3] console.log([...new Set(arr)])

方法二

let arr = [1, 2, 2, 3]

function unique(arr) {

     let tmpArr = []

      for (let i = 0; i < arr.length; i++) {

          if (!tmpArr.includes(arr[i])) {

                 tmpArr.push(arr[i])

            }

      }

     return tmpArr
}

console.log(unique(arr))

七css垂直居中

 1、现在最常用的是flex布局

2、也可以使用 transform: translate,是css3新增的,兼容性比flex好点,可以支持ie9

3、如果元素是文本,那可以使用line-height,不过前提是要知道父级的高度。当然还有诸如 vertical-align:middle这种的

4、如果元素是dom,且知道自身的宽高,可以使用position:absolute; left:50%;top:50%  然后配合 transform:translate或者是margin: -xx 0 0 -xx;   xx表示需要居中元素宽高的一半;如果不知道自身的宽高,可以用position:absolute;left:0;right:0;top:0;bottom:0;margin:auto;

八css中自适应的单位

1. %

2. vw(相对于视口宽度的单位)

3. vh

4. vm(相对于视口宽度或者高度,取决于哪个小)

5. em(相对于父元素字体大小的单位)

6. rem(相对于根元素字体大小的单位)(有的会问em和rem的区别)

九css  rem的优缺点

优点:rem 是根据跟字体大小变化适配的,所以取决于跟字体的大小,把所有字体设置和宽高等像素设置的大小设置成rem ,这样可以在浏览器缩放大小的时候跟字体的改变就可以跟着变化其他的值的,这样是很方便是不需要自己配置对应浏览器适配的,而且不管在浏览器还是移动端基本都会保持布局不变。

缺点:虽然上面说的很简单,但是要做到rem全局适配是要用到计算的过程的,第一,要根据浏览器大小去做跟字体的大小,第二,根据跟字体设置的大小和设计图的px大小再去计算rem的大小,这样的操作会让我们的工作成本增加不少,而且需要引用额外的js操作。 但是我们可以做一个vw和rem搭配的适配,具体做法如下 1. 使用css的 calc计算函数计算跟字体大小 2. 对着设计图的宽度大小排版除以 100 ,比如说设计图是按375*1080的 那就是 3.75 3. 使用100vw设置html 字体大小 (这里的100vw等同于一个屏幕的宽度) font-size: calc(100vw /3.75)

4. 然后可以在你需要设置字体的地方设置rem大小,比如标题大小在设计图上是18px 那么对应的rem就是 0.18rem,需要除以 100做换算,当然如果觉得麻烦可以借助编辑器插件自动帮你换算成rem即可。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值