美文网首页让前端飞前端开发
前端面试资料总结(持续更新)

前端面试资料总结(持续更新)

作者: 小鳄鱼的大哥哦 | 来源:发表于2019-02-16 15:30 被阅读6次

    CSS盒模型

    盒模型包含了content,padding,border,margin

    1.一个是标准模型:盒模型的宽高只是content的宽高
    2.一个是IE模型(又叫怪异模型):盒模型的宽高是内容(content)+填充(padding)+边框(border)的总宽高。
    如何统一模型:将模型的宽高都统一为内容(content)+填充(padding)+边框(border)的总宽高。

    div{
        box-sizing: border-box;
    }
    
    两种盒模型

    DOM事件流

    JS中事件分为三个阶段: 事件捕获 --> 事件目标 --> 事件冒泡

    dom事件流图示
    栗子:给目标元素(text)绑定click事件,实际的(text)元素在捕获阶段不会接收到事件,意味着在捕获阶段,事件从document到<body>再到<div>后就停止了。下一个阶段是“处于目标阶段”,于是事件在(text)上发生,并在事件处理中被看成是冒泡阶段的一部分。最后,冒泡阶段发生,事件又传播回文档。
    DOM层级越小,事件传播的消耗越小,在一定情况下也可以视为一种优化性能的手段

    比较常见的冒泡现象:

    <a href="http://www.sina.com" id='test'>sina</a></body>
    <script>
        document.onclick = function() {
            alert('doc click');
            return false;
        }
        var a = document.getElementById('test');
        a.onclick = function() {
            alert('a click');
        }
    </script>
    

    正常执行顺序
    1.从document慢慢找下去,判断当前元素是否是时间的触发源
    2.找到事件源,执行a元素上的onclick事件
    2.事件进入冒泡阶段,包含a元素的document的onclick事件
    3.事件完成,进入浏览器默认行为,即跳转。

    PS:如果当使用return false会打断后续行为,所以这里不会跳转
    使用event.preventDefault取消浏览器默认行为
    使用event.stopPropagation会取消冒泡,但不取消浏览器默认行为。

    CSS层叠规则(视图上的显示层级)

    显示的层级

    元素居中

    • 水平居中
      行内元素: text-align: center
      块级元素: margin: 0 auto
      absolute + transform
      flex + justify-content: center

    • 垂直居中
      line-height: height
      absolute + transform
      flex + align-items: center
      table

    • 水平垂直居中
      absolute + transform
      flex + justify-content + align-items

    CSS选择器问题

    优先级:!important > 行内样式 > #id > .class > tag > * > 继承 > 默认
    css选择器原理:采用递归方式,从右往左找,如body #box1 .box2 div span a
    1.浏览器会先找所有的a标签
    2.从这些a标签中找到父元素是span
    3.从这些span中找父元素是div
    4.从这些div中找父元素是.box2
    ........
    优化问题:
    1.层级越多需要找的时间越久,耗时,尽量直接写class或者id来找,层级顶多3层。
    2.尽量不要直接写div span a,因为页面上可能有很多a标签,spandiv,会更耗时。

    清除浮动

    只介绍以下两种我用的,其他不赘述
    1.(推荐)给浮动元素的父元素加上clearfix

    .clearfix{*zoom:1;}
    .clearfix:after{display:block; content:"clear"; height:0; clear:both; overflow:hidden; visibility:hidden;}
    

    2.给浮动元素结尾处添加一个空的div,并且clear:both;

    link 与 @import 的区别

    1.link功能较多,可以定义 RSS,定义 Rel 等作用,而@import只能用于加载 css
    2.当解析到link时,页面会同步加载所引的 css,而@import所引用的 css 会等到页面加载完才被加载,从体验来说,link要由于@import
    3.@import需要 IE5 以上才能使用
    4.link可以使用 js 动态引入,@import不行

    javascript数据类型

    值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
    引用数据类型:对象(Object)、数组(Array)、函数(Function)。
    区别:
    1.值类型变量是存放在栈区的(栈区指内存里的栈内存)
    2.引用类型顾名思义只是引用,数据是存在堆内存中,如果内存中的值变化,那么引用它的变量也会变化
    看下面栗子

    var a = [1,2,3];
    var b = a;
    a.push(4);
    console.log(b);  // [1,2,3,4]
    

    关于变量提升问题

    JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。来看这一段代码

    console.log(a,fun); // undefiend undefiend
    var a = 1;
    function fun(){}
    

    那么,JS执行以上代码时,实际执行顺序是这样的

    var a, fun;
    console.log(a,fun); 
    a = 1;
    fun = function (){}
    

    闭包

    js常见面试题之闭包

    script标签

    1.<script defer>: 异步加载,元素解析完成后执行
    2.<script async>: 异步加载,与元素渲染并行执行
    对于大多情况来说,script标签尽量放在html最底部引入进来,防止影响html以及css的加载,影响页面呈现的速度。

    对象的深拷贝浅拷贝问题

    讲一下简单实现原理
    1.浅拷贝:便利对象source的属性,然后赋值到新对象target上,如果source的某一个子属性是引用类型的,那么target复制的属性的内存地址与source的的子属性指向同一内存地址。会出现如下问题:

    //浅拷贝
    function shallow(target, source) {
        for (let i in source) {
            target[i] = source[i];
        }
        return target;
    }
    var obj1 = {
        name: 'obj1',
        arr: [1, 2, 3]
    },
    obj2 = {};
    //浅拷贝一次
    shallow(obj2, obj1);
    obj1.arr.push(4);
    console.log(obj2.arr); // [1,2,3,4]
    

    2.深拷贝:在浅拷贝基础上,遇到引用类型的值需要再次执行浅拷贝,也就是递归执行浅拷贝,就不会出现浅拷贝的问题

    function deep(target, source) {
        for (var i in source) {
            // 含有引用类型
            if (typeof source[i] === 'object') {
                // 这里可能是数组或者对象
                if (source[i].constructor == Array) {
                    target[i] = [];
                } else {
                    target[i] = {};
                }
                //需要递归执行deep拷贝
                deep(target[i], source[i]);
            } else {
                target[i] = source[i];
            }
        }
    }
    var obj1 = {
        name: 'obj1',
        arr: [1, 2, 3]
    },
    obj2 = {};
    //浅拷贝一次
    deep(obj2, obj1);
    obj1.arr.push(4);
    console.log(obj1.arr,obj2.arr); // [1,2,3,4]  [1,2,3]
    

    对于更多出现的情况请参考lodash拷贝

    new到底干了什么

    1.新生成一个对象obj
    2.链接到原型: obj.__proto__ = 对应的构造函数.prototype
    3.修改this执行: apply
    4.返回新对象

    相关文章

      网友评论

        本文标题:前端面试资料总结(持续更新)

        本文链接:https://www.haomeiwen.com/subject/takmeqtx.html