zoukankan      html  css  js  c++  java
  • Javascript高级面试

    原型

    异步

    一、什么是单线程,和异步有什么关系

    单线程:只有一个线程,同一时间只能做一件事

    原因:避免DOM渲染的冲突
    解决方案:异步

    为什么js只有一个线程:避免DOM渲染冲突
    • 浏览器需要渲染DOM
    • JS可以修改DOM结构
    • JS执行的时候,浏览器DOM渲染会暂停
    • 两端JS也不能同时执行(都修改DOM就冲突了)
    • webworker支持多线程,但是不能访问DOM

     

    解决方案存在的问题
    • 问题一:没按照书写方式执行,可读性差
    • 问题二:callback中不容易模块化

    二、什么是event-loop

    • 事件轮询,JS实现异步的具体解决方案
    • 同步代码,直接执行
    • 异步函数先放在异步队列中
    • 待同步函数执行完毕,轮询执行异步队列的函数
    
    setTimeout(function(){
        console.log(1);
    },100);              //100ms之后才放入异步队列中,目前异步队列是空的
    setTimeout(function(){
        console.log(2);  //直接放入异步队列
    })
    console.log(3)       //直接执行
    
    //执行3之后,异步队列中只有2,把2拿到主线程执行,2执行完之后,异步队列中并没有任务,所以一直轮询异步队列,直到100ms之后1放入异步队列,将1拿到主线程中执行
    
    
    $.ajax({
        url:'./data.json',
        success:function(){        //网络请求成功就把success放入异步队列
            console.log('a');
        }
    })
    
    setTimeout(function(){
        console.log('b')
    },100)
    
    setTimeout(function(){
        console.log('c');
    })
    console.log('d')
    
    //打印结果:
    //d    //d   
    //c    //c  
    //a    //b   
    //b    //a   
    
    //真实环境不会出现dacb
    

    三、是否用过jQuery的Deferred

    • jQuery1.5的变化
    • 使用jQuery Deferred
    • 初步引入Promise概念

     

    jQuery1.5之前
    
    var ajax = $.ajax({
        url:'./data.json',
        success:function(){
            console.log('success1');
            console.log('success2');
            console.log('success3');
        },
        error:function(){
            console.log('error');
        }
    })
    console.log(ajax); //返回一个XHR对象
    

     

    jQuery1.5之后
    
    var ajax = $.ajax('./data.json');
    ajax.done(function(){
        console.log('success1')
    })
    .fai(function(){
        console.log('fail')
    })
    .done(function(){
        console.log('success2');
    })
    console.log(ajax); //deferred对象
    
    
    var ajax = $.ajax('./data.json');
    ajax.then(function(){
        console.log('success1')
    },function(){
        console.log('error1');
    })
    .then(function(){
        console.log('success2');
    },function(){
        console.log('error');
    })
    
    //使用
    var w = waithandle()
    w.then(function(){
        console.log('ok1');
    },function(){
        console.log('err2');
    })
    .then(function(){
        console.log('ok2');
    },function(){
        console.log('err2');
    })
    //还有w.wait w.fail
    
    • 无法改变JS异步和单线程的本质
    • 只能从写法上杜绝callback这种形式
    • 它是一种语法糖,但是解耦了代码
    • 很好的提现:开放封闭原则(对扩展开放对修改封闭)
    使用jQuery Deferred
    
    //给出一段非常简单的代码,使用setTimeout函数
    var wait = function(){
        var task = function(){
            console.log('执行完成');
        }
        setTimeout(task,2000)
    }
    
    wait();
    
    //新增需求:要在执行完成之后进行某些特别复杂的操作,代码可能会很多,而且分好几个步骤
    
    
    function waitHandle(){
        var dtd = $.Deferred();//创建一个deferred对象
        
        var wait = function(dtd){  // 要求传入一个deferred对象
            var task = function(){
                console.log("执行完成");
                dtd.resolve();  //表示异步任务已完成
                //dtd.reject() // 表示异步任务失败或者出错
            };
            setTimeout(task,2000);
            return dtd;
        }
        //注意,这里已经要有返回值
        return wait(dtd);
    }
    /*
    *总结:dtd的API可分成两类,用意不同
    *第一类:dtd.resolve  dtd.reject
    *第二类:dtd.then  dtd.done  dtd.fail
    
    *这两类应该分开,否则后果严重!
    *可以在上面代码中最后执行dtd.reject()试一下后果
    */
    
    
    使用dtd.promise()
    
    function waitHandle(){
        var dtd = $.Deferred();
        var wait = function(){
            var task = function(){
                console.log('执行完成');
                dtd.resolve();
            }
            setTimeout(task,2000)
            return dtd.promise();  //注意这里返回的是promise,而不是直接返回deferred对象
        }
        return wait(dtd)
    }
    
    
    var w = waitHandle();   //promise对象
    $.when(w).then(function(){
        console.log('ok1');
    },function(){
        console.log('err1');
    })
    /*
    只能被动监听,不能干预promise的成功和失败
    */
    
    • 可以jQuery1.5对ajax的改变举例
    • 说明如何简单的封装、使用deferred
    • 说明promise和Defrred的区别

    要想深入了解它,就需要知道它的前世今生

    四、Promise的基本使用和原理

    基本语法回顾
    异常捕获

    //规定:then只接受一个函数,最后统一用catch捕获异常

    多个串联
    
    var scr1 = 'https://www.imooc.com/static/img/index/logo_new.png';
    var result1 = loadImg(src1);
    var src2 = 'https://www.imooc.com/static/img/index/logo_new.png';
    var result2 = loadImg(src2);
    
    result1.then(function(img1) {
        console.log('第一个图片加载完成', img1.width);
        return result2;
    }).then(function(img2) {
        console.log('第二个图片加载完成', img2.width);
    }).catch(function(ex) {
        console.log(ex);
    })
    
    Promise.all和Promise.race
    
    //Promise.all接收一个promise对象的数组
    //待全部完成后,统一执行success
    Promise.all([result1, result2]).then(datas => {
            //接收到的datas是一个数组,依次包含了多个promise返回的内容
            console.log(datas[0]);
            console.log(datas[1]);
    })
       
    //Promise.race接收一个包含多个promise对象的数组
    //只要有一个完成,就执行success
    Promise.race([result1, result2]).then(data => {
        //data即最先执行完成的promise的返回值
        console.log(data);
    })
    
    Promise标准
    • 三种状态:pending,fulfilled,rejected
    • 初始状态:pending
    • pending变为fulfilled,或者pending变为rejected
    • 状态变化不可逆

    promise必须实现then这个方法
    then()必须接收两个函数作为标准
    then

    五、介绍一下async/await(和Promise的区别、联系)

    六、总结一下当前JS结局异步的方案

    虚拟DOM

    • vdom 是 vue 和 React 的核心,先讲哪个都绕不开它
    • vdom 比较独立,使用也比较简单
    • 如果面试问到 vue 和 React 和实现,免不了问 vdom

    问题

    - vdom 是什么?为何会存在 vdom?
    什么是vdom
    • virtual dom,虚拟DOM
    • 用JS模拟DOM结构
    • DOM变化的对比,放在JS层来做(图灵完备语言:能实现各种逻辑的语言)
    • 提高重绘性能
    DOM
    
    <ul id="list">
        <li class="item">Item 1</li>
        <li class="item">Item 2</li>
    </ul>
    
    虚拟DOM:
    
    {
        tag: 'ul',
        attrs: {
            id: 'list'
        },
        children: [{
                tag: 'li',
                attrs: { className: 'item' },
                children: ['item1']
            },
            {
                tag: 'li',
                attrs: { className: 'item' },
                children: ['item2']
            }
        ]
    }
    
    //className代替class,因为class是js的保留字
    

    浏览器最耗费性能就是DOM操作

    现在浏览器执行JS性能非常低

    设计一个需求场景

    用jQery实现

    遇到的问题

    • vdom 的如何应用,核心 API 是什么
    • 介绍一下 diff 算法
    说一下使用 jquery 和使用框架的区别
    jQuery 实现 todo-list

    vue 实现 todo-list

    jQuery 和框架的区别

    • 数据和视图的分离,解耦(开放封闭原则)
    • 以数据驱动视图,只关心数据变化,DOM 操作被封装
    说一下对 MVVM 的理解
    • MVC
    • MVVM
    • 关于ViewModel

    MVVM和vue

    组件化和React

    hybrid

    未完待续,每日更新

    来源:https://segmentfault.com/a/1190000017498782

  • 相关阅读:
    逻辑架构设计目标和任务
    业务架构设计
    架构设计概念
    可扩展设计:如何做到增加功能不修改调用方代码?
    P2661 信息传递
    Network of Schools POJ
    1002 过河卒
    P3254 圆桌问题
    P2765 魔术球问题
    P1141 01迷宫
  • 原文地址:https://www.cnblogs.com/datiangou/p/10173016.html
Copyright © 2011-2022 走看看