天天看点

2018年底遇到的前端面试题

1.浮动:

    父级:overflow:hidden,float,position:relative-->块级上下文(bfc) ;

    子级:clear:both-->换行,需要高度。

2.进制转换:num.toString(n)--> 十 转 n ;parsInt(num,m) --> m 转 十; [1,2,3,4,5,6].map(parsInt)    注:小数会被忽略

        有小数的话:

// 进制转换
function transform(num, from, to) {
    // 默认两位参数,num  to,   num  from  to
    // 默认num 是 十进制
    !to?(to=from,from = 10):null;
    if (from > 1 && to > 1) {
        var intN = 0, floatN = 0;
        if (from != 10) {// 是十进制可以省略处理
            var pow = Math.pow(10,15);
            floatN = Math.round((num - parseInt(num))*pow)/pow,
                intN = parseInt(num, from);// 整数可以直接使用方法转换
            // 小数转10进制
            // 例如5进制  0.12345
            // res = 1*5^-1 + 2*5^-2 + ……
            var temp=0;
            floatN = floatN.toString();
            for(var i=2;i<floatN.length;i++){
                temp+=floatN[i]*(Math.pow(from,-i+1));
            }
            // console.log(temp);
            floatN = temp;
        }
        return +intN.toString(to)-(-floatN.toString(to));
    } else {
        return null;
    }
}
           

3.数组排序:sort():默认小--> 大 'hello word'.split('').sort().join(''); // dehlloorw

      array扁平化:toString(),或者 join()方法。

    当数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 

compareFunction

),比较的数字会先被转换为字符串,所以在Unicode顺序上 "80" 要比 "9" 要靠前。如果 

compareFunction(a, b)

 小于 0 ,那么 a 会被排列到 b 之前

// 转载自:https://www.jb51.net/article/137788.html

// 排序方法
function bubbleSort(array) {
    for (var a = 0; a < array.length; a++) {
        for (var b = a + 1; b < array.length; b++) {
            if ((array[a] - array[b]) > 0) {
                [array[a], array[b]] = [array[b], array[a]]
            }
        }
    }
    return array;
}

function chooseSort(array) {
    for (var a = 0; a < array.length; a++) {
        var min = a;
        for (var b = a + 1; b < array.length; b++) {
            if ((array[min] - array[b]) > 0) {
                min = b;
            }
        }
        if (a != min) {
            [array[min], array[a]] = [array[a], array[min]]
        }
    }
    return array;
}
//quickSort
function splitSort(array) {
    if (array.length < 2) {
        return array;
    } else {
        var left = [], right = [], mid = Math.floor(array.length / 2);
        mid = array.splice(mid, 1)[0];
        for (var i = 0; i < array.length; i++) {
            if ((array[i] - mid) > 0) {
                right.push(array[i])
            } else {
                left.push(array[i])
            }
        }
        var res = arguments.callee(left).concat([mid], arguments.callee(right));
        return res;
    }
}

function insertSort(array) {
    var index, current;
    for (var i = 1; i < array.length; i++) {
        index = i, current = array[i];
        index--;
        while (index > -1) {
            if (array[index] > current) {
                array[index + 1] = array[index];
                index--;
            } else {
                break;
            }
        }
        array[index + 1] = current;
    }
    return array;
}

function insertSort2(array) {
    var index, current;
    for (var i = 1; i < array.length; i++) {
        index = i, current = array[i];
        index--;
        while (index > -1) {
            if (array[index] > current) {
                // array[index+1] = array[index];
                index--;
            } else {
                break;
            }
        }
        current = array.splice(i, 1)[0];
        array.splice(index + 1, 0, current);
        // array[index+1] = current;
    }
    return array
}

function shellSort(array) {
    if (array.length < 2) {
        return array;
    }
    var len = array.length;
    for (var gap = Math.floor(len / 2); gap > 0; gap = Math.floor(gap / 2)) {
        for (var i = gap; i < len; i++) {
            for (var n = i - gap; n >= 0 && array[n + gap] < array[n]; n -= gap) {
                [array[n], array[n + gap]] = [array[n + gap], array[n]]
            }
        }
    }
    return array
}

function mergeSort(array) {
    function merge(left, right) {
        var res = [];
        while (left.length > 0 && right.length > 0) {
            if (left[0] > right[0]) {
                res.push(right.shift())
            } else {
                res.push(left.shift())
            }
        }
        return res.concat(left).concat(right)
    }

    function sort(array) {
        if (array.length == 1) {
            return array;
        }
        var mid = Math.floor(array.length / 2),
            left = array.slice(0, mid),
            right = array.slice(mid);
        return merge(sort(left), sort(right))
    }

    return sort(array);
}
//
| 排序算法 | 平均情况         | 最好情况   | 最坏情况   |  稳定性 |(元素相同时可能会调换顺序)
---------------------------------------------------------------
| 冒泡排序 |  O(n²)          |  O(n)     |  O(n²)    |  稳定  |
---------------------------------------------------------------
| 选择排序 |  O(n²)          |  O(n²)    |  O(n²)    |  不稳定 |
---------------------------------------------------------------
| 插入排序 |  O(n²)          |  O(n)     |  O(n²)    |  稳定   |
---------------------------------------------------------------
| 希尔排序 |  O(nlogn)~O(n²) |  O(n^1.5) |  O(n²)    |  不稳定 |
---------------------------------------------------------------
| 归并排序 |  O(nlogn)       |  O(nlogn) |  O(nlogn) |  稳定   |
---------------------------------------------------------------
| 快速排序 |  O(nlogn)       |  O(nlogn) |  O(n²)    |  不稳定 |
---------------------------------------------------------------
           

4.页面通讯:1.window.postMessage(IE8+),解决跨域通讯;  2. localStorage方法:监听window 的 storage事件

5.

以下6个属性设置在容器上:
 flex-direction:row | row-reverse | column | column-reverse;
 flex-wrap: nowrap | wrap | wrap-reverse;
 flex-flow: direction wrap 
 justify-content:flex-start | flex-end | center | space-between | space-around;
 align-items: flex-start | flex-end | center | baseline | stretch;
 align-content: flex-start | flex-end | center | space-between | space-around | stretch;
               //定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用
           
以下6个属性设置在项目上:
    order: 定义项目的排列顺序。数值越小,排列越靠前,默认为0。
    flex-grow: 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
    flex-shrink
    flex-basis: 定义了在分配多余空间之前,项目占据的主轴空间(main size)
    flex: 是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto
    align-self: auto | flex-start | flex-end | center | baseline | stretch;
               //允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性
           

6.优化:

    1.代码写法:委托时间,dom操作,css js位置, css替代简单图片,css3替代js动画;

    2.延时加载:img lazyloading,用户交互在异步加载资源;

    3.缓存:304不稳定;手动缓存localstorage : css,js,ajax数据

                服务器设置缓存:cache-control / expires, last-modified(if-modified-since)/ETag( if-none-match )

                一般情况下,使用Cache-Control/Expires会配合Last-Modified/ETag一起使用,因为即使服务器设置缓存时间, 当用户点击“刷新”按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将能够很好利用304,从而减少响应开销。Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

      localstorage:兼容>7; 浏览器大小限制5M左右(相比cookie 4 K 左右);

                           用处:页面数据保存,如list数据,表单数据( onload取出数据,beforeunload保存数据,submit删除保存数据 )

    4.编译处理:css,js,img 压缩图片(jpg,png: png效果好,但size大,优选jpg,base64,),requireJS,webpack 按需加载 ; 设置favicon.ico图标;

    5. 服务器:Gzip,CDN加速,合并请求

        gzip:兼容IE6+;只需后端开启gzip,response-header添加 content-Encoding:gzip(一般用于html,css,js,其他资源如图片视频音频文件都已经压缩过,无需再次压缩。压缩需要占用资源和时间,需权衡利弊)

    6. css优化: a. 避免内联样式,改为css文件 : 利于维护,方便复用,可以缓存

                        b. css统一放在head中,减少repaint和reflo :

                        c. 避免使用通配符,标签选择符,及多级嵌套: 不够精确,

                        d. css匹配规则从右到左:性能更高,是因为从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点);而从左向右的匹配规则的性能都浪费在了失败的查找上面。所以右侧选择尽量精确。

                        e. css继承:color,font-size,font-family等属性可以继承自父节点。

                        f. 权重:                   

  !important        style=''     id         class/attribute /伪类          elements /伪元素

    最高               1000       100               10                         1      

 权重比较:同等级的选择可以累加,但是不会越级,比如:ID大于11个class选择。

 样式最终决定于style中的样式顺序,而不是class中类名的顺序,比如:
 <style>
     .red {color:red}  
     .blue{color:blue}
</style>
<div class="red blue"></div>  // blue
<div class="blue red"></div>  // blue
           
2018年底遇到的前端面试题

                        (参考:https://www.cnblogs.com/walls/p/4263463.html)

        ( 关于优化的文章:https://www.jianshu.com/p/2818f6dcbf23 )

     7.循环优化:for(以及倒序) ,  while  , for in , foreach ,Buff's Device

        当数据量小时,不用担心方法的性能问题,当数据量增大后,性能优劣即显示出来:

               Buff's Device  >   while  >   for ~ forEach  > for in(很慢,不是一个数量级)

          达夫设备:通过减少循环次数,适度增加每次循环的运算来提高性能。(在老浏览器中效果显著。当循环中的运算已经很复杂了,优化效果将降低)

          (参考:https://www.cnblogs.com/libin-1/p/6964591.html) 

7.兼容性问题:

     1.focus: ios下触发必须为用户交互事件。

     2.定位fixed(ios8以下系统):

        a.  content内容区域定位并添加滚动替代页面滚动(-webkit-overflow-scroll: touch,改善效果),底部也就不用fixed

        b. 在输入控件获取焦点时,改变控件的属性:fixed-->absolute,并计算定位

    3.虚拟键盘遮挡:scrollIntoView();

    4.300ms延迟:fastClick,zepto,

    5.点击态:pc正常,移动端需加上 ontouchstart 事件;

    6.微信识别二维码:ios经常出问题。(绝对定位,top高度,同一屏内不要出现两个二维码,二维码尺寸不能太小,设置一个大的二维码且透明)

8.cookie操作:(https://blog.csdn.net/liuyingv8/article/details/80257145)

     1.只可赋值,删除是通过设置过期事件。

    2.过期事件以服务器事件为准,一般为标准时间。

    3.httpOnly:服务器通过设置此值,防止客户端修改此cookie,此cookie将不会再document.cookie中显示,但是仍会随着请求发送。

    4.secure: 安全标志,指定后,只有在使用SSL链接时候才能发送到服务器,如果是http链接则不会传递该信息

    注:当cookie禁用后,通过对url重写使用sessionId(怎么实现呢??)

(function (window,undefined) {
 //输入cookie信息时不能包含空格,分号,逗号等特殊符号;而在一般情况下,cookie 信息的存储都是采用未编码的方式。所以,在设置 cookie 信息以前要先使用escape()函数将 cookie 值信息进行编码,在获取到 cookie 值得时候再使用unescape()函数把值进行转换回来:escape(value),  unescape(value),ECMAScript v3 已从标准中删除了 unescape() 函数,并反对使用它,因此应该用 decodeURI() 和 decodeURIComponent() 取而代之。

 function MyCookie() { 
   this.constructor = {};
 }

 MyCookie.prototype = {
    hours8: 8 * 3600 * 1000, 
    // 事件设置也可以直接使用toUTCString();  (new Date()).toUTCString() 
    get: function (name) { 
         var cookie = document.cookie; 
         var regx = eval('/(^|;)' + name + '=([^;]{1,})' + '(;|$)/');
         var res = regx.exec(cookie); 
         return res && res[2] 
    },
    get2: function (name) {
         var cookie = document.cookie; 
         var regx2 = new RegExp('(^|;)' + name + '=([^;]{1,})' + '(;|$)');
         var res = regx2.exec(cookie); 
         return res && res[2] 
    },
    set: function (name, value, expires) { 
         var str = ''; 
         str += name + '=' + value;
         var date = new Date(new Date() - this.hours8 + (expires || 0) * 24 * 3600 * 1000);
       //var date = new Date(new Date() + (expires || 0) * 24 * 3600 * 1000).toUTCString();
         str += expires ? (';expires=' + date) : '';
         document.cookie = str;
   },
   delete: function (name) {
        var str = '';
        str += name + '=' + '1';
        var date = new Date(new Date() - this.hours8 - 5000); 
      //var date = new Date(new Date() - 5000).toUTCString(); 
        expires=' + date;
        document.cookie = str;
  }
 };

 window.MyCookie = new MyCookie();

})(window)
           

9. React:

    a.事件:react实现了自己的一套事件机制,冒泡,捕获。  所以的react事件(e事件对象,合成对象解决了浏览器的兼容)都会冒泡至document中,并在此处理。事件对象属于公用,当异步获取合成对象时,可能得到NUll或者其他事件的对象。

      阻止冒泡:e.stopPropagation;获取原生事件对象:e.nativeEvent( 注:不要在页面中使用原生的阻止冒泡方法)

    b.组件间通讯:

        1.父子组件通讯:传递参数和回调函数。多级嵌套组件通讯也可以层层传递,但是较繁琐。兄弟组件通讯可以选择公共父类组件做中转(a-->b, b-->c)

        2.发布订阅模式:自定义事件,并自行监听和触发,最是方便。 使用 node中的Event对象,写法很相同。(记得先安装Event包,参考使用方法:http://www.runoob.com/nodejs/nodejs-event.html)

自定义事件: index.js

function Event(){
    this.handles={};
} 

Event.prototype={

    constructor:Event,

    addEventListener:function(eventName,fn){
        if(this.handles[eventName]){
            this.handles[eventName].push(fn);
        }else{
             this.handles[eventName]=[fn]; 
        }
    },

    emitter:function(eventName){
        if(this.handles[eventName]){
          // this.handles[eventName].map(item=>item())
          for(var i=0;i<this.handles[eventName].length;i++){
              this.handles[eventName][i]();
          }
        }
    }

    removeEventListener:function(eventName,fn){

         if(!this.handles[eventName])return ;
                            
         if(fn){
            var list = this.handles[eventName];

            for(var i=0;i<list.length;i++){
               if(list[i]==fn){
                  list.splice(i,1);
                  i--;  // 一般遍历集合时,是不能同时修改集合本身的,避免循环出错(漏掉,重复遍历某个元素,死循环等)
               }
            }
         }else{
            this.handles[eventName]=[];   // 不传递参数,默认解除所有监听
         }

    }
}
           

        3.context:是个全局对象,可以 将需要传递的信息放在上面,但是全局对象维护起来很麻烦。官方也不推荐使用(我也没用过)

    c.ref:

    d.周期:

2018年底遇到的前端面试题
2018年底遇到的前端面试题

(详细介绍转载:https://blog.csdn.net/javaexploreroooo/article/details/71244808)

    e. 优化:

        1.render:在render中尽量少的定义变量和绑定函数(特别是不经常改变的变量),最好在constructor中做这些操作(因为constructor中的定义只会定义一次,而render)。

        2.shouldComponentUpdate(nextProps,nextState):在此处判断,返回false以优化(return nextProps.name!==this.props.name),特别是作为list列表项中的子组件特别注意。

        3.PureComponent:使用PureComponent替代Component可以达到2中的 效果。

        (注:PureComponent对比的都是浅对比,所以pros,state要尽量扁平化,不要嵌套)

        4.list渲染:渲染list时,通过key 属性作为唯一辨识,所以同一个item的key值应不变化;key值一般以id 等作为唯一标识,不要用 index 索引

    f:虚拟dom,diff比较:内存虚拟dom可以快速的比较出差异;可以合并一个周期的多次变化;diff在同级中比较,将时间复杂度降低O(n3) --> O(n) 

10.js绑定事件:

   1.行内绑定,div.οnclick=function(){}  这两种效果相同,后面的方法会覆盖掉前面定义的方法。

   2.addEventListener(name,fun,boolean): 参数三:true:捕获阶段实行   ;   false(默认):冒泡阶段执行    

     冒泡,捕获(阻止冒泡后,上层绑定的此类型事件将不再触发),响应的顶级标签是 html

11.综合:

  function Foo(){
     getName=function(){alert(1)}
     return this;
  ​​​​​​​}

  Foo.getName=function(){alert(2)}

  Foo.prototype.getName=function(){alert(3)}

  var getName = function(){alert(4)}

  function getName(){alert(5)}


  //执行结果:
  Foo.getName()        // 2

  getName()            //4

  Foo().getName()      //1

  getName()            //1

  new Foo.getName()    //2

  new Foo().getName()  //3

  new new Foo().getName()  //3
  
           

12:布局

 垂直水平居中方法:

a.flex布局:父级:display:flex; justify-content:center; align-items:center;
      (最完美的方法,处兼容性外>IE9)
    b.position: display:absolute ; left,right,top,bottom:0 ; margin: auto;width:100px;
      (宽高度需固定,不然铺满整个页面)
    c.translate:display:absolute; left,top:50%;  translate(-50%,-50%);
      (兼容>IE8)
    (注:margin,padding的百分比参照的是父级元素);(在考虑兼容性的情况下,仅仅通过css是无法做到水平垂直居中的(除非宽度确定),否则必须加入js判断;参照多数弹框写法,一般都会指定默认宽度)
    d.table布局:parent: display:table
                content:display:table-cell ; vertical-align:middle;               

    (注:块级元素的垂直相邻外边距会合并(不包括浮动和绝对定位元素 ),而行内元素实际上不占上下外边距。行内元素的的左右外边距不会合并。同样地,浮动元素的外边距也不会合并。允许指定负的外边距值,不过使用时要小心。)

           

 table中thead滚动:

table {       
            width: 500px;
        }
        table thead {
            display: table;
            width:100%;
        }
        table tbody {
            display: block;
            height: 195px;
            overflow-y: scroll;
        }
        tbody tr {
            display: table;
            width: 200%;
            /*table-layout: fixed;*/
        }

       
           

13.css实现三角:

width:0;height:0; 
  border-bottom:100px solid red;
  border-left:50px solid transparent;
  border-right:50px solid transparent;
           

14. slice , splice区别,substr,substring区别: 

数组方法: 
 slice(start,end[可省略]);索引start 至end(不包括)的值; 

        start可以为负(倒序);不改变原数组,返回副本

  splice(index,howmany,item1,.....,itemX) 向/从数组中添加/删除项目,然后返回被删除的项目。

        改变原数组

字符串方法:  
  substring(start,end[可省略]);     //返回副本

  substr(start [,length])          //返回副本 ,(substr 短小精悍,start  竟然还能接受负数,返回末尾的start位)

  slice(start,end); 同数组
  (slice可以转换数组: [].slice.call(arguments,0) 或者 Array.prototype.slice.call(arguments,0))
           

15.apply,call,bind 区别,应用场景?

call,apply和bind都是Function原型中的方法,而所有的函数都是Function的实例   

   .call(obj,argu1,argu2 ...)
   .apply(obj,[argu1,argu2 ...])
   .bind(obj,argu1,argu2 ...)    //返回这个函数,this已变
   call的性能优于apply;
   模式区别:
     严格模式:当obj为null,undefined, 无参 时,this为: null ,undefined  ,空; 与obj完全一样
     非严格模式:obj为null,undefined, 无参 时,this为:window

   使用场景:
          1.实现继承  
          2.用于借用某些构造函数的方法,比如:({}).toString.call(obj,arguments), [].slice.call(arr,arguments)

   自定义call函数:
         Function.prototype.mycall=function (context) {
 
             context = context|| window;
             context.fn = this;    //this指向调用方法的环境,this便在此改变
             var result,args = [...arguments];
             args.splice(0,1);
             result = context.fn(...args);
             delete context.fn;
             return result;
         };
           

16.es6属性:

1.class:类
     JS本身就是面向对象的,ES6中提供的类实际上只是JS原型模式的包装。现在提供原生的class支持后,对象的创建,继承更加直 
     观了,并且父类方法的调用,实例化,静态方法和构造函数等概念都更加形象化
     (https://blog.csdn.net/pcaxb/article/details/53759637)

   2.箭头操作符:=>

   3.字符串模板:
     ES6中允许使用反引号 ` 来创建字符串,此种方法创建的字符串里面可以包含由美元符号加花括号包裹的变量${vraible}
     console.log(`your num is ${num}`);

   4.结构赋值:
     自动解析数组或对象中的值:[name,,age]=['wayou','male','secrect'];//数组解构

   5.function 的默认参数,rest参数:
     function test(name='123'){console.log(name)}
     test(1,2,3) function test(...name){console.log(name)}

   6.let , const 关键字:

   7.for of :用于遍历数组,类数组或对象,每次循环它提供的是值。
     (for in 功能相同,每次循环提供的是键或索引)

   8.promise
           

17. 复制,引用:深拷贝就是对目标的完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也都复制了

a.Object.assign(target,source...)
       只是一级属性复制,比浅拷贝多深拷贝了一层而已。 针对深拷贝,需要使用其他方法,因为 Object.assign()拷贝的是属性值。假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。

    b.concat, slice方法:返回新的数组
      只对第一层深复制,同上

    c.JSON:  JSON.parse(JSON.stringify(obj))
      可以达到深拷贝的效果; 但是会丢失一些属性:当值为 undefined,function时,会忽略

    (最好的方法:自定义方法,递归, Object.prototype.toString.call(value)(如果用typeOf的话,Date也是对象,判断不够精确,符合遍历的对象暂时考虑到:object,array,set);for in ; ; Object.hasOwnProperty )
           

18. axios与ajax的区别:

    axios优点:axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,

  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 提供了一些并发请求的接口(重要,方便了很多的操作)
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防止CSRF/XSRF

19.sass,less区别:

sass/scss  (scss类似less,使用{},而不用缩进)     less

定义变量:           $                                           @ 
引用父选择符:        &                                           &
混入属性集创建:  @mixin name($amount) {}                   .className(@amount){}  //可以定义多个,判断参数使用
混入属性集使用:  @include name(0.5em)                      .className(@amount){}
继承:          @extend .className
注释:                                      /**/ ;  //
导入文件:                                @import font.scss
颜色运算:                                                    lighten,darken ,fadein,fadeout,fade,mix
js运算:                                    常用js运算


(SCSS 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。另外,SCSS 还能识别大部分 CSS hacks(一些 CSS 小技巧)和特定于浏览器的语法,例如:古老的 IE filter 语法。只需要理解 Sass 扩展部分如何工作的,就能完全理解 SCSS。唯一不同的是,SCSS 需要使用分号和花括号而不是换行和缩进。 )
           

20.Vue:

    1.双向数据绑定:利用 Object.defineProperty(obj,name,{options});

    options有以下4个特性:

        1.Configurable: 能否用delete删除属性从而重新定义属性。默认true

        2.Enumerable: 能否通过for-in遍历,即是否可枚举。默认true

        3.get: 读取属性时调用的函数,默认undefined

        4.set: 写入属性时调用的函数,默认undefined   

    (优点:数据变化采用发布订阅模式,性能优于react的setState方法,因为react中即使数据没有变化,当执行了方法后依然会重新渲染,所以为了优化性能,需要在shouldComponentUpdate中判断是否重新渲染。)

    2. vue2.0:开始映入虚拟dom概念

    3.computed 和 method方法的区别:

        1. vue数据支持在行内进行简单的计算,但当计算方式复杂时,可能无法满足要求,并且不利于维护,因此需要对数据进行处理。两者在处理结果上是一样的。

        2.  computed是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值;methods在重新渲染的时候,函数总会重新调用执行。所以使用computed会比methods方法性能更好。

    4.数据监听:vue使用$watch方法监听某个数据;(react可在componentWillRecieveProps或者在shouldComponentUpdate方法中判断)

    5. 周期函数:

2018年底遇到的前端面试题

    6. 页面回退页面刷新:当页面回退时,页面刷新,并重新请求数据。

    避免方法:

    vue: 首先是要 keep-alive组件处理,是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。然后手动将页面滚动到指定位置。(参考:https://blog.csdn.net/leileibrother/article/details/79376502)

    react: react中没有keep-alive概念,只能自己实现;将状态保存至本地,回退时判断是否有本地保存,有则直接使用缓存。

21. 小程序:

    1. 周期:

2018年底遇到的前端面试题
  • onLoad: 页面加载。

    1)一个页面只会调用一次。

    2)参数可以获取wx.navigateTo和wx.redirectTo及<navigator/>中的 query。

  • onShow: 页面显示

    1)每次打开页面都会调用一次。

  • onReady: 页面初次渲染完成

    1)一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。

    2)对界面的设置如wx.setNavigationBarTitle请在onReady之后设置。详见生命周期

  • onHide: 页面隐藏

    1)当navigateTo或底部tab切换时调用。

  • onUnload: 页面卸载

    1)当redirectTo或navigateBack的时候调用。

    2. 

22. 缓存

    1. 直接使用缓存: 通过服务端设置永久缓存,永不过期,每次请求直接使用

    2. 304 :cache-control 、 expires  、ETag(文件的标识)  、last-Modified

    a .  浏览器首先判断资源的过期时间,未过期则直接使用资源,不发生请求: cache-control:public,max-age=30   (单位:s, 或者no-cache,优先级高于expires),若设置no-store则直接请求资源。不判断;

    b . 当1中的条件不满足时,将发送请求,并带上Etag,last-Modified参数(若有,这也是实现304缓存的标识符,Etag的准确度更高)

版权声明:本文为CSDN博主「weixin_33895604」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_33895604/article/details/92380580