2017前端面试题总结

1:为什么选择前端这个方向和对前端的理解javascript

为何:php

第一的话就是对前端很感兴趣,以前也接触过其余的语言,可是直到接触到前端才发现真的有兴趣作下去,兴趣是一我的最好的老师,css

第二的话前端颇有前途,像如今nodejs,rn,微信小程序这类工具和框架可让前端进行后端和移动开发,因此我以为前端的前途会更多一点。html

理解:前端

首先前端工程师最核心的技能仍是:Html、CSS、JS。前端负责的是用户能够看到的部分,因此也是最接近用户的工程师。同时在产品研发流程中前端要同时与产品、设计、后端等不少人合做。vue

2:Vue双向数据绑定的实现html5

vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,经过Object.defineProperty()来劫持各个属性的settergetter,在数据变更时发布消息给订阅者(文本节点则是做为订阅者),在收到消息后执行相应的更新操做。java

compile主要作的事情是解析模板指令,将模板中的变量替换成数据,而后初始化渲染页面视图,并将每一个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变更,收到通知,更新视图node

MVVM做为数据绑定的入口,整合Observer、Compile和Watcher三者,经过Observer来监听本身的model数据变化,经过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通讯桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变动的双向绑定效果。react

AngularJS 采用“脏值检测”的方式,数据发生变动后,对于全部的数据和视图的绑定关系进行一次检测,识别是否有数据发生了改变。

3:react和vue有哪些不一样 说说你对这两个框架的见解

都用了virtual dom的方式, 性能都很好

ui上都是组件化的写法,开发效率很高

vue是双向数据绑定,react是单项数据绑定,当工程规模比较大时双向数据绑定会很难维护

vue适合不会持续的  小型的web应用,使用vue.js能带来短时间内较高的开发效率. 不然采用react

4:let和const的区别

let声明的变量能够改变,值和类型均可以改变,没有限制。

const声明的变量不得改变值

5:平时用了es6的哪些特性,体验如何 和es5有什么不一样

let const关键字 箭头函数 字符串模板 class类 模块化 promise

es5 require react.createclass

6:浏览器原生支持module吗,若是支持,会带来哪些便利

不支持

7:介绍一下你对webpack的理解,和gulp有什么不一样

Webpack是模块打包工具,他会分析模块间的依赖关系,而后使用loaders处理它们,最后生成一个优化而且合并后的静态资源。

gulp是前端自动化工具 可以优化前端工做流程,好比文件合并压缩

8:webpack打包速度慢,你以为可能的缘由是什么,该如何解决

模块太多

Webpack 能够配置 externals 来将依赖的库指向全局变量,从而再也不打包这个库 或者dllplugin

webpack-parallel-uglify-plugin 并行压缩

CommonsChunkPlugin提取公共的模块

happypack 多进程构建

9:http响应中content-type包含哪些内容

请求中的消息主体是用何种方式编码

application/x-www-form-urlencoded

这是最多见的 POST 提交数据的方式 按照 key1=val1&key2=val2 的方式进行编码

application/json

告诉服务端消息主体是序列化后的 JSON 字符串

10:浏览器缓存有哪些,一般缓存有哪几种方式

强缓存 强缓存若是命中,浏览器直接从本身的缓存中读取资源,不会发请求到服务器。

协商缓存 当强缓存没有命中的时候,浏览器必定会发送一个请求到服务器,经过服务器端依据资源的另一些http header验证这个资源是否命中协商缓存,若是协商缓存命中,服务器会将这个请求返回(304),若未命中请求,则将资源返回客户端,并更新本地缓存数据(200)。

HTTP头信息控制缓存

Expires(强缓存)+过时时间   ExpiresHTTP1.0提出的一个表示资源过时时间的header,它描述的是一个绝对时间

Cache-control(强缓存) 描述的是一个相对时间,在进行缓存命中的时候,都是利用客户端时间进行判断 管理更有效,安全一些 Cache-Control: max-age=3600

服务端返回头Last-Modified/ 客户端请求头If-Modified-Since(协商缓存) 标示这个响应资源的最后修改时间。Last-Modified是服务器相应给客户端的,If-Modified-Sinces是客户端发给服务器,服务器判断这个缓存时间是不是最新的,是的话拿缓存。

服务端返回头Etag/客户端请求头If-None-Match(协商缓存) etag和last-modified相似,他是发送一个字符串来标识版本。

强缓存不请求服务器,客户端判断 、协商缓存要请求服务器

11:如何取出一个数组里的图片并按顺序显示出来

function loadImage(imgList,callback){
        if(!$.isArray(imgList) || !$.isFunction(callback)) return ;
        var imageData = [] ;
        $.each(imgList, function(i,src){
            var img = new Image() ;
            img.onload = function(){
                $(imageData.shift()).appendTo("body") ;
                if(!imageData.length){
                    callback() ;
                    return ;
                }
                this.onload = null ;
            } ;
            img.src= src ;
            imageData.push(img) ;
        }) ;
    } ;
async function loadImgs(imgList, cb) {

    console.log("start")
    for( var i =0; i<imgList.length; i++) {
        await imgLoader(imgList[i], i);
        console.log("finish"+i)
    }
    cb();
}

async function imgLoader(url, num){
    return new Promise((resolve, reject) => {
        console.log("request"+num)
        
        setTimeout(resolve, 1000);
        // let img = new Image();
        // img.onload = () => resolve(img);
        // img.onerror = reject;

        console.log("return"+num)
    })
}

loadImgs(["xxx/a.png","xxx/b.png"],function() {
	console.log("开始干活");
})

12:平时是怎么学新技术的

伯乐在线 infoq 掘金 简书 慕课网

13:Node,Koa用的怎么样

koa是一个相对于express来讲,更小,更健壮,更富表现力的Web框架,不用写回调

koa是从第一个中间件开始执行,遇到next进入下一个中间件,一直执行到最后一个中间件,在逆序

async await语法的支持

 

14:使用模块化加载时,模块加载的顺序是怎样的,若是不知道,根据已有的知识,你以为顺序应该是怎么样的

commonjs 同步 顺序执行

AMD 提早加载,无论是否调用模块,先解析全部模块 requirejs 速度快 有可能浪费资源

CMD 提早加载,在真正须要使用(依赖)模块时才解析该模块 seajs 按需解析 性能比AMD差

 

15: 介绍一下闭包和闭包经常使用场景

  • 闭包是指有权访问另外一个函数做用域中的变量的函数. 建立闭包常见方式,就是在一个函数内部建立另外一个函数.
  • 本质上,闭包就是将函数内部和函数外部链接起来的一座桥梁。

应用场景 设置私有变量和方法让这些变量的值始终保持在内存中还有读取函数内部变量。

不适合场景:返回闭包的函数是个很是大的函数

闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易形成内存泄露。

  function f1(){

    var n=999;

    function f2(){
      alert(n); 
    }

    return f2;

  }

  var result=f1();

  result(); // 999

  

16: 为何会出现闭包这种东西,解决了什么问题

受JavaScript链式做用域结构的影响,父级变量中没法访问到子级的变量值,为了解决这个问题,才使用闭包这个概念

17: 介绍一下你所了解的做用域链,做用域链的尽头是什么,为何

每个函数都有一个做用域,好比咱们建立了一个函数,函数里面又包含了一个函数,那么如今 就有三个做用域,这样就造成了一个做用域链。

做用域的特色就是,先在本身的变量范围中查找,若是找不到,就会沿着做用域链往上找。

18: 一个Ajax创建的过程是怎样的,主要用到哪些状态码

ajax:在不切换页面的状况下完成异步的HTTP请求

(1)建立XMLHttpRequest对象,也就是建立一个异步调用对象.

(2)建立一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.

(3)设置响应HTTP请求状态变化的函数.

(4)发送HTTP请求.

(5)获取异步调用返回的数据.

(6)使用JavaScript和DOM实现局部刷新.

  var xmlHttp = new XMLHttpRequest();

    xmlHttp.open('GET','demo.php','true');

    xmlHttp.send()

    xmlHttp.onreadystatechange = function(){

        if(xmlHttp.readyState === 4 & xmlHttp.status === 200){

        }

    }

使用promise封装

function getJSON(url) {  
    return new Promise(function(resolve, reject) {  
        var XHR = new XMLHttpRequest();  
        XHR.open('GET', url, true);  
        XHR.send();  
  
        XHR.onreadystatechange = function() {  
            if (XHR.readyState == 4) {  
                if (XHR.status == 200) {  
                    try {  
                        var response = JSON.parse(XHR.responseText);  
                        resolve(response);  
                    } catch (e) {  
                        reject(e);  
                    }  
                } else {  
                    reject(new Error(XHR.statusText));  
                }  
            }  
        }  
    })  
}  
  
getJSON(url).then(res => console.log(res));  

  

 

当前状态readystate

0 表明未初始化。 尚未调用 open 方法
1 表明正在加载。 open 方法已被调用,但 send 方法尚未被调用
2 表明已加载完毕。send 已被调用。请求已经开始
3 表明交互中。服务器正在发送响应
4 表明完成。响应发送完毕

经常使用状态码status

404 没找到页面(not found)
403 禁止访问(forbidden)
500 内部服务器出错(internal service error)
200 一切正常(ok)
304 没有被修改(not modified)(服务器返回304状态,表示源文件没有被修改)

19: 说说你还知道的其余状态码,状态码的存在解决了什么问题

302/307  临时重定向

301 永久重定向

借助状态码,用户能够知道服务器端是正常处理了请求,仍是出现了什么错误

20: 知道语义化吗?说说你理解的语义化,若是是你,平时会怎么作来保证语义化

像html5的新的标签header,footer,section等就是语义化

一方面,语义化就是让计算机可以快速的读懂内容,高效的处理信息,能够对搜索引擎更友好。

另外一方面,便于与他人的协做,他人经过读代码就能够理解你网页标签的意义。

21: 说说content-box和border-box,为何看起来content-box更合理,可是仍是常用border-box

content-box 是W3C的标准盒模型 元素宽度=内容宽度+padding+border

border-box 是ie的怪异盒模型  他的元素宽度等于内容宽度  内容宽度包含了padding和border

 好比有时候在元素基础上添加内距padding或border会将布局撑破 可是使用border-box就能够轻松完成

22:介绍一下HTML5的新特性

  • 新的DOCTYPE声明  <!DOCTYPE html> 
  • 彻底支持css3
  • video和audio
  • 本地存储
  • 语义化标签
  • canvas
  • 新事件 如ondrag onresize

23:对本身将来的规划是怎样的

对于刚毕业的人来讲,前两年是很重要的,先打好基础,多提高js能力。三至四年在提高JS能力的同时,开始要往多方面发展,前端工程师远远不只是JS而已。制做一个性能高、交互好、视觉美的页面,须要从前端框架选型、架构设计、构建工具,到后端通讯机制、设计与交互、网络和浏览器优化等各方面的知识。一专多长才是前端工程师的终极目标。

 24: 在一个UI李有10个li,实现点击对应的li,输出对应的下标

var lis = querySelectorAll('li')
for(var i=0;i<10;i++){
   lis[i].onclick = (function(a) {
      return function() {
       alert(a)
    }
  })(i) 
}    

  事件委托

利用冒泡的原理,把事件加到父级上,触发执行效果。

1.能够大量节省内存占用,减小事件注册。
2.能够方便地动态添加和修改元素,不须要由于元素的改动而修改事件绑定。
var ul = document.querySelector('ul');  
var list = document.querySelectorAll('ul li');  
  
ul.addEventListener('click', function(ev){  
    var ev = ev || window.event;  
    var target = ev.target || ev.srcElemnt;  
  
    for(var i = 0, len = list.length; i < len; i++){  
        if(list[i] == target){  
            alert(i + "----" + target.innerHTML);  
        }  
    }  
});  

25:实现三个DIV等分排布在一行(考察border-box)

1.设置border-box width33.3%

2.flexbox flex:1 

26: 说说你知道JavaScript的内存回收机制

垃圾回收器会每隔一段时间找出那些再也不使用的内存,而后为其释放内存。

通常使用标记清除方法  当变量进入环境标记为进入环境,离开环境标记为离开环境

还有引用计数方法

堆栈

stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小不定也不会自动释放。

基本数据类型存放在栈中

引用类型 存放在堆内存中,首先从栈中得到该对象的地址指针,而后再从堆内存中取得所需的数据

27函数防抖和函数节流

函数防抖是指频繁触发的状况下,只有足够的空闲时间,才执行代码一次

函数防抖的要点,也是须要一个setTimeout来辅助实现。延迟执行须要跑的代码。
若是方法屡次触发,则把上次记录的延迟执行代码用clearTimeout清掉,从新开始。
若是计时完毕,没有方法进来访问触发,则执行代码。

//函数防抖
var timer = false
document.getElementById("debounce").onScroll = function() {
        clearTimeout(timer)   
        timer = setTimeout(function(){
                console.log(‘函数防抖’)  
  }, 300)      
}

函数节流是指必定时间内js方法只跑一次

函数节流的要点是,声明一个变量当标志位,记录当前代码是否在执行。
若是空闲,则能够正常触发方法执行。
若是代码正在执行,则取消此次方法执行,直接return

//函数节流
var canScroll = true;
document.getElementById('throttle').onScroll = function() {
               if (!canScroll) {
                return;
               } 
                canScroll = false;
                setTimeout(function(){
                   console.log('函数节流');
                   canScroll = true;
                },300)        
}

  

28:编程实现输出一个数组中第N大的数据

29.实现两栏布局有哪些方法

*{margin:0; padding: 0;}
html,body{
        height: 100%;/*高度百分百显示*/
}
#left{
    width: 300px;
    height: 100%;
    background-color: #ccc;
    float: left;
}
#right{
    height: 100%;
    margin-left: 300px;
    background-color: #eee;

  

*{margin:0; padding: 0;}
html,body{
        height: 100%;/*高度百分百显示*/
}
#left{
    width: 300px;
    height: 100%;
    background-color: #ccc;
    float: left;
}
#right{
    height: 100%;
    overflow:hidden;
    background-color: #eee;
}

第二种方法,我利用的是建立一个新的BFC(块级格式化上下文)来防止文字环绕的原理来实现的。BFC就是一个相对独立的布局环境,它内部元素的布局不受外面布局的影响。它能够经过如下任何一种方式来建立: 
float 的值不为 none 
position 的值不为 static 或者 relative 
display 的值为 table-cell , table-caption , inline-block , flex , 或者 inline-flex 中的其中一个 
overflow 的值不为 visible

第三种flex布局

30:设置width的flex元素,flex属性值是多少

flex属性是flex-growflex-shrink 和 flex-basis的简写

flex-grow属性定义项目的放大比例,默认为0

flex-shrink属性定义了项目的缩小比例,默认为1

flex-basis属性定义了项目的固定空间

31get和post有什么不一样

 get是从服务器上获取数据,post是向服务器传送数据

get请求能够将查询字符串参数追加到url的末尾; post请求应该把数据做为请求的主体提交.

get请求数据有大小限制;post没有

post比get安全性更高

32:cookie和session有什么联系和区别

cookie数据存放在客户的浏览器上,session数据放在服务器上。

session比cookie更安全

单个cookie保存的数据不能超过4K,不少浏览器都限制一个站点最多保存20个cookie。

通常用cookie来存储sessionid

33:判断链表是否有环

使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则二者相遇;如不存在环,fast遇到NULL退出。

34:输出二叉树的最小深度

 判断左子树或右子树是否为空,若左子树为空,则返回右子树的深度,反之返回左子树的深度,若是都不为空,则返回左子树和右子树深度的最小值。

35: javaScript中的this是什么,有什么用,它的指向是什么

全局代码中的this  是指向全局对象

做为对象的方法调用时指向调用这个函数的对象。

做为构造函数指向新建立的对象

使用apply和call设置this

36写一个快速排序

 var quickSort = function (arr){
        if(arr.lenght <= 1) {
           return arr;
          }

       var left = [];
       var right = [];
       var mid = arr.splice(Math.floor(arr.length/2), 1);

       for(var i=0;i<arr.length;i++){
             if(arr[i]<mid) {
                 left.push(arr[i]);
            }
             if(arr[i]>mid) {
                 right.push(arr[i]);
            }
          return quickSort(left).concat(mid, quickSort(right));
     }   
}   

37怎么实现从一个DIV左上角到右下角的移动,有哪些方法,都怎么实现

改变left值为window宽度-div宽度 top值为window高度-div高度

jquery的animate方法

css3的transition

38: 简单介绍一下promise,他解决了什么问题

Promise,就是一个对象,用来传递异步操做的消息。有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。

有了 Promise 对象,就能够将异步操做以同步操做的流程表达出来,避免了层层嵌套的回调函数。

 

39: 写一个组合继承

var Super = function(name){
  this.name = name;
}
Super.prototype.func1 = function() { console.log('func1'); }
var Sub = function(name,age) {
  Super.call(this, name);
  this.age = age;
}
Sub.prototype = new Super();

40:深拷贝方案有哪些,手写一个深拷贝

var clone = function(v) {
  var o = v.constructor === Array ? [] : {};
  for (var i in v) {
    o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i];
  }
  return o;
}

41:判断数组有哪些方法

a instanceof Array
a.constructor == Array
Object.prototype.toString.call(a) == [Object Array]

42: 跨域通讯有哪些方案,各有什么不一样

JSONP:因为同源策略的限制,XmlHttpRequest只容许请求当前源,script标签没有同源限制

经过动态<script>元素使用,使用时为src指定一个跨域url。回调函数处理JSON数据  兼容性好 不支持post

简述原理与过程:首先在客户端注册一个callback, 而后把callback的名字传给服务器。此时,服务器先生成一个function , function 名字就是传递上来的参数。最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据做为参数,传入到了客户端预先定义好的 callback 函数里

  <script>  
  var url = "http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=callbackfunction";   
  var script = document.createElement('script');   
  script.setAttribute('src', url);  //load javascript    
  document.getElementsByTagName('head')[0].appendChild(script);   
  
  //回调函数  
   function callbackfunction(data){  
var html=JSON.stringify(data.RESULTSET);  
alert(html);  
     }  

cors:经过设置Access-Control-Allow-Origin来容许跨域 cors可用ajax发请求获取数据 可是兼容性没有jsonp好 

43:多页面通讯有哪些方案,各有什么不一样

localstorge在一个标签页里被添加、修改或删除时,都会触发一个storage事件,经过在另外一个标签页里监听storage事件,便可获得localstorge存储的值,实现不一样标签页之间的通讯。

settimeout+cookie

44:用Node实现一个用户上传文件的后台服务应该怎么作

multer模块

45: XSS和CSRF攻击

xss:好比在一个论坛发帖中发布一段恶意的JavaScript代码就是脚本注入,若是这个代码内容有请求外部服务器,那么就叫作XSS

写一个脚本将cookie发送到外部服务器这就是xss攻击可是没有发生csrf

防范:对输入内容作格式检查 输出的内容进行过滤或者转译

CSRF:又称XSRF,冒充用户发起请求(在用户不知情的状况下),完成一些违背用户意愿的请求 如恶意发帖,删帖

好比在论坛发了一个删帖的api连接 用户点击连接后把本身文章给删了 这里就是csrf攻击没有发生xss

防范:验证码 token 来源检测

46:圣杯布局和双飞翼布局

【圣杯布局】

html代码中  middle部分首先要放在container的最前部分。而后是left,right

1.将三者都 float:left , 再加上一个position:relative (由于相对定位后面会用到)

2.middle部分 width:100%占满

3.此时middle占满了,因此要把left拉到最左边,使用margin-left:-100%

4.这时left拉回来了,但会覆盖middle内容的左端,要把middle内容拉出来,因此在外围container加上 padding:0 220px 0 200px

5.middle内容拉回来了,但left也跟着过来了,因此要还原,就对left使用相对定位 left:-200px  同理,right也要相对定位还原 right:-220px

6.到这里大概就自适应好了。若是想container高度保持一致能够给left middle right都加上min-height:130px

【双飞翼布局】

前几步都同样 后边把外围padding和相对定位作法换成内层margin

给middle增长一个内层div-- middle-inner, 而后margin:0 220px 0 200px

47:offsetHeight, scrollHeight, clientHeight分别表明什么

clientHeight:包括内容可见部分的高度,可见的padding;不包括border,水平方向的scrollbarmargin

offsetHeight:包括内容可见部分的高度,border,可见的padding,水平方向的scrollbar(若是存在);不包括margin

scrollHeight:包括内容的高度(可见与不可见),padding(可见与不可见);不包括bordermargin

48:垂直居中

单行行内元素 1.能够设置padding-top,padding-bottom 2.将height和line-height设为相等

多行行内元素 1.能够将元素转为table样式,再设置vertical-align:middle; 2.使用flex布局

块级元素

已知高度绝对定位负边距

未知高度transform: translateY(-50%);

flex布局 
display: flex;
justify-content: center;
align-items: center;

49:transition的属性值和应用

属性的名称 过渡时间 时间曲线 延迟

50:rem和em的区别

em相对于父元素,rem相对于根元素

51:严格模式的特性

严格模式对Javascript的语法和行为,都作了一些改变。

全局变量必须显式声明。

对象不能有重名的属性

函数必须声明在顶层

  • 消除Javascript语法的一些不合理、不严谨之处,减小一些怪异行为;
  • 消除代码运行的一些不安全之处,保证代码运行的安全;
  • 提升编译器效率,增长运行速度;
  • 为将来新版本的Javascript作好铺垫。

52:js的原型链,如何实现继承?

原型链实际上就是js中数据继承的继承链。
在访问一个实例的属性的时候,如今实例自己中找,若是没找到就去它的原型中找,还没找到就再往上找,直到找到。这就是原型链。

function foo(){}
foo.prototype.z = 3;
var obj = new foo();
obj.x=1;
obj.y=2;
obj.x //1
obj.y //2
obj.z //3

obj.__proto__===foo.prototype true
foo.prototype.constructor === foo

53:图片预加载和懒加载

预加载:

function loadImage(url, callback) {
    var img = new Image();
    img.src = url;
    if (img.complete) { // 若是图片已经存在于浏览器缓存,直接调用回调函数 防止IE6不执行onload BUG
        callback.call(img);
        return;
    }
    img.onload = function () {
        callback.call(img);//将回调函数的this替换为Image对象
    };
};

懒加载:

当网页滚动的事件被触发 -> 执行加载图片操做 -> 判断图片是否在可视区域内 -> 在,则动态将data-src的值赋予该图片。

 

  var aImages = document.getElementById("SB").getElementsByTagName('img'); //获取id为SB的文档内全部的图片
  loadImg(aImages);
  window.onscroll = function() { //滚动条滚动触发
  loadImg(aImages);
  };
  //getBoundingClientRect 是图片懒加载的核心
  function loadImg(arr) {
  for(var i = 0, len = arr.length; i < len; i++) {
   if(arr[i].getBoundingClientRect().top < document.documentElement.clientHeight && !arr[i].isLoad) {
   arr[i].isLoad = true; //图片显示标志位
   //arr[i].style.cssText = "opacity: 0;";
   (function(i) {
    setTimeout(function() {
    if(arr[i].dataset) { //兼容不支持data的浏览器
     aftLoadImg(arr[i], arr[i].dataset.imgurl);
    } else {
     aftLoadImg(arr[i], arr[i].getAttribute("data-imgurl"));
    }
    arr[i].style.cssText = "transition: 1s; opacity: 1;" //至关于fadein
    }, 500)
   })(i);
   }
  }
  }

  function aftLoadImg(obj, url) {
  var oImg = new Image();
  oImg.onload = function() {
   obj.src = oImg.src; //下载完成后将该图片赋给目标obj目标对象
  }
  oImg.src = url; //oImg对象先下载该图像
  }

 

54.输入网址后到页面展示的过程

经过dns解析获取ip

tcp连接

客户端发送http请求

tcp传输报文

服务器处理请求返回http报文

客户端解析渲染页面 (构建DOM树 –> 构建渲染树 –> 布局渲染树:计算盒模型位置和大小 –> 绘制渲染树)

 

55:UMD规范和ES6模块化,Commonjs的对比

CommonJS是一个更偏向于服务器端的规范。用于NodeJS 是同步的

AMD是依赖前置的

CMD推崇依赖就近,延迟执行。能够把你的依赖写进代码的任意一行

AMD和CMD都是用difine和require,可是CMD标准倾向于在使用过程当中提出依赖,就是无论代码写到哪忽然发现须要依赖另外一个模块,那就在当前代码用require引入就能够了,规范会帮你搞定预加载,你随便写就能够了。可是AMD标准让你必须提早在头部依赖参数部分写好(没有写好? 倒回去写好咯)。这就是最明显的区别。

UMD写一个文件须要兼容不一样的加载规范

ES6经过importexport实现模块的输入输出。其中import命令用于输入其余模块提供的功能,export命令用于规定模块的对外接口。

56:http请求头

get post delete put head options trace connect

OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法

57:nginx的好处?和node的比较

高并发 响应快

区别不是很大,一个更专业,一个更全面:
1.类似点:
1.1异步非阻塞I/O, 事件驱动;
2.不一样点:
2.1Nginx 采用C编写,更性能更高,可是它仅适合于作web服务器,用于反向代理或者负载均衡等服务;Nginx背后的业务层编程思路很仍是同步编程方式,例如PHP.
2.2NodeJs高性能平台,web服务只是其中一块,NodeJs在处理业务层用的是JS编写,采用的是异步编程方式和思惟方式。

58.框架问题

  • 什么是 MVVM , 和 MVC 是什么区别, 原理是什么?

  mvc的界面和逻辑关联紧密,数据直接从数据库读取,必须经过Controller来承上启下,通讯都是单向的。mvvm的View 和 ViewModel能够互相通讯,界面数据从viewmodel中获取。

  • 父子组件怎么通讯的?
  vue:父组件是经过props属性给子组件通讯  在子组件里面emit,在父组件监听
  react:props传递  父给子传一个回调函数 将数据传给父亲处理
  • 兄弟组件怎么通讯的?

  vuex 创建一个vue实例 emit触发事件 on监听事件

  redux  子A -> 父 -> 子B

  • 生命周期有哪些, 怎么用?
  beforecreated:el 和 data 并未初始化 
  created:完成了 data 数据的初始化,el没有
  beforeMount:完成了 el 和 data 初始化 

  mounted :完成挂载  updated;destroyed

  react:初始化阶段、运行中阶段、销毁阶段

  初始化getDefaultProps()getInitialState()初始化

    componentWillMount() 在组件即将被渲染到页面

  render() 组件渲染
    componentDidMount() 组件被渲染到页面上,

  运行中shouldComponentUpdate() componentWillUpdate() render() componentDidUpdate() 
  销毁componentWillUnmount()

59:清除浮动

两种原理:

一、利用clear属性进行清理

具体的实现原理是经过引入清除区域,这个至关于加了一块看不见的框把定义clear属性的元素向下挤
父容器结尾插入空标签<div style="clear: both;"></div>

利用CSS伪元素:

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

经过将这个类添加到父容器当中,会在父容器的末尾增长了一个高度为0、具备清除属性的、不可见的块级元素。

二、将父容器造成BFC

BFC能清理浮动主要运用的是它的布局规则:

  1. 内部的Box会在垂直方向,一个接一个地放置。
  2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
  3. 每一个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,不然相反)。即便存在浮动也是如此。
  4. BFC的区域不会与float box重叠。
  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  6. 计算BFC的高度时,浮动元素也参与计算

浮动清理利用的主要是第六条规则,只要将父容器触发为BFC,就能够实现包含的效果。

那么触发BFC有哪几种方法?

  1. 根元素
  2. float属性不为none
  3. position为absolute或fixed
  4. display为inline-block, table-cell, table-caption, flex, inline-flex
  5. overflow不为visible

60.前端性能优化

1.减小http请求 使用sprite图、合并js和css文件

2.使用cdn 将用户安排在近的服务器上

3.使用缓存 缓存ajax 使用外部的css和js以便缓存 使用expire cach-control etag

4.压缩资源 使用gzip压缩js和css文件

5.代码层面 避免使用样式表达式、通配符选择器、样式放在顶部、脚本放在底部

61.事件模型和事件代理

事件三个阶段:事件捕获,目标,事件冒泡(低版本ie不支持捕获阶段)

w3c绑定事件target.addEventListener(event,handler,false)

解绑target.removeEventListener(eventType, handler, false)

ie绑定 target.attachEvent(on+event, handler)

解绑target.detachEvent("on"+eventType, handler)

事件代理优势:

  • 能够大量节省内存占用,减小事件注册,好比在table上代理全部td的click事件就很是棒

  • 能够实现当新增子对象时无需再次对其绑定事件,对于动态内容部分尤其合适

bind和trigger实现:

建立一个类或是匿名函数,在bind和trigger函数外层做用域建立一个字典对象,用于存储注册的事件及响应函数列表,bind时,若是字典没有则建立一个,key是事件名称,value是数组,里面放着当前注册的响应函数,若是字段中有,那么就直接push到数组便可。trigger时调出来依次触发事件响应函数便可。

function Emitter() {
    this._listener = [];//_listener[自定义的事件名] = [所用执行的匿名函数1, 所用执行的匿名函数2]
}
 
//注册事件
Emitter.prototype.bind = function(eventName, callback) {
    var listener = this._listener[eventName] || [];//this._listener[eventName]没有值则将listener定义为[](数组)。
    listener.push(callback);
    this._listener[eventName] = listener;
}
 
 //触发事件
Emitter.prototype.trigger = function(eventName) {
    var args = Array.prototype.slice.apply(arguments).slice(1);//atgs为得到除了eventName后面的参数(注册事件的参数)
    var listener = this._listener[eventName];
 
    if(!Array.isArray(listener)) return;//自定义事件名不存在
    listener.forEach(function(callback) {
        try {
            callback.apply(this, args);
        }catch(e) {
            console.error(e);
        }
    })
}

  

62.将url的查询参数解析成字典对象

function getQueryObject(url) {
    url = url == null ? window.location.href : url;
    var search = url.substring(url.lastIndexOf("?") + 1);
    var obj = {};
    var reg = /([^?&=]+)=([^?&=]*)/g;
    search.replace(reg, function (rs, $1, $2) {
        var name = decodeURIComponent($1);
        var val = decodeURIComponent($2);               
        val = String(val);
        obj[name] = val;
        return rs;
    });
    return obj;
}
 
getQueryObject("http://www.cnblogs.com/leee/p/4456840.html?name=1&dd=ddd**")
Object {name: "1", dd: "ddd**"}

  

63.position的值, relative和absolute分别是相对于谁进行定位的?
<1>、relative:相对定位,相对于本身自己在正常文档流中的位置进行定位。
<2>、absolute:生成绝对定位,相对于最近一级定位不为static的父元素进行定位。
<3>、fixed: 生成绝对定位,相对于浏览器窗口或者frame进行定位。
<4>、static:默认值,没有定位,元素出如今正常的文档流中。
<5>、sticky:生成粘性定位的元素,容器的位置根据正常文档流计算得出。

64.position:absolute和float属性的异同?
共同点:对内联元素设置float和absolute属性,可让元素脱离文档流,而且能够设置其宽高。
不一样点:float仍可占据位置,不会覆盖在另外一个BFC区域上,浮动的框能够向左或向右移动,直到它的外边缘碰到包含框或另外一个浮动框的边框为止。absolute会覆盖文档流中的其余元素。

65.CSS 选择符有哪些?哪些属性能够继承?优先级算法如何计算? CSS3新增伪类有那些?

选择符
<1>、id选择器(#myId);
<2>、类选择器(.myClassName);
<3>、标签选择器(div,p,h1);
<4>、相邻选择器(h1 + p);
<5>、子选择器(ul > li);
<6>、后代选择器(li a);
<7>、通配符选择器(*);
<8>、属性选择器(button[disabled="true"]);
<9>、伪类选择器(a:hover,li:nth-child);表示一种状态
<10>、伪元素选择器(li:before、:after,:first-letter,:first-line,:selecton);表示文档某个部分的表现

优先级
!important > 行内样式(比重1000) > id(比重100) > class/属性(比重10) > tag / 伪类(比重1);

伪类和伪元素区别
1>、伪类:a:hover,li:nth-child;
2>、伪元素:li:before、:after,:first-letter,:first-line,:selecton;

65.两个数组合并成一个数组排序返回

先依次比较两个数组,按照小的就传入新的数组。当此次比较完以后可能有一个数组的长度很长,留下一些数组,而后在新数组的末尾插入便可。

functiongetRes(arr1, arr2){
   var len1 = arr1.length,
       len2 = arr2.length,
       i = 0,
       j = 0,
       k = 0,
       res = new Array(len1+len2);
 
       while(i < len1 && j <len2){
res[k++] = arr[(arr[i] > arr[j]) ? j++ : i++];
}
While(i < len1)   res[k++]= arr1[i++];
While(j < len2)   res[k++]= arr2[j++];
Return res;
}

66.zepto和jquery区别

zepto比jquery体积小不少,移动端的兼容性不须要要考虑不少,jquery中的不少功能都没有。

width()和height()不同  解决用.css('width')

67.css3动画和jquery动画的差异

1.css3中的过渡和animation动画都是基于css实现机制的,属于css范畴以内,并无涉及到任何语言操做。效率略高与jQuery中的animate()函数,但兼容性不好。

2.jQuery中的animate()函数能够简单的理解为css样式的“逐帧动画”,是css样式不一样状态的快速切换的结果。效率略低于css3动画执行效率,可是兼容性好。‍

68.如何解决ajax没法后退的问题

HTML5里引入了新的API,即:history.pushState, history.replaceState

能够经过pushState和replaceState接口操做浏览器历史,而且改变当前页面的URL。

onpopstate监听后退

69.实现一个once函数

 

function test () {console.log('test')}

var once = function (fn) {
  var isFirst = true;
  return function () {
    if (isFirst) {
      isFirst = !isFirst;
      fn();
    }
  };
};

var b = once(test);
b(); // 'test'
b(); // nothing

 

70.分域名请求图片的缘由和好处

浏览器的并发请求数目限制是针对同一域名的,超过限制数目的请求会被阻塞

浏览器并发请求有个数限制,分域名能够同时并发请求大量图片

 

71.页面的加载顺序

html顺序加载,其中js会阻塞后续dom和资源的加载,css不会阻塞dom和资源的加载可是会阻塞js的加载。

浏览器会使用prefetch对引用的资源提早下载

1.没有 defer 或 async,浏览器会当即加载并执行指定的脚本

2.有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(下载异步,执行同步,加载完就执行)。

3.有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),可是 script.js 的执行要在全部元素解析完成以后,DOMContentLoaded 事件触发以前完成。

72.生成10个20-50之间的随机数,存在数组中,常见排序方法,数组乱序方法

var arr = [];
for(var i = 0;i<10;i++){
    var num = Math.random()*30 + 20;
    num = parseInt(num, 10);
    arr.push(num);
}

 

arr.sort(function(a,b){
    return 0.5 - Math.random();
})

73.计算机网络的分层概述

tcp/ip模型:从下往上分别是链路层,网络层,传输层,应用层

osi模型:从下往上分别是物理层,链路层,网络层,传输层,会话层,表示层,应用层。

73.jscss缓存问题

浏览器缓存的意义在于提升了执行效率,可是也随之而来带来了一些问题,致使修改了js、css,客户端不能更新

都加上了一个时间戳做为版本号

<script type=”text/javascript” src=”{JS文件链接地址}?version=XXXXXXXX”></script>

74.setTimeout,setInterval,requestAnimationFrame之间的区别

setInterval若是函数执行的时间很长的话,第二次的函数会放到队列中,等函数执行完再执行第二次,致使时间间隔发生错误。

而settimeout必定是在这个时间定时结束以后,它才会执行

requestAnimationFrame是为了作动画专用的一个方法,这种方法对于dom节点的操做会比较频繁。

75.webpack经常使用到哪些功能

设置入口  设置输出目 设置loader  extract-text-webpack-plugin将css从js代码中抽出并合并 处理图片文字等功能 解析jsx解析bable

76.介绍sass

&定义变量 css嵌套 容许在代码中使用算式 支持if判断for循环

77.websocket和ajax轮询

Websocket是HTML5中提出的新的协议,注意,这里是协议,能够实现客户端与服务器端的通讯,实现服务器的推送功能。

其优势就是,只要创建一次链接,就能够接二连三的获得服务器推送的消息,节省带宽和服务器端的压力。

ajax轮询模拟长链接就是每一个一段时间(0.5s)就向服务器发起ajax请求,查询服务器端是否有数据更新

其缺点显而易见,每次都要创建HTTP链接,即便须要传输的数据很是少,因此这样很浪费带宽

78.tansition和margin的百分比根据什么计算

transition是相对于自身,margin相对于参照物

 79.冒泡排序、快速排序、去重、查找字符串最多值

//冒泡排序
var bubbleSort = function(arr) {
   for (var i = 0; i < arr.length-1; i++) {
     for (var j = i+1; j < arr.length; j++) {
       if (arr[i]>arr[j]) {
         var temp = arr[i];
         arr[i] = arr[j];
         arr[j] = temp;
       }
     }
   }
   return arr;
};

  

//快速排序
var quickSort = function(arr) {
  if (arr.length <= 1) {
    return arr;
  }
  var len = arr.length;
  var midIndex = Math.floor(len/2);
  var mid = arr.splice(midIndex,1);
  var left = [];
  var right = [];
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] < mid) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat(mid,quickSort(right))
}

  

// 去重
 var distinct = function(arr) {
   var map = {};
   var result = [];
   for (var i = 0; i < arr.length; i++) {
      if (!map[arr[i]]) {
        map[arr[i]] = true;
        result.push(arr[i]);
      }
   }
   return result;
 }

  

//查找字符串中最多的值
var search = function(str) {
  var json = {};
  var max = 0;
  var char;
  for (var i = 0; i < str.length; i++) {
    if (!json[str[i]]) {
      json[str[i]]=1;
    } else {
      json[str[i]]++;
    }
  }
  console.log(json);
  for(var i in json){
        if(json[i]>max){
                max = json[i];
                char = i;
        }
}
  console.log(max, char);
}

 80.函数组合继承

原型继承、构造函数继承、call aplly继承

var Super = function(name){
  this.name = name;
}
Super.prototype.func1 = function() { console.log('func1'); }
var Sub = function(name,age) {
  Super.call(this, name);
  this.age = age;
}
Sub.prototype = new Super();

 81.事件绑定

var addEvent = function(e, type, handler, capture ) {
  if (e.addEventListener) {
    e.addEventListener(type, handler, capture);
  } else if (e.attachEvent) {
    e.attachEvent('on'+type, handler);
  } else {
    e['on'+type] = handler;
  }
}

82.浅克隆和深度克隆

 

//浅克隆
function extendCopy(p) {
    var c = {};
    for (var i in p) { 
      c[i] = p[i];
    }
    c.uber = p;
    return c;
 }
 
   
//深度克隆
var clone = function(v) {
  var o = v.constructor === Array ? [] : {};
  for (var i in v) {
    o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i];
  }
  return o;
}

es6的深度克隆

经过Object.getPrototypeOf函数获得obj被克隆函数的原型上的属性,而后经过Object.assign实现深度克隆。

 

const deepClone=(obj)=>{
   var proto=Object.getPrototypeOf(obj);
   return Object.assign({},Object.create(proto),obj);
}

 

83.实现一个秒针绕一点转动的效果

          animation: move 60s infinite steps(60);  
         /*设置旋转的中心点为中间底部*/  
          transform-origin: center bottom;  
        /*旋转从0度到360度*/  
        @keyframes move {  
            from {  
                transform: rotate(0deg);  
            }  
            to {  
                transform: rotate(360deg);  
            }  
        }  

84.移动端兼容问题

IOS移动端click事件300ms的延迟响应

一些状况下对非可点击元素如(label,span)监听click事件,ios下不会触发,css增长cursor:pointer就搞定了

85.bootstrap的栅格系统如何实现的

 

box-sizing: border-box;
container row column设置百分比

 

85.js基本类型及判断方法

null, undefined,bool,number,string,object,symbol(es6 独一无二)

1.typeof()出来的没有null 对象,数组和null typeof(x) = "object"

2.instanceof() 对象的原型是否在对象的原型链上

以下:判断Person的原型是否在p的原型链上

function Person(){};
var p =new Person();
console.log(p instanceof Person);//true

3.Object.prototype.toString.call()

每种对象对toString都进行了改写,只有Object.prototype.toString.call(obj)能够进行类型判断

var a=new Number(12);
var toString=Object.prototype.toString;
console.log(toString.call(a));//'[object Number]''
console.log(a.toString());//'12'

  

86 JavaScript为何是单线程?eventloop

JavaScript的单线程,与它的用途有关。做为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操做DOM。这决定了它只能是单线程,不然会带来很复杂的同步问题。

好比,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另外一个线程删除了这个节点,这时浏览器应该以哪一个线程为准?

异步执行:

(1)全部同步任务都在主线程上执行,造成一个执行栈(execution context stack)。

(2)主线程以外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的全部同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,因而结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。

主线程从”任务队列”中读取事件,这个过程是循环不断的,因此整个的这种运行机制又称为Event Loop(事件循环)。

node里的process.nextTick指定的回调函数是在本次”事件循环”触发,而setImmediate指定的是在下次”事件循环”触发,因此很显然,前者老是比后者发生得早,并且执行效率也高。

 

87 http http2 https

http(超文本传输协议)是一种经常使用于应用层的协议,它是基于文本传输内容。

https能够称为http安全版,主要是http下增长了SSL(安全套接层)或者TSL(传输层安全),在SSL或TSL在传输层对数据进行了加密处理。

http/2(超文本传输协议第二版),他对http进行了一些升级改造

  • 新的二进制格式
  • 多路复用
  • header压缩
  • 支持server push

 87  枚举

 

 

88  meta属性

1.name 网页描述

<meta name="参数" content="描述内容">

a.keword

b.description

c.viewport

2.http-equiv http相关描述

<meta http-equiv="参数" content="描述内容">

a.content-type

b.cache-control

c.expires

89 react 相关

react router:

实现URL与UI界面的同步。其中在react-router中,URL对应Location对象,而UI是由react components来决定的,这样就转变成location与components之间的同步问题。

react事件:

React并非将click事件绑在该div的真实DOM上,而是在document处监听全部支持的事件,当事件发生并冒泡至document处时,React将事件内容封装并交由真正的处理函数运行。

90 js css加载顺序

js全阻塞,css半阻塞

  1. JS 会阻塞后续 DOM 解析以及其它资源(如 CSS,JS 或图片资源)的加载。
  2. CSS 不会阻塞后续 DOM 结构的解析,不会阻塞其它资源(如图片)的加载,可是会阻塞 JS 文件的加载。
  3. 现代浏览器很聪明,会进行 prefetch 优化,浏览器在得到 html 文档以后会对页面上引用的资源进行提早下载。

js为何阻塞?

  1. JS 运行在浏览器中,是单线程的,每一个 window 一个 JS 线程,因此固然会阻塞后续 DOM 树的解析咯。
  2. JS 有可能会修改 DOM 结构,给 DOM 添加样式等等,因此这就意味着在当前 JS 加载执行完成前,后续资源的加载多是没有意义的

css为何阻塞js?

JS 代码在执行前,浏览器必须保证在 JS 以前的全部 CSS 样式都解析完成,否则不就乱套了,前面的 CSS 样式可能会覆盖 JS 文件中定义的元素样式,这是 CSS 阻塞后续 JS 执行的根本缘由。

defer,async?

JS 会阻塞后续 DOM 解析以及其它资源(如 CSS,JS 或图片资源)的加载,这是在没有考虑到 defer, async 的状况下。

  1. 因为现代浏览器都存在 prefetch,因此 defer, async 可能并无太多的用途,能够做为了解扩展知识,仅仅将脚本文件放到 body 底部就能够起到很不错的优化效果。
  2. defer 和 async 都是异步加载脚本文件,defer异步加载,最后执行。
  3. 慎用 async,由于它彻底不考虑依赖关系,只要下载完后就加载,不考虑此时页面样式前后的加载顺序,不过它对于那些能够不依赖任何脚本或不被任何脚本依赖的脚原本说倒是很是合适的,最典型的例子:Google Analytics。
  4. 耗时较长的脚本代码可使用 defer 来推迟执行。

 91. 三次握手四次挥手

第一次握手:客户端请求与服务端创建链接。第二次:服务端返回确认信息。第三次:客户端收到。

客户:喂?你在吗?我想跟你聊会儿天儿!(发送SYN请求同步报文)

服务:好的,我听着呢(发送SYN请求同步报文,意思是说,咱俩同步着呢),你说吧!(发送ACK确认报文,便可以说了)

客户:好的!(发送ACK确认报文,开始吐槽XXXX)

 

第一次挥手:客户端传完了,想要断开链接。第二次:服务端收到,半关闭状态。第三次:服务端没信息发了,发送结束报文。第四次:客户端确认,关闭。

而后客户有事儿要挂电话了,又有了下面一段对话,即四次挥手:

客户:我有事儿要挂电话了!(发送Fin结束报文,1次挥手)

服务:好吧(发送ACK确认报文,2次挥手),对了,还有个事儿要跟你说!

......

服务:好了,就这些了,挂了吧!(发送Fin结束报文,3次挥手)

客户:行,挂了吧!(发送ACK确认报文,4次挥手)

服务挂断电话.....

2MSL后......

客户:喂,你还在吗?

啪!(这才断开链接)

 为何四次挥手?

当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。

但未必被动方全部的数据都完整的发送给了主动方,因此被动方不会立刻关闭SOCKET,它可能还须要发送一些数据给主动方后,

相关文章
相关标签/搜索