前端面试题

159 阅读2分钟

一、算法

1.写个函数使 sum1(1, 2, 3, 4, 5)) 返回15 sum1(1, 2, 3))返回6

方案1:可以使用rest参数

function sum(...res: number[]){
   return res.reducer((a,b)=> a+b , 0)  
}

方案2:也可以用函数中的arguments属性

(附加拓展)sum(1)(2)(3)(4)返回10函数柯里化
function add() {
  // 第一次执行时,定义一个数组专门用来存储所有的参数
  var _args = Array.prototype.slice.call(arguments);
  // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
  var _adder = function() {
    _args.push(...arguments);
    return _adder;
  };
  // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
  _adder.toString = function () {
    return _args.reduce(function (a, b) {
      return a + b;
    });
  }
  return _adder;
}

二、 【Javascript、Typescript、ES6、ES7、Html】

1.import xxx 与 import xxx from xxx有什么区别?

2.网页输入网址到页面渲染期间发生了什么?

大致以下六个过程

  1. DNS域名解析
  2. TCP连接
  3. HTTP请求
  4. 处理请求返回HTTP响应
  5. 页面渲染
  6. 关闭连接

3.说说es6的新特性有哪些?

  • let const
  • 模板字面量 ` `
  • 解构赋值
  • 对象字面量简写
  • for...of
  • 展开运算符
  • 箭头函数
  • class类 super extend
    //父类
    class Person{
        constructor(name){
            this.name = name
        }

        showName(){
            console.log(`父类名字:${this.name}`)
        }

    }
    //子类
    class Student extends Person{
        constructor(name,skill){
            super(name)
            this.skill = skill
        }
        showName(){
            super.showName();//父级的方法执行
            console.log(`子类名字:${this.name}`)
        }
        showSkill(){
            return `技能:${this.skill}`
        }
    }

    let s = new Student("吾爱博客","逃学")
    console.log(s.skill,s.name)
    s.showName()

4.ts中interface和type的区别

  • 1.类型别名可以用于其它类型 (联合类型、元组类型、基本类型(原始值)),interface不支持
  • 2.interface 可以多次定义 并被视为合并所有声明成员 type 不支持
  • 3.type 能使用 in 关键字生成映射类型,但 interface 不行
  • 4.默认导出方式不同,inerface 支持同时声明,默认导出,而type必须先声明后导出

三、 Vue

1.vue组件中data为什么是函数?

因为如果data是一个对象则会造成数据共享,在多次使用该组件时,改变其中一个组件的值会影响全部该组件的值。而如果是通过函数的形式返回出一个对象的话,在每次使用该组件时返回出的对象的地址指向都是不一样的,这样就能让各个组件的数据独立

  • 如果data是一个对象Object
    结果:会干扰到其他组件的使用。
    原因: Object是引用数据类型,如果不是function返回,每个数组的data都是内存的同一个地址,一个组件中的数据改变了,其他组件中的数据也会发生改变

  • 如果data是一个函数形式
    结果:每个实例的数据互不干扰
    原因:data返回的数据会形成闭包,类似于创建私有数据空间,实例的data属性就都是独立的,不会相互影响。

2.父子组件、兄弟组件的通信方式有哪些?

父访子:refs、props
子访父:$emit, $parent, props传递函数
兄弟之间:新建空的Vue实例对象bus, provide/inject

3. 如何让css只在当前组件中起作用?

这个特别简单 <style scoped></style>

4. 如何对前端所有的路由地址的query参数进行统一的编码?

使用路由钩子beforeEach对路由进行统一编码

router.beforeEach((to, form, next)=>{
    if(to.query.abc){
        next()
    }else{
        let toQuery = JSON.parse(JSON.stringify(to.query));
        toQuery.abc = '页面共有参数';
        next({
           path: to.path,
           query: toQuery
        })
    }
})

5. vue.use()的作用是什么

安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。  
如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。
该方法需要在调用 new Vue() 之前被调用。  
当 install 方法被同一个插件多次调用,插件将只会被安装一次。

6. v-for、 v-if为什么不能同时使用

因为v-for优先级比v-if高,每次v-for都会执行一次v-if,造成不必要的计算,影响性能。

7. vue-router hash与history区别

hash

优点:  
1.只需要前端配置路由表, 不需要后端的参与  
2.兼容性好, 浏览器都能支持  
3.hash值改变不会向后端发送请求, 完全属于前端路由  
缺点:  
hash值前面需要加#, 不符合url规范,也不美观

history

优点:  
1.符合url地址规范, 不需要#, 使用起来比较美观  
缺点:  
1.在用户手动输入地址或刷新页面时会发起url请求, 后端需要配置index.html页面用户匹配不到静态资源的情况, 否则会出现404错误  
2.兼容性比较差, 是利用了 HTML5 History对象中新增的 pushState() 和 replaceState() 方法,需要特定浏览器的支持.

8. watch与computed的区别

参考文章
watch

1.是观察的动作,  
2.应用:监听props,$emit或本组件的值执行异步操作  
3.无缓存性,页面重新渲染时值不变化也会执行

computed

1.是计算值,
2.应用:就是简化tempalte里面{{}}计算和处理props或$emit的传值
3.具有缓存性,页面重新渲染值不变化,计算属性会立即返回之前的计算结果,而不必再次执行函数

9. 谈谈对vue框架的理解

关键点:渐进式 JavaScript框架、核心库加插件、动态创建用户界面(异步获取后台数据,数据展示在界面
特点: MVVM 模式;代码简洁体积小,运行效率高,适合移动PC端开发;本身只关注 UI (和 react 相似),可以轻松引入 Vue 插件或其他的第三方库进行开发。

10. 谈谈vue中的虚拟dom(开放性)

参考文章参考文章

11. vue 数组和对象不能直接赋值情况的原因?

尤大:因为javascript的限制,Vue监听数组赋值性变动会造成性能代价和获得的用户体验收益不成正比。