zoukankan      html  css  js  c++  java
  • 前端面试100问(1-10)

    内容的起源来自于掘金上的一篇文章——《前端 100 问:能搞懂 80% 的请把简历给我》

    系列笔记:

    题1:(滴滴、饿了么)写React/Vue项目时为什么要在列表组件中写key,其作用是什么?

    答:(以Vue举例回答)

    1.维护状态。

    Vue默认使用“就地更新”策略,如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序。

    这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时DOM状态的列表渲染输出。

    为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一key属性。

    <div v-for="item in items" v-bind:key="item.id">
      <!-- 内容 -->
    </div>

    2.key的特殊属性主要用在Vue的虚拟DOM算法,再新旧nodes对比时辨识VNodes。

    使用key,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素。

    有相同父元素的子元素必须有独特的key。重复的key会造成渲染错误。

    它也可以用于强制替换元素/组件而不是重复使用它。场景如下:

    • 完整地触发组件的生命周期钩子
    • 触发过渡

    例如:

    <transition>
      <span :key="text">{{ text }}</span>
    </transition>

    当text发生改变时,<span>会随时被更新,因此会触发过渡。

    题2:['1', '2', '3'].map(parseInt) what & why?

    答:看到这题的时候,我快速按下f12打开开发者工具,console打印结果是[1, NaN, NaN],纳尼~

    当时我就懵了。于是我又去看了下map方法的文档,没毛病,常用的~等等,就在最下面,竟然出现了和题目一样的代码~

    MDN开发者文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map

    见最下面的【使用技巧案例】

    // 下面的语句返回什么呢:
    ["1", "2", "3"].map(parseInt);
    // 你可能觉的会是[1, 2, 3]
    // 但实际的结果是 [1, NaN, NaN]
    
    // 通常使用parseInt时,只需要传递一个参数.
    // 但实际上,parseInt可以有两个参数.第二个参数是进制数.
    // 可以通过语句"alert(parseInt.length)===2"来验证.
    // map方法在调用callback函数时,会给它传递三个参数:当前正在遍历的元素, 
    // 元素索引, 原数组本身.
    // 第三个参数parseInt会忽视, 但第二个参数不会,也就是说,
    // parseInt把传过来的索引值当成进制数来使用.从而返回了NaN.

    题3:什么是防抖和节流?有什么区别?如何实现?

    答:说真的,看到这题我是懵的。赶紧查了下什么是防抖和节流。

    研究了一天,准备单独写一篇防抖和节流。

    相关文章:

    一个防抖和节流的实用例子

    一个Vue表单提交防抖的实用例子

    题4:介绍下Set、Map、WeakSet和WeakMap的区别?

    答:

    Set 一种类似于数组但没有重复值的数据结构

    const s = new Set();
    
    [2, 3, 5, 4, 2, 2].forEach(x => s.add(x));
    
    for (let i of s) {
      console.log(i);  
    }
    
    // 2 3 5 4

    详细内容参见:阮一峰的《ECMAScript 6 入门》 http://es6.ruanyifeng.com/#docs/set-map

    WeakSet 结构与Set类似,但有2个区别:

    WeakSet的成员只能是对象,而不能是其他类型的值,比如数值和Symbol

    WeakSet中的对象都是弱引用

    Map数据结构类似于对象,“键”的范围不限于字符串,各种类型的值都可以当作键

    Map结构提供了“值-值”的对应,是一种更完善的Hash结构实现

    WeakMap结构与Map结构类似,也是用于生成键值对的集合。

    WeakMap与Map的区别:

    WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名

    WeakMap的键名所指向的对象,不计入垃圾回收机制

    (有点晕~)

    题5:介绍下深度优先遍历和广度优先遍历,如何实现?

    题6:请分别用深度优先思想和广度优先思想实现一个拷贝函数?

    这两题我看了很久,有点晕,先跳过

    贴上木易杨说的答案:

    题5答案:https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/9

    题6答案:https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/10

    题7:ES5/ES6的继承除了写法以外还有什么区别?

    答:

    1.class声明不会提升(有人说是会提升但不赋值)

    2.class声明内部会启用严格模式

    3.class的所有方法(包括静态方法和实例方法)都是不可枚举的

    4.class的所有方法(包括静态方法和实例方法)都没有原型对象prototype

    5.必须使用new调用class

    6.class内部无法重写类名

    //普通函数
    function Bar() {
        Bar = 'Baz'; //没问题
    }
    
    //
    class Bar {
        constructor() {
            Bar = 'Baz'; // 错误
        }
    }

    7.因为this生成顺序不同,所以子类的constructor中需要使用super()

    答案摘自:https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/20

    题8:setTimeout、Promise、Async/Await的区别?

    答:那天首先花了一天时间去了解下什么是JS事件循环、宏任务和微任务这些概念,整理成笔记如下:

    学习笔记:初识JS事件循环机制

    以下是来自github木易杨的blog的答案,原链接:https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/33

    1.setTimeout

    console.log('script start')
    setTimeout(function () {
        console.log('settimeout')
    })
    console.log('script end')
    
    // 输出顺序:script start -> script end -> settimeout

    2.Promise

    Promise本身是同步的立即执行函数。当在executor中执行resolve或者reject时是异步操作,会先执行then/cathc等,当主栈完成后,才会去调用resolve/reject中存放的方法执行。

    console.log('script start')
    let promise1 = new Promise(function(resolve) {
        console.log('promise1')
        resolve()
        console.log('promise1 end')
    }).then(function(){
        console.log('promise2')
    })
    setTimeout(function(){
        console.log('settimeout')
    })
    console.log('script end')
    
    //输出顺序: script start -> promise1 -> promise1 end -> script end -> promise2 -> settimeout

    当JS主线程执行到Promise对象时

    • promise1.then()的回调就是一个task
    • promise1是resolved或者rejected:那这个task就会放入当前事件循环回合的microtask queue
    • promise1是pending:这个task就会放入事件循环的未来的某个(可能下一个)回合的microtask queue中
    • setTimeout的回调也是个task,它会被放入microtask queue即使是0ms的情况

    3.async/await

    async function async1 () {
        console.log('async1 start')
        await async2()
        console.log('async1 end')
    }
    
    async function async2 () {
        console.log('async2')
    }
    
    console.log('script start')
    async1()
    console.log('start end')
    
    // 输出顺序:script start -> async1 start -> async2 -> script end -> async1 end

    async函数返回一个Promise对象,当函数执行的时候,一旦遇到await就会先返回,等到触发的异步操作完成,再执行函数体内后面的语句。可以理解为,是让出了线程,跳出了async函数体。

    举个例子:

    async function fn1 () {
        return 1
    }
    console.log(fn1())

    fn1的运行结果是 一个Promise对象。因为也可以用then来处理后续逻辑。

    fn1().then(res => {
        console.log(res)
    })

    await的含义为等待,也就是async函数需要等待await后的函数执行完成并且有了返回结果(Promise对象)之后,才能继续执行下面的代码。

    await通过返回一个Promise对象来实现同步的效果。

    await/async是通过Generator/function*来实现的。所以async/await的相关优势也来自于generator.

    Generator是一个可以暂停function.

    function* generator(i) {
        console.log('inside before')
        yield i;
        yield i + 10;
        console.log('inside after')
    }
    
    var gen = generator(10)
    console.log('outside before')
    console.log(gen.next().value)
    console.log(gen.next().value);
    console.log('outside after')
    gen.next();
    
    //结果如下:
    // outside before
    // inside before
    // 10
    // 20
    // outside after
    // inside after

    题9:Async/Await如何通过同步的方式实现异步?

    答:

    针对这个问题的学习笔记: 每日技术:Promise和Async/Await用法

     

     题10:异步笔试题

    请写出下面代码的运行结果

    async function async1() {
        console.log('async1 start');
        await async2();
        console.log('async1 end');
    }
    async function async2() {
        console.log('async2');
    }
    console.log('script start');
    setTimeout(function() {
        console.log('setTimeout');
    }, 0)
    async1();
    new Promise(function(resolve) {
        console.log('promise1');
        resolve();
    }).then(function() {
        console.log('promise2');
    });
    console.log('script end');

    答:每日技术:关于promise,async,setTimeout的执行顺序

  • 相关阅读:
    linux设置网关修改ip
    Linux Source命令及脚本的执行方式解析
    ARM9 S3C2440 定时器中断
    Linux下配置静态IP地址,设置DNS和主机名
    s3c2440外部中断操作
    vmware中为虚拟机添加硬盘空间
    『SHELL』SHELL脚本执行方式
    WCF开发的几个频骤
    MyEclipse下Axis2插件的下载和安装
    WCF系列(二) 使用配置文件构建和使用WCF服务
  • 原文地址:https://www.cnblogs.com/cathy1024/p/11171762.html
Copyright © 2011-2022 走看看