2018前端面试题

259 阅读10分钟

一段文本的line-height设置为父容器的高度为什么可以实现文本的居中?

由图片可以清晰地看出,行高是baseline之前的距离,而行距是bottom-top之间的距离,行高-行距=1+3+4=字体大小。而行距是一半字体分布在下边,一半分布在字体上边,且均匀分布,所以就达到了垂直居中的效果。 比如:文字是18px,height=100px,line-height=100px,就会出现文字在中间,上间距=下间距=41px 若高度和行高都变成200px时,文字位置不变,上下间距变大为91px

如何判断一个变量是Array类型

Array.isArray(arr)

Object.prototype.toString.call(arr) === "[object Array]";

function isArray(value){ 
   if (typeof Array.isArray === "function") {
       return Array.isArray(value);
   }else{
       return Object.prototype.toString.call(value) === "[object Array]";
   }
}
isArray([1,2,5])  //true

你用过哪些前端性能优化的方法?

  1. 减少http请求:
    • 因为一个完整的请求要经过DNS寻址,与服务器建立连接,发送数据,等待服务器响应,接收数据这样一个消耗时间成本和资源成本的复杂的过程。
    • 方法:合并多个CSS文件和js文件,利用CSS Sprites整合图像,设置缓存,图片lazy-load
  2. 将外部脚本置底:
    • 因为加载外部脚本时会造成页面堵塞,脚本加载完成之前图片样式等会处于阻塞状态
  3. 样式放在head里,而且用link不是用@import
    • 因为link是异步加载的,和页面是并发加载,不会堵塞页面的加载
    • 如果样式放在body中,则浏览器有可能还未下载和解析到 CSS就已经开始渲染页面了,这就导致页面由无 CSS状态跳转到 CSS状态,用户体验比较糟糕。
  4. 减少cookie传输
    • cookie包含在每次请求和响应中,太大的cookie会严重影响数据传输
  5. 减少DOM操作
    • 频繁的操作DOM元素,会影响页面的Reflow和Repaint,影响页面的性能

* 性能优化的方式还有很多,可以单写一篇文章 *

Vue和React数据驱动实现方式的区别

React当真没有学过

Vue数据驱动: 官网的相关介绍虚拟DOM diff原理

  • vue会把data属性转为getter/setter,在内部让vue追踪依赖。每个组件实例都有相应的 watcher实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。
  • 虚拟DOM就是当数据发生变化时,vue会产生虚拟的dom元素,与已有的dom元素做对比,可能新增、删除、修改,修改的时候采用“就地复用”策略。官网有相关介绍cn.vuejs.org/v2/guide/li…

(目前不是很理解,还不能做总结)

js哪些操作会造成内存泄漏及避免?

对于持续运行的服务进程(daemon),必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。 不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。

  • 全局变量引起的内存泄漏
  • 闭包引起的内存泄漏
    • 闭包中的变量被引用,不会被垃圾回收
    • 在退出函数之前,将不使用的局部变量全部删除
  • dom清空或删除时,事件未清除导致的内存泄漏
  • 被遗忘的定时器,回调函数不需要时,定时器及时回收

一个页面从输入URL到页面加载显示完成,这个过程中都发生了什么?

详细版:

  • 浏览器会开启一个线程来处理这个请求,对 URL 分析判断如果是 http 协议就按照 Web 方式来处理;
  • 调用浏览器内核中的对应方法,比如 WebView 中的 loadUrl 方法;
  • 通过DNS解析获取网址的IP地址,设置 UA 等信息发出第二个GET请求;
  • 进行HTTP协议会话,客户端发送报头(请求报头);
  • 进入到web服务器上的 Web Server,如 Apache、Tomcat、Node.JS 等服务器;
  • 进入部署好的后端应用,如 PHP、Java、JavaScript、Python 等,找到对应的请求处理;
  • 处理结束回馈报头,此处如果浏览器访问过,缓存上有对应资源,会与服务器最后修改时间对比,一致则返回304;
  • 浏览器开始下载html文档(响应报头,状态码200),同时使用缓存;
  • 文档树建立,根据标记请求所需指定MIME类型的文件(比如css、js),同时设置了cookie;
  • 页面开始渲染DOM,JS根据DOM API操作DOM,执行事件绑定等,页面显示完成。

简洁版:

  • 浏览器会先查找缓存,若缓存中有且没有过期的情况下会直接显示页面内容
  • 解析域名获取响应的IP地址
  • 向服务器发起连接,四次握手
  • 浏览器向服务器发送http请求,然后服务器返回数据
  • 浏览器收到响应后,读取页面进行渲染
  • 生成Dom树、解析css样式、js交互

你都用过ES6什么语法?

  • 变量声明
  • 模板字符串
  • 默认参数
function test(msg, type = 'world') {
  console.log(msg, type)
}
test('hello')  // hello world
  • 箭头函数
  • 模块的引入和导出
  • 解构赋值
  • 扩展运算符:用于取出参数对象的所有可遍历属性,拷贝到当前对象中
const a = [1, 2];
const b = [...a, 3];
console.log(b)  //[1, 2, 3]

// 代替 apply。
function foo(x, y, z) {}
const args = [1,2,3]

// 下面两句效果相同
foo.apply(null, args)
foo(...args)

// 组装对象
const a = { x : 1, y : 2 }
const b = { ...a, z : 3 }
  • promise

小程序的登录流程

每个用户都有登录码,先用微信的login()获取code,再用request请求获取openid(用户标识符)和session_key(用户登录状态),这两个值不需要返回客户端,但是会返回一个标志userId,下次再进入的时候就会先从缓存中获取,获取不到就会重新登录。

angular1和angular2的区别

  • Angular2不是从Angular1升级过来的,Angular2是重写的,所以他们之间的差别比较大
  • Angular2使用了javascript的超集‘Typescript’
  • Angular 1的核心概念是$scope,但是angular2中没有$scope
  • Angular 1 中的控制器在angular2中不再使用
  • Angular 2中, 指令的结构、用法作了一些调整,比如1中的ng-repeat被*ngFor替代

vue中当A和B的权限不同,可以打开的页面也不同时需要怎么实现?(即A只能打开A.html,B只能打开B.html,当A打开B.html时怎么办)

可以给A一个路由列表,B一个路由列表,当A打开B.html时,会显示404

ajax请求中成功回调函数中的this指针指向的是谁?

指向的是success回调

网站的登录注册流程

  • 客户端通过用户名和密码登录账号
  • 服务器对客户端身份进行验证
  • 服务器对用户生成token,返回客户端
  • 客户端将token保存到本地,通常是cookie中
  • 客户端发起请求,通常带着token
  • 服务端收到请求后,首先验证Token,之后返回数据。服务端不需要保存Token,只需要对Token中携带的信息进行验证即可。

vuex中的数据刷新的话还有吗

没有

vuex的存储的数据只是在页面的中,相当于我们定义的全局变量,刷新之后,里边的数据就会恢复到初始化状态。

将state对象存入到sessionStorage/localStorage中。页面打开之后,判断sessionStorage/localStorage中是否存在state对象,如果存在,则说明页面是被刷新过的,将sessionStorage/localStorage中存的数据取出来给vuex中的state赋值。如果不存在,说明是第一次打开,则取vuex中定义的state初始值。

http状态码有那些?分别代表是什么意思?

  • 1**(信息类):表示接收到请求并且继续处理
    • 100——客户必须继续发出请求
    • 101——客户要求服务器根据请求转换HTTP协议版本
  • 2**(响应成功):表示动作被成功接收、理解和接受
  • 3**(重定向类):为了完成指定的动作,必须接受进一步处理
    • 301永久重定向
    • 302暂时重定向
    • 304未修改
  • 4**(客户端错误类):请求包含错误语法或不能正确执行
  • 5**(服务端错误类):服务器不能正确执行一个正确的请求

vuex单向数据流

单向数据流就是只能从一个方向来修改状态。

vuex完整的流程就是:组件中触发 Action,Action 提交 Mutations,Mutations 修改 State。 组件根据 State 或 Getters 来渲染页面。

注意mutations里面所有的操作都是同步的,也就是mutations触发之后,立即会更新state,不存在异步。但是actions里面没有这个限制,所以把异步的操作放到actions中,当actions中的异步触发之后再分发mutations

json和jsonp的区别

jsonp是一种跨域请求方式。主要原理是利用了script标签可以跨域请求的特点,由其src属性发送请求到服务器,服务器返回js代码,网页端接受响应,然后就直接执行了,这和通过script标签引用外部文件的原理是一样的。

json是一种数据交换的格式。

promise的三种状态

  • pending(等待态):可以迁移至完成态或拒绝态
  • fulfiled(成功态):不能迁移至其他任何状态、必须拥有一个不可变的终值
  • rejected(失败态):不能迁移至其他任何状态、必须拥有一个不可变的据因

浅拷贝与深拷贝

  • 浅拷贝:将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用
  • 深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”
  • 区别: 做浅拷贝,由于只是对原对象的拷贝,所以当修改新的数据的时候旧数据也会发生改变。深拷贝,拷贝的是值,修改新数据对之前的数据没有影响
//浅拷贝
Object.assign() 
function clone(obj1, obj2) {
    for (let key in obj2) {
        obj1[key] = obj2[key]
    }
}
//深拷贝
function clone(obj1, obj2) {
    for (let key in obj2) {
        if (typeof obj2[key] == 'object') {
            obj1[key] = {};
            clone(obj1[key], obj2[key]);
        } else {
            obj1[key] == obj2[key]
        }
    }
}

DOM0级和DOM2级事件处理

DOM0级事件

  • 就是直接绑定事件
  • 在标签内写事件 onclick="alert('这是通过DOM0级添加的事件!');"
  • 直接写在dom元素上
document.getElementById("myButton").onclick = function () {
    alert('这是通过DOM0级添加的事件!');
}
  • 移除事件element.事件=null;
  • 0级DOM事件模型处理没有capturing阶段
  • 后边绑定的会覆盖前边绑定的事件

DOM 2级事件

  • 事件绑定addEventListener(event, function, useCapture);
  • 事件移除removeEventListener(event, function, useCapture)
  • 浏览器兼容处理
var addEvent = document.addEventListenter ?
    function(elem, type, listenter, useCapture) {
        elem.addEventListenter(type, listenter, useCapture);
    } : 
    function(elem, type, listenter, useCapture) {
        elem.attachEvent('on' + type, listenter);
    }

Bootstrap3.0的栅格布局系统实现原理

参考链接 www.cnblogs.com/chengdabeli…

<div class="container">
    <div class="row">
      <div class="col-xs-12"></div>
    </div>
</div>

Container的正padding值造成了15px的留空,row用负margin值反的延伸回去, col的padding值与container的padding重叠了。

永远不要在container外用row, row在container外面使用是无效的;永远不要在row外使用col,在row外使用col是无效的

浏览器的标准模式和怪异模式

  • 标准模式: 浏览器按W3C标准解析代码
  • 怪异模式: 浏览器按照自己的标准