让前端飞前端开发

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

2019-02-16  本文已影响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层叠规则(视图上的显示层级)

显示的层级

元素居中

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.返回新对象

上一篇下一篇

猜你喜欢

热点阅读