前端面试题(不断整理中)

226 阅读3分钟

最近在准备找工作,整理下被问到的面试题以及搜索到的题目,大概记录一下。(涉及到原理和代码的话,会在以后找时间进行补充和完善)

javascript

防抖和节流

防抖

对于高频率事件事件来说,在被触发指定时间后在执行,如果在此期间在此被触发的,则会重新计时,直到指定时间内不在触发,才会执行。

例如可以定义一个定时器,在事件被触发之后,将该事件放到定时器中,如果在1秒内,该事件又被触发了,则清除这个定时器,重新定义一个,放入点击事件。循环如此。一秒没没点击,则执行定时器内的方法。

节流

在指定时间内,无论触发了事件几次,都只能执行一次事件的回调。可以使用时间戳类计算时间差。

es6新特性

函数柯里化

如果一个函数接收多个参数,可以将其转化为先接收一个或者一部分参数,然后在返回一个方法,接收另一个或者一部分参数,最后返回执行结果。

其可以复用参数,节省代码,减少工作代码重复性。

详解JS函数柯里化

深克隆和浅克隆

事件轮询

jquery链式的实现原理

内部的每一个函数都会返回this。

对回调函数的理解

回调函数是作为参数传给另一个函数的函数,然后通过在外部函数内部调用该回调函数以完成某种操作。

css

水平居中和垂直居中

行内元素和块级元素

小程序

小程序页面跳转传参

vue

Vue父组件和子组件声明周期函数顺序

加载渲染过程

  1. 父 beforeCreate
  2. 父 created
  3. 父 beforeMount
  4. 子 beforeCreate
  5. 子 created
  6. 子 beforeMount
  7. 子 mounted
  8. 父 mounted

子组件更新过程

  1. 父 beforeUpdate
  2. 子 beforeUpdate
  3. 子 updated
  4. 父 updated

父组件更新过程

  1. 父 beforeUpdate
  2. 父 updated

销毁过程

  1. 父 beforeDestory
  2. 子 beforeDestory
  3. 子 destoryed
  4. 父 destoryed

vue组件之间的传参

父子组件

props + $emit

父组件
<component-a @btnclick="handleChangeParentData"></component-a>

// 子组件
Vue.component('component-a', {
    template: `
        <button @click="childBtnClick">btnClick</button>
        `,
    methods: {
        childBtnClick: function(){
            // $emit 触发组件绑定的父组件方法
            this.$emit('btnclick');
        }
    }
})

跨组件传参

provider + inject

  • 一旦注入了某个数据,比如上面示例中的 foo,那这个组件中就不能再声明 foo 这个数据了,因为它已经被父级占有。
//祖先组件,提供数据foo
export default {
  name: "grandfather",
  provide(){
    return{
      foo:'halo'
    }
  },
}
// 后代组件
export default {
  inject:['foo'],
}

  • 也可以将provider绑定到最顶层的组件(如App)上,作为全局变量, 也可以返回this,这样在所有的子组件中都可以注入(inject)。
//app.vue
export default {
    name: 'App',
    provide(){
        return{
            app:this
        }
    },
    data(){
        return{
            text:"it's hard to tell the night time from the day"
        }
    },
    methods:{
        say(){
            console.log("Desperado, why don't you come to your senses?")
        }
    }
}

//其他所有子组件,需要全局变量的,只需要按需注入app即可
export default {
    inject:['foo','app'],
    mounted(){
        console.log(this.app.text);//获取app中的变量
        this.app.say();//可以执行app中的方法,变身为全局方法!
    }
}

vue-router

vue-router的基本使用

  1. 安装 => npm install vue-router -S
  2. 在main.js中导入vue-router => import VueRouter from 'vue-router';
  3. 使用插件 => Vue.use(VueRouter);
  4. 创建路由对象并配置路由规则 => let router = new VueRouter({ routes: [ { path: 'home', component: Home }]})
  5. 将路由对象传进Vue实例 => new Vue({ el:'#app', router: router })
  6. 在app.vue中留一个页面插槽 => router-view></router-view>
// main.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './pages/Home';
import Index from './pages/Index';

Vue.use(VueRouter);

let router = new VueRouter({
    routes: [
        {
            path: '/home',
            name: 'homePage',
            component: Home,
        },
        {
            path: '/index',
            name: 'indexPage'
            component: Index,
            // 嵌套路由
            children: [
            	{
                    path: '/tab1',
                    component: Tab1,
                },
        		{
                    path: '/tab2',
                    component: Tab2,
                }
            ]
        }
    ]
});

new Vue({
    el: '#app',
    // 传入路由规则
    router: router
});


// App.vue
<template>
    {/* 路由占位 */}
    <router-view></router-view>
</template>

// Index.vue
<template>
	<div>
        IndexPage
    </div>
	// 嵌套路由的占位
	<router-view></router-view>
</template>

vue-router嵌套路由

  • 路由配置 children
  • 对应vue页面,添加<router-link></router-link> 标签

vue-router参数传递

路由跳转方式

  • <router-link to="url"></router-link>
  • this.$router.push(url)

传参

  1. 使用query来传递

    • 传值页面:this.$router.push({ path: '/home', query: { id: 100 } } )
    • 取值页面: this.$route.query.id // 100
    • 注意: 传值的时候是$router,取值的时候是$route
  2. 写在router-link中的to属性上

    • 传值:通过path <router-link to="{ path: '/home', query: { id: 100 }}" ></router-link>

      ​ 也可以通过name <router-link to="{ name: 'homePage', query: { id: 100 }}" ></router-link>

    • 取值: this.$route.query.id

vue-router路由守卫

全局守卫

  • beforeEach((to, from, next) => { next() })
  • afterEach((to, from) => { ... })
  • next可以传入一个false,终止页面跳转,或者传入一个地址,更改跳转。如果不调用,则也会终止跳转。下next同。

路由独享的守卫

  • 配置路由规则时候声明
{
    path: '/',
    component: Home,
    beforeEnter:(to, from, next ) => { next() }
}

组件内守卫

  • beforeRouteEnter => 不能访问this。
  • beforeRouteUpdate
  • beforeRouteLeave

webpack

webpack包括那几个方面?

entry

output

loader

loader有两个属性:

test 属性,识别出哪些文件会被转换。

use 属性,定义出在进行转换时,应该使用哪个 loader。

plugin

mode