就题目谈答案不是目的,了解更深层次的东西才是根本。不仅要知道,还要答的漂亮。
1.描述盒子模型。
2.两个并列的display:inline-block的子元素之间的为什么有空隙。
- 答案很简单,这些空隙就是空白符。
- 怎么去掉这个空白符呢,就是把父元素的样式设为font-size:0;别忘了子元素自己也要设置字号,不然就会继承父元素的字号变成0了。
3.举几个行内元素的例子。
- b, big, i, small, tt
- abbr, acronym, cite, code, dfn, em, kbd, strong, samp, var
- a, bdo, br, img, map, object, q, script, span, sub, sup
- button, input, label, select, textarea
4.cookie、localStorage、sessionStorage的区别。
- Http cookie,通常叫做cookie,用于在客户端存储简单的会话信息,长度不超过4095B,由
名称、值、域、路径、失效时间、安全标志组成。需要注意的是,除了名值对是在Request Headers中一起发送给服务器的,其他的只有Response Headers才会有,是服务器给浏览器的指示。 - sessionStorage对象用于存储特定于某个会话的数据,浏览器关闭数据就会消失,他可以跨越页面刷新而存在。可以用getItem(), setItem(), removeItem() 等去操作数据。
- localStorage对象用于储存持久的大量的客户端数据,只有同域名同协议通端口的页面才可以访问。
5.如何实现浏览器的跨tab通信,就是两个Tab页面,在第一个里面比如点击了一下,然后另一个Tab页面会有相应的反应。
- 这个问题就是上面的客户端存储问题涉及到的一个用法,对sessionStorage和localStorage的操作会触发
storage事件,通过监听这个事件就可以知道其他的同源的页面对sessionStorage或者localStorage的操作。
6.css实现三角形,不是svg那些。
7.实现元素的垂直水平居中。
8.position定位的四种属性,分别表示什么。
9.如何解决移动端适配的问题。
10.js的基本数据类型有哪些,ES6新增了什么?
- 基本数据类型:Undefined,Null,Boolean,Number,String,Symbol(ES6新增,一种数据类型,它的实例是唯一且不可改变的);
- 引用数据类型:Object;
- 基本数据类型和引用数据类型的区别:在将一个值赋给变量时,解析器会去确定这个值是基本类型值还是引用类型值。基本数据类型是按值访问,可以操作保存在变量中的实际的值;而引用数据类型是保存在内存中的对象,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,在操作对象时,实际上是在操作对象的引用而不是实际的对象,为此,引用类型的值是按引用访问的。引用是一个指向对象实际位置的指针。
11.跨域请求的方法,重点问了jsonp的实现原理。
- 参考阮一峰老师的这两篇吧
- 浏览器同源政策及其规避方法
- 跨域资源共享 CORS 详解
12.如何按需加载js,就是满足某个条件就加载这段script,不需要就不加载。
举个栗子吧:
<body>
<div onclick='loadjs()'>click me!</div>
<div onclick='loadjs2()'>click me!</div>
</body>
<script>
// 期望的状态。
function loadjs() {
var script = document.createElement('script');
script.src = '//cdn.bootcss.com/jquery/1.12.4/jquery.min.js';
document.getElementsByTagName('html')[0].append(script);
}
// 对比。
function loadjs2() {
document.write('<script src="//cdn.bootcss.com/jquery/1.12.4/jquery.min.js" type="text/javascript" charset="utf-8" async defer><\/script>');
}
</script>
13.bind、call、apply的区别及使用场景。
14.事件传播会经过哪些阶段。然后接着问,事件捕获的原理是什么,为什么绑定在父元素的事件,在子元素触发。addEventListener第二个参数的默认值是什么。
- 三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。
- 当时说的是子元素从父元素那里继承了这个事件。
- addEventListener的第二个参数是默认值是false,true表示在事件捕获阶段调用事件处理程序,false表示在事件冒泡阶段调用事件处理程序。
15.描述什么是原型链,prototype和__proto__的区别是什么。
- js中每个对象都有一个私有属性(称之为[[Prototype]]),它指向创建它的函数对象的原型对象(prototype)。
- 该 prototype 对象又具有一个自己的 prototype, 层层向上直到一个对象的原型为null。根据定义,null没有原型,并作为这个原型链中的最后一个环。其实原型链的顶端就是Object.prototype.proto,也即为null。
- [[Prototype]]就是主流浏览器所说的__proto__。
16.let、var的区别,一条考烂了的题。
for(var i = 0; i < 10; i ++) {
setTimeout(function(){
console.log(i);
},0);
}
会输出什么,如何让他输出0-9呢,如果回答了把var换成let,紧接着会问,为什么换成let就能输出0-9,原理是什么。
- 会输出10。这里会输出10的原因是,setTimeout是异步任务执行,会被加入到任务队列中,等执行栈中的同步任务都执行完毕,任务队列中的异步任务才会被调用,这是影响因素之一;影响因素二就是var没有块级作用域,所有的i都指向同一个引用,而i的累加会先于异步任务执行,再次之前i已经变成了10;
- 这个使用let,每一次循环会生成独立的执行环境,每一个i指向不同的引用,所以最终打印出来就是不一样的。
17.数组去重。
// Set
function unique(arr) {
return [...new Set(array)];
}
18.编写一个会被两次调用的函数,如add(2)(3),结果是5。
function add(a) {
return function(b) {
return a + b;
}
}
19.实现斐波那契数列。
// 递归实现,看上去比较优雅。
function Fib(n) {
return n < 2 ? n : (Fib(n - 1) + Fib(n - 2));
}
// for循环非递归实现
function fib(n) {
if (n < 2) {
return 1;
}
var a = 1, b = 1;
for (var i = 2; i < n - 1; i++) {
b = a + b;
a = b - a;
}
return a + b;
}
20.实现一个求算术平方根的函数。
21.不使用循环实现数组元素的累加(递归和非递归两种实现)。
22.ES6中的.repeat()方法的polyfill。
23.返回数组中包含aa的元素['aaa','abc','bbc','dadadeq',['aaa','bbb','ccc',['aaa','bac','ccc','ewee',['aaa','asasa']]],使得返回值为['aaa','aaa','aaa','aaa'],差不多就这个意思,只不过里面具体的元素不是这些。
24.vue的不同生命周期的函数钩子?
// 源码直接给出
export const LIFECYCLE_HOOKS = [
'beforeCreate',
'created',
'beforeMount',
'mounted',
'beforeUpdate',
'updated',
'beforeDestroy',
'destroyed',
'activated',
'deactivated',
'errorCaptured'
]
25.浏览器性能优化。
26.控制缓存问题。
- 谷歌的这篇大概够全面吧。
- 当时还说到jQuery的$.ajax的cache配置项设置也可以控制这次的请求内容要不要缓存。
27.如何避免用户看到未渲染完成的页面。
28.如何解决移动端1px被渲染为2px的问题。
-
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /> 和 transform: scale(0.5) 来处理 -
<meta name="viewport" content="width=device-width,initial-scale=0.5,minimum-scale=0.5,maximum-scale=0.5,user-scalable=no" /> - 上面两种是针对*2的屏,如果有*3的屏,0.5就会是0.3333333
-
//更加通用的方法 var dpr = window.devicePixelRatio; meta.setAttribute('content', 'initial-scale=' + 1/dpr + ',maximum-scale=' + 1/dpr + ', minimum-scale=' + 1/dpr + ',user-scalable=no');
29.知道SEO吗,用了vue或者react之后怎么做SEO,问vue还是react视简历而定,你写的什么你会用什么,他就问什么。
- 服务器端渲染的页面做SEO的过程,在<meta><title>标签里面设置要设置合适的关键词,关键词在整个页面里面出现的几率为5%-8%比较合适。
- 在根目录建一个sitemap.xml
- 和其他网站交换友链
- 如果使用了vue,尤大大也说了,用了vue也不一定要写成SPA,如果不是SPA而是而是服务器端渲染的,那么SEO还是上面的,如果既想要SPA的强交互性又想要SEO,可以使用SSR。
30.如何评价各种前端技术栈,好大的题目,怎么回答,见仁见智了。
- 这个题我感觉按照31的思路去说也是可以的。
31.vue、react、jquery等的优劣对比。
- 这种题目单纯的对比优劣可以参考的帖子很多。
- 但是选择什么最终要服务于要实现什么,选择最适合自己网站的技术栈才是根本,不妨从这个角度去谈优劣对比更有说服力,毕竟所谓优劣更多都是相对而言的。
- 那就先从单页面应用和多页应用说起吧,参考
- 简而言之,如果追求强交互性选择SPA,如果对SEO要求比较高、交互性需求比较一般可以使用MPA,如果不管怎么样既要交互性又要SEO,vue给出的解决方案就SSR。
- 然后从几个角度去谈具体的优劣:DOM操作、虚拟DOM、响应式、组件化、性能、学习成本等等方面分别谈一谈各有优劣。
- 然后说到SPA说到性能,可能会谈的首屏加载太慢的问题,这算是自己给自己挖坑吗,除了基本的CDN加速,压缩静态资源,按需引入组件,要么就是 服务器端渲染。
- 参考:Vue SPA 首屏加载优化实践、vue、react、angular三大框架对比 && 与jQuery的对比
32.看你项目里面jq用的挺多的,读过源码吗?
我:没有。
好了,今天的面试结束了,回去吧。
后来又是一场问到这个问题,我就回答了“稍微看了一点”,然后就问,那你对jq的架构设计或者底层原理知道什么,说说看。
emmm....,问的倒是一点都不客气。
33.这是一个比较personal的问题,一个聊天室,我用了ajax轮询实现的消息的获取,当时是局限于后端不支持websocket,所以没能使用这个更好的技术实现。于是此处引出两个问题,1)ajax轮询如果某一次请求的返回结果比较慢,甚至比后一次的返回结果还晚,如何避免因为这种延时造成消息显示的混乱;2)了解过websocket吗,如果用它要怎么去实现?
- websokcet的使用,我没有用过,先贴一个websocket教程吧
34.一般你是怎么写babel配置文件的让ES6的代码能够兼容各种老的浏览器。
35.this作用域。
36.闭包肯定少不了了。
37.如何解决点击穿透问题。
- touchstart 300ms之后会触发click时间,在300ms之内,如果上面的一层已经消失,click就会作用到下面一层,如果下面一层恰好可以点击,就会发生点击穿透。
- 解决方法,只用touch事件,如果全局没有click事件,就不会触发后续的click事件了。
- 只用click事件会导致任何交互都有300ms的延时,体验不太好。
- touch事件350ms之后再隐藏弹层,那么click就不会触发到下面的元素了。
- 这篇提供的其他方法作为参考吧
38.ios的scroll问题怎么解决。
39.移动端适配如果使用rem的话,rem的根节点的font-size的值通常怎么计算。
- rem = document.documentElement.clientWidth * dpr / 10
- 除以10是为了方便计算,其实可以是任何值。
- 个人觉得这个只是一种约定俗成的办法,也不是非这样不可吧。
- 参考
40.列举一些用到的css3的属性,着重问了animation的使用方法。
41.ES6的箭头函数与ES5的function除了this的不同点,还有什么不同点。
- 箭头函数不可以当作构造函数。
- 箭头函数不存在arguments对象。
- 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
42.Vue的响应式是通过什么实现的。
- Object.defineProperty
43.一般平时通过什么途径获取前端的知识或者资讯。
44.列举一个自己觉得比较满意的项目,并说明做了哪些功能上的优化。
45.npm版本号一般有哪些写法
- emmm.....还是看senmver吧
46.npm的script里面一般写些什么。
47.webpack的hash的用法
48.git如果某一次提交中有一个文件提交错了,该如何操作。
- git reset <文件名>
49.SPA首屏比较慢,可以如何优化。
- 参照31
50.const定义的数组或者对象可以改变吗
- 数组和对象可以改
- const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。
51.Objects和Maps的区别
- 一个对象通常都有自己的原型,所以一个对象总有一个"prototype"键。不过,从 ES5 开始可以使用 map = Object.create(null) 来创建一个没有原型的对象。
- 一个对象的键只能是字符串或者 Symbols,但一个 Map的键可以是任意值。
- 可以通过size属性很容易地得到一个Map的键值对个数,而对象的键值对个数只能手动确认。
52.解构的原理
53.从promise谈谈event loop。
54.谈谈浏览器兼容用过哪些。
55.做移动端开发和pc端开发有什么区别。
这个肯定很多区别啊,但是突然这么问,很多一时间就想不到了,参考知乎这个答案有意识的准备一下吧,否则这种开放性的题型,哎....心有千言,却什么都说不出来,仿佛一个智障。
经此一役,我开启了跪读源码的慢慢长征路......