2017 面经一

  1. CSS3动画与JS动画的区别?什么情况下使用JS动画?
  2. JS异步回调函数有什么缺陷?
  3. 前端优化
  4. promise
  5. script标签中的async和defer
  6. 不知道元素的宽度和高度,如何实现水平和垂直方向的居中(多种解决方法)
  7. 三栏布局
  8. 除了bootstrap能实现响应式布局,还有其它的框架吗?
  9. AJAX实现的过程
  10. 跨域的方式
  11. ==和===的区别?
  12. [1,2] == [1,2]
  13. 如何实现浮点数的相加,0.1+0.2===0.3
  14. flex布局
  15. 链式调用
  16. HTTP响应状态码
  17. 了解过vue和react区别吗
  18. IE和其它浏览器在JS和CSS样式方面有哪些区别?
  19. 描述webpack
  20. loader和插件plugin有什么区别?插件有什么优点?
  21. 什么是闭包?在必须使用闭包的情况下如何避免内存泄漏
  22. 项目中的登录模块如何实现
  23. CSRF和XSS是什么?如何预防网页攻击?
  24. em和rem
  25. webpack是基于CommonJs规范的,简述一下CommonJs/AMD/CMD?
  26. 尝试过给localStorage和sessionStorage封装过一些方法吗?
  27. cookie、localStorage、sessionStorage三者的区别?
  28. 浏览器如何实现cookie机制?
  29. CSS3中动画强制停止

不足:
1. 专注于一些基础知识,没有深入了解,以致于一些内部实现的机制都不了解。
2. 在巩固基础的前提下,再广度的学习。
3. 面试之前需要将自己的项目重新看一遍,而不是用一句“做了,忘了”敷衍了事。

总结:
人生第一次面试,感激自己迈出的第一步,看到了很多方面的不足,将基础知识打牢,再花时间去学习一些新框架和其它技术方面知识,“既保证了深度的情况下,也要保证广度学习”,本周将这些知识点了解并记录在博客中。(补充:博客记录的内容,偶尔花点时间重新看看)

一、CSS3动画与JS动画

运用JS动画已经是前半年做项目的时候,运用定时器实现了匀速、变速等动画。

而在学习CSS3动画的时候,发现更加简单,易操作,从此走上CSS3的不归路,从那基本没怎么用JS动画了。

即使这样,仍要了解一下两者的区别,以及在什么情况下必须使用JS动画。

搜了一大堆信息,并没有明确说什么时候必须用JS动画,都是在讲述CSS3动画如何高大上,如何赞…

那就从我自己的想法说一下吧。

在第三大点也说过了,尽量减少DOM操作,以及最小化重绘重排能实现前端的优化,而JS动画需要运用DOM操作实现元素效果的改变,以及元素的改变可能会导致整个页面大部分的重排reflow和重绘repaint。最重要的一点就是JS动画各种动画的实现比CSS3动画复杂了。

而在什么情况下我们必须用JS动画呢?

我觉得在涉及一些点位置不确定的情况,这时候就必须得用JS动画了。要不然你说说CSS3动画能运用表达式计算点,在或者是计算滚动条到顶部的位置实现滚动居中,在来个动画么…

目前我知道的只有这一个,后续如果知道了,会进行补充~


三、前端优化

对于目前的我来说,在实际操作中,比如我会减少JS、CSS中重复的代码,图片在一定情况下选择png格式。使用webpack工具将各种文件进行压缩和合并,从而减少HTTP请求数量和请求文件的体积大小,提高网页的响应速度。

在Js中尽量减少使用DOM操作

现在我会疑惑,为什么常说的DOM操作会影响性能? 传送门

现在在来梳理一下整体的思路:
1. 减少HTTP请求
原理:发起请求之前就需要建立一个TCP连接,这非常耗时。随着时代的发展,一个网页中内部的请求资源(多张图片、CSS文件、JS文件等)越来越多,这就需要我们发起多个HTTP请求。举个例子,请求1张100KB的图片比请求2张50KB的图片更快速。
方法:合并图片(CSS Sprite)、合并CSS、JS文件等、对于具有多张图片的页面可以使用延迟加载(Lazy Load)技术

2. 减少DOM访问和修改
原理:DOM的操作可能会改变元素的布局,导致渲染树中受影响的部分失效,重新构建该部分的渲染树。这也就是我们常说的”重排”。
方法:事件委托

3. 最小化重排和重绘
方法:将需要进行多次重排的元素设置为绝对定位元素,脱离文档流,这样不会影响其它元素,比如动画元素;在修改元素的布局时不要进行查询操作,否则会强制刷新渲染队列;同一个元素的多个属性可以进行合并;

4. 减少传输过程中实体的大小
方法:使用webpack等工具将代码进行压缩、在一定情况下图片选用png格式

5. JS放底部、CSS放顶部
(这里涉及加载、解析、渲染、阻塞等,后续会另写一篇文章详细介绍)

6. DNS解析优化
方法:DNS缓存、减少DNS查找、keep-alive


六、未知宽高元素的垂直水平居中

只回答了第一种,使用绝对定位结合translate()平移函数实现。当然这是CSS3新特性,对于IE8-的浏览器是不支持的。

<div id="box">
#box{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
}

今天了解了其它三种实现的方式
第二种实现方式:父元素设置table(即此元素会按照块级表格显示,类似<-table>标签,表格前后带有换行符),子元素设置table-cell(此元素会按照内联表格显示,类似<-table>标签,表格前后没有换行符)以及center/middle实现水平/垂直居中。

<div id="parent">
    <div id="son">
        <img src="1.jpg" alt="error">
    </div>
</div>
#parent{
    width:300px;
    height:300px;
    display:table;
    background-color:pink;
}
#son{
    display:table-cell;
    vertical-align:middle;
    text-align:center;
}

元素水平垂直居中

嘻嘻,为自己学习到另外一种解决的方法而高兴。
优点:父元素可以动态的改变宽度和高度(table元素的特性)
但是display:table也有不足的地方:
1. IE7-不支持。
2. 与其它display属性一样,会被float、position:absolute等属性所破坏。所以尽量不要一起使用。
3. display:table-cell对高度和宽度敏感,对于margin的设置是无效的(设置padding是有效的)

第三种实现方式:使用一个空标签span设置他的vertical-align基准线为中间,并且让他为inline-block,宽度为0(疑惑:还是不太理解原理,再慢慢研究)

<div class="parent">
    <span></span>
    <div class="child">hello world!</div>
</div>
.parent{
    height:800px;
    width: 800px;
    text-align: center;
    background: #FD0C70;
}
.parent span{
    display: inline-block;
    width: 0;
    height: 100%;
    vertical-align: middle;
    zoom: 1;/*BFC*/
    *display: inline;
}
.parent .child{
    display: inline-block;
    vertical-align: middle;
    color: #fff;
    zoom: 1;/*BFC*/
    *display: inline;
}

第四种实现方式:涉及到CSS3的flex布局,等面完找到合适的实习,一定要把布局看透。
(6月23日补充:原理其实这是将父元素设置为伸缩容器,再将其主轴和侧轴分别居中对齐,从而实现了垂直水平居中的效果)

<div class="parent">
        <div class="child">hello world!</div>
</div>
.parent{
    display: flex;
    justify-content: center;
    align-items: center;
    width: 300px;
    height:300px;
    background: #FD0C70;
}
.parent .child{
    color:#fff;
}

优点:简单 快捷
缺点:flex兼容性问题(三种版本分别兼容不同的浏览器)

八、响应式布局

其实从这个问题中,我更想了解一下响应式布局是什么?如何实现?

以前只知道适应不同的设备(手机端、PC端)有不同的分辨率,从而需要显示不同的样式。

很想知道如何去实现这个响应式布局,今天稍微整理一下心情。(以后会写一篇文章关于响应式布局,以及固定布局、流式布局、弹性布局四者区别)

结合弹性布局、弹性图片以及CSS3媒体查询(@media-query)实现响应式布局(responsive)

这里可以通过改变浏览器窗口大小实现尺寸大小的改变,不需要用多个不同屏幕的手机和平板进行测试,方便了我们的操作。

<div class="heading"></div>
<div class="container">
    <div class="left"></div>
    <div class="main"></div>
    <div class="right"></div>
</div>
<div class="footing"></div>
*{
    margin:0px;
    padding: 0px;
}
.heading,
.container,
.footing{
    margin: 10px auto;
}

.heading{
    height: 100px;
    background-color: red;
}

.left,
.right,
.main{
    height: 300px;
    background-color: yellow;
}
.footing{
    height: 100px;
    background-color: gray;
}
/*media="only screen and (min-width:960px)" 这句话的意思是:只要当渲染屏幕的宽度大于或等于960px的时候才会使用这个样式表*/

@media screen and (min-width: 960px){
    .heading,
    .container,
    .footing{
        width:960px;
    }

    .left,
    .main,
    .right{
        float: left;
        height: 500px;
    }

    .left,
    .right{
        width:200px;
    }

    .main{
        margin: 0px 5px;
        width:550px;
    }

    .container{
        height: 500px;
    }
}

min-width:960px

/*并且内部代码并不会全部覆盖原来的代码,只会覆盖设置为同一个属性的,比如.heading、.container、.footing这里重新设置了width属性等*/
@media screen and (min-width: 600px) and (max-width: 960px){
    .heading,
    .container,
    .footing{
        width: 600px;
    }

    .left,
    .main{
        float: left;
        height:400px;
    }

    .right{
        display: none;
    }

    .left{
        width: 160px;
    }

    .main{
        width: 435px;
        margin-left: 5px;
    }

    .container{
        height: 400px;
    }
}

600~900px

@media screen and (max-width: 600px){
    .heading,
    .container,
    .footing{
        width: 400px;
    }

    .left,
    .right{
        width: 400px;
        height: 100px;
    }

    .main{
        margin-top: 10px;
        width:400px;
        height:200px;
    }

    .right{
        margin-top: 10px;
    }

    .container{
        height: 420px;
    }
}

<900px


九、AJAX

  1. 创建一个异步调用对象,IE和其它浏览器不兼容
//其它浏览器
var xml = new XMLHttpRequest();
//IE浏览器
var xml = new ActiveXObject("Microsoft.XMLHttpRequest");
  1. 设置请求的参数(请求方法、请求URI、验证信息)
  2. 设置响应的状态变化函数
  3. 发送请求
  4. 获取异步回调函数
  5. 使用JavaScript Dom实现局部刷新

十、跨域的方式

由于同源策略的限制,AJAX不能实现跨域,保证了安全性
同源:协议、域名、端口号一致
1. 图片ping:原理是<-img>标签src属性不受同源策略的限制,可以访问其它域的图片资源
2. CORS(跨域资源共享)
3. JSONP:原理是<-script>标签不受同源策略的限制,可以访问其它域的脚本资源。在请求地址中加上回调函数名的参数,请求的文件接收到请求之后执行该回调函数,并传递Json格式数据的参数。

//basic.js
<script>
    function fn(){
        alert("hello");
    }
</script>
<script src="index.js?callback=fn"></script>
//index.js
fn({
"name":"suoz"
});


十一、十二 “==”与“===”

以前只知道==是判断数据的值,而===先判断两者的数据类型,再判断数据的值。
现在了解到==如果是两个不同类型的数据,还会将其中一个进行隐式类型的转换,转换成相同的类型再进行比较。

在了解的时候发现一个有意思的问题,toString() 和 valueOf()
toString()是将一个数据的类型转换为字符串类型;
valueOf()是将对象的原始值返回;

toString & valueOf 文章传送门

为什么去掉toString方法之后,会自动执行valueOf方法(疑惑点)

var color = ["pink","red"];
color.valueOf = function(){
    alert("valueOf");
};
alert(color);  //pink,red
color.__proto__.toString = null;

alert(color); //valueOf、undefined


”相等运算符”:对于两个基本数据类型的判断,原始类型的数据会转换成数值类型再进行比较。字符串和布尔值都会转换成数值

//在JavaScript中false、‘’、0和Null、undefined是两两“相等”的
alert(''==0);
alert(0==false);
alert(false=='');
alert(undefined==null);

注:一个值应该与其自身“相等/相同”,但存在一个例外:一个NaN值,与自身不相等,也不相同。

”相等运算符”:对于一个引用类型和一个基本数据类型的判断,对象转化成原始类型的值=>即自动执行valueOf(),再进行比较,(疑惑点:如果valueOf不存在,则调用toString)

var color = [10,2];
color.valueOf = function(){
    alert("valueOf");
    return this[0];
};
color.toString = function(){
    alert("toString");
    return this[0];
};

alert(color == '10'); //valueOf、true


”相等运算符”:对于两个引用类型的值,判断两者的引用地址

[1,2] == [1,2]; //false
var obj1= {"name":"suoz"}; 
var obj2= {"name":"suoz"};
alert(obj1 == obj2); //false(obj1和obj2引用地址不同)

总结:相等运算符隐藏的类型转换,会带来一些违反直觉的结果。

var a = undefined;
if(a == null){
    alert("1"); //1
}
if(a === null){
    alert("2"); //无输出
}

也就是说当a为undefined时,输出的值会有变化,而在编程中对象变成undefined实在是太常见了。这就是为什么建议尽量不要使用相等运算符”==”。

十三、0.1+0.2 !== 0.3

以前就涉及JS浮点数的问题。
据我所了解JavaScript在处理浮点数问题上,确实有精度方面的问题。
但是一直没有找到很好的解决方案

console.log(0.1+0.2);  //0.30000000000000004
console.log(0.28*100); //28.000000000000004

现在我想封装一个具备浮点数”加减乘除”算法对象。
只能解决一些常运用的浮点数算法,不过对于我来说足够了。
具体运用具体分析

//浮点数实现加减乘除 
var float_obj = {
    //加法
    add : function(num1,num2){
        var x,y,max,pow;
        try{
            x = num1.toString().split(".")[1].length;
        }catch(e){
            x = 0;
        }
        try{
            y = num2.toString().split(".")[1].length;
        }catch(e){
            y=0;
        }
        max = Math.max(x,y);
        pow = Math.pow(10,max);
        return (num1*pow + num2*pow)/pow;
    },
    //减法
    sub : function(num1,num2){
        return this.add(num1,-num2);
    },
    //乘法
    mul : function(num1,num2){
        var count = 0;
        var x = num1.toString();
        var y = num2.toString();
        try{
            count += x.split(".")[1].length;
        }catch(e){}
        try{
            count += y.split(".")[1].length
        }catch(e){}
        return (Number(x.replace(".",""))*Number(y.replace(".","")))/count;
    },
    //除法
    div : function(num1,num2){
        var t1=0,t2=0;
        var x,y;
        try{
            var t1 = num1.toString().split(".")[1].length;
        }catch(e){}
        try{
            var t2 = num2.toString().split(".")[1].length;
        }catch(e){}
        x = Number(num1.toString.replace(".",""));
        y = Number(num2.toString.replace(".",""));
        return (x/y)*Math.pow(10,r1-r2);
    }
};

实现代码:

    console.log(float_obj.add(0.1,0.2));  //0.3

七、十四 flex布局

flex布局文章传送门

十五 链式调用

链式调用,其实是在自己项目里实现过该功能。不过自己想得太多了,表述不清不楚,现在想起来对自己都觉得无语。

链式调用:我的思路就是创建一个对象,重新定义该对象的原型对象(定义的时候也要将constructor属性指向该函数),调用该对象的某个属性的时候,return返回该对象,这样就可以实现了多次调用该对象的属性。

//此处参数用id选择器
function Base(args){
    this.id = document.getElementById(args);
}
Base.prototype = function(){
    constructor : Base,
    a : function(){
        console.log("a方法");
        return this;
    },
    b : function(){
        console.log("b方法");
        return this;
    },
    c : function(){
        console.log("c方法");
        return this;
    }
};

function $(args){
    return new Base(args);
}
$('box').a().b().c();

链式调用的优点:代码简洁易读,减少多次重复使用同一个对象。

十八、IE与其它浏览器兼容性

在面试中只回答了JS方面的差异,对于样式的差异一时反应不过来,现在想想…平时用的opacity透明度、CSS3一些新特性在IE8-以下都不兼容!!当时怎么没想到(撞豆腐去了…)

JavaScript方面的差异:

1. 获取事件对象 window.event || event
2. 获取事件目标 srcElement || target
3. 阻止默认事件 returnValue || preventDefault()
4. 阻止事件冒泡 cancelBubble || stopPropagation
5. 获取非行间样式 currentStyle || getComputedStyle
6. 获取滚动条距离顶部的位置 document.documentElement.scrollTop || document.body.scrollTop
7. 设置float样式 element.style.styleFloat || element.style.cssFloat
8. 创建异步调用对象 XMLHttpRequest() || ActiveXObject("Microsoft.XMLHttpRequest")
9. 获取可见区域/窗口的大小 document.documentElement.clientWidth ||  window.innerWidth 
10. 访问元素的class getAttribute("className") || getAttribute("class")
11. 获取鼠标指针的位置 window.event.clientX || event.pageX
12. 自定义属性问题 IE下可以使用获取常规属性的方法去获取自定义属性+getAttribute() || getAttribute()

CSS样式方面的差异

1. 透明度 filter(alpha:opacity=100) || opacity:1
2. border-radius
3. transform:scale() skew() translate() rotate()
4. 盒模型 IE5-低版本浏览器盒模型相当于box-sizing:border-box || W3C标准盒模型相当于box-sizing:content-box
5. 其它的CSS新特性
6. 后续会慢慢补充

二十一、闭包

闭包:一个能够访问外部函数变量的函数
通过闭包可以避免全局变量的污染、以及访问函数内私有变量的值。
但是闭包的滥用会导致内存泄漏问题
内存泄漏:不需要的对象仍然存在内存中
扩展:执行完一个外部函数,此时会销毁该函数的执行环境和作用域,由于闭包还引用着外部函数的变量,因此外部函数的活动对象不会被销毁,此时内存占用相对于其它函数较大。
在必须使用闭包的情况下,如何避免”内存泄漏”的问题:
在该闭包执行完毕的时候,将闭包赋值为null

二十二、登录模块

我觉得自己在这一方面有很多不足之处,先来分析一下,如果让我去设计一个登录模块,具体的步骤吧。

  1. 首先会设计好这个登录模块界面效果,并实现
  2. 涉及有哪些数据(用户名、密码),并设计数据库表
  3. 用户不仅需要输入用户名、密码,还要进行验证码的判断,以及是否N天内免登录操作(COOKIE实现)。
  4. 将用户输入的form表单进行判断,数据是否为空、输入不正确的字符、将数据进行Html解析和过滤,以防止XSS攻击。这个步骤也就是客户端信息的验证。
  5. 接下来为了更安全点,还要进行服务器端的验证。将用户输入的数据与数据库中的数据进行比较,如果正确则使用AJAX异步回调函数进行页面的跳转(并且使用cookie保存用户名等信息保存在客户端,实现了跳转页面用户仍能获取这些数据,不用再次向数据库获取),反之错误。

二十三、CSRF和XSS

XSS(跨站脚本攻击):一些具有安全漏洞的网页,由于html注入的问题,没有将代码进行过滤和解析,最终显示给其它来访的用户,导致用户在不知情的情况下执行恶意代码,达到获取和修改重要信息的目的。

解决方法:
1. 将用户输入的信息进行过滤、解析
2. 使用HTTP指定的内容类型(Content-Type),使得输出的内容避免被作为HTML被解析。

CSRF(跨站请求伪造):源于Web的隐式身份验证机制,Web验证机制只能确认一个请求来自某用户的浏览器,却不能保证该请求是用户批准发送的。

过程:
1. 登录网站A,生成cookie
2. 在不退出网站A的前提下,进入恶意网站B,此时网站B会通过一些手段伪装成该用户,获取用户COOKIE等重要信息

解决方法:
1. 验证HTTP Referer字段:Referer字段中保存着发送请求的URL地址。通常访问一个安全受限的页面时,必须保证请求来自同一个网站。(在每次请求的时候,服务器端验证Referer字段内容是否与访问的网站相关域名一致,如果一致则请求成功;如果不一致则为其它恶意网站访问,拒绝访问)
2. 在请求地址中添加Token并验证:在服务器端生成随机字符串(请求令牌Token),并保存在Session中。然后在发送请求的页面中,以隐藏域的形式随其它信息一并发出。服务器端获取传递过来的Token与Session中的Token进行比较,如果一致则请求成功,如果不一致有可能是CSRF攻击)
3. HTTP头添加自定义属性并验证: 在HTTP头中加上csrfToken自定的属性,然后传入Token的值,发送至服务器端。服务器端获取相关的信息,进行比较,如果一致则请求成功。HTTP头自定义属性解决了前一种方法中Token随其它信息一起传递的不便。

二十四、rem与em

两者都是相对单位。
em是相对于父元素的字体大小
rem是相对于文档根元素<-html>的字体大小

<span>hello world</span>
<div id="parent">
    <span>hello world</span>
</div>
html{
    font-size:20px;
}
span{
    font-size:10rem;
}
#parent{
    font-size:10px;
}
#parent span{
    font-size:10rem;
}

二十九、CSS3动画停止

CSS3动画

animation-name:指定实现的动画名称
animation-duration:动画播放的时间
animation-timing-function:动画播放的方式
[linear] | [ease] | [ease-in] | [ease-out] | [ease-in-out]
animation-delay:动画开始播放的时间
animation-iteration-count:动画播放的次数
[inifinite] | [number]
animation-direction:动画播放的方向
[normal] | [alternate]
animation-play-state:动画的状态
[running] | [paused]
animation-fill-mode:动画时间外属性
[node] | [forwards] | [backwards] | [both]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值