前端面试分析

1.什么情况下会碰到跨域问题?有哪些解决方法?
跨域问题是这是浏览器为了安全实施的同源策略导致的,同源策略限制了来自不同源的document、脚本,同源的意思就是两个URL的域名、协议、端口要完全相同。
script标签jsonp跨域、nginx反向代理、node.js中间件代理跨域、后端在头部信息设置安全域名、后端在服务器上设置cors。
2.如何判断一个变量是对象还是数组?
判断数组和对象分别都有好几种方法,其中用prototype.toString.call()兼容性最好。
 function isObjArr(value){ if (Object.prototype.toString.call(value) === "[object Array]") { console.log('value是数组'); }else if(Object.prototype.toString.call(value)==='[object Object]'){//这个方法兼容性好一点 console.log('value是对象'); }else{ console.log('value不是数组也不是对象') } } 
ps:千万不能使用typeof来判断对象和数组,因为这两种类型都会返回"object"。
3.定时器的执行顺序或机制。
因为js是单线程的,浏览器遇到setTimeout或者setInterval会执行完当前的代码块,在此之前会把定时器推入浏览器的待执行事件队列里面,等到浏览器执行完当前代码之后会看一下事件队列里面有没有任务,有的话才执行定时器的代码。
4.伪类和伪元素的特性和区别
伪类存在的意义是为了通过选择器找到那些不存在与DOM树中的信息以及不能被常规CSS选择器获取到的信息。伪类由一个冒号:开头,冒号后面是伪类的名称和包含在圆括号中的可选参数。
:link; :visited;:hover;:active;:focus; :not; :first-child; : last-child; first-of-type; :last-of-type;:nth-child; :nth-last-child;:nth-of-type;:nth-last-type; :only-of-type; :target;:checked;
伪元素在DOM树中创建了一些抽象元素,这些抽象元素是不存在于文档语言里的(可以理解为html源码)。比如:documen接口不提供访问元素内容的第一个字或者第一行的机制,而伪元素可以使开发者可以提取到这些信息。并且,一些伪元素可以使开发者获取到不存在于源文档中的内容(比如常见的::before,::after)。
伪元素的由两个冒号::开头,然后是伪元素的名称。
 ::before/:before; ::after/:after; ::first-letter/:first-letter; ::selection; ::placeholder;
伪类与伪元素的特性及其区别:
伪类本质上是为了弥补常规CSS选择器的不足,以便获取到更多信息;
伪元素本质上是创建了一个有内容的虚拟容器;
CSS3中伪类和伪元素的语法不同;
可以同时使用多个伪类,而只能同时使用一个伪元素;

前端面试分析  前端面试分析
5.标准盒子模型与IE怪异盒子模型
box-sizing: content-box|border-box|inherit;
content-box 在宽度和高度之外绘制元素的内边距和边框。
border-box 从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。
inherit    规定应从父元素继承 box-sizing 属性的值。
6.JS中的异步操作有哪些
1.利用setTimout实现异步; 事件绑定都是异步操作;  AJAX;回调函数可以理解为异步(不是严谨的异步操作)   
2.动态创建script标签 
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = 'xx.js';
head.appendChild('script');
3.利用script提供的defer/async
<script src="xx.js" defer></script>defer:当页面加载完毕以后才去执行这段代码。
<script src="xx.js" async></script>async:异步执行script代码
7.如何对一个数组去重?
1.Set结构去重。
这是ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值,有重复的值会自动去重。Set内部使用===来判断是否相等。
2、遍历,将值添加到新数组,用indexOf()判断值是否存在,已存在就不添加,达到去重效果。
8.盒子垂直水平居中
方法1:父:position: relative;子position: absolute;top: 0;left: 0;bottom: 0;right: 0;(不推荐)
方法2:  父:position: relative;子:position: absolute;top:50%;left: 50%;transform: translate(-50%,-50%);
 方法3: 父:display: table-cell;vertical-align: middle;text-align: center;子:display: inline-block;
方法4:父:display:flex;justify-content:center;align-items:center;
方法5:父:display:flex;justify-content:center; 子:align-self:center;
方法6:父:display: box;display: -webkit-box;-webkit-box-align: center;-webkit-box-pack: center;
方法:让图片在一个盒子里垂直居中(在img后边添加一个span元素):
img{ vertical-align: middle;}
span{ vertical-align: middle;  display: inline-block;    width: 0px;     height: 100%; }
9.翻转一个字符串
(1)使用字符串函数
//使用数组翻转函数
function reverseString(str){
    var array = str.split('');  //转换成字符串数组
    array = array.reverse();
    str = array.join('');
    return str;
}
//简写
function reverseString(str){
    return str.split('').reverse().join('');
}
(2)使用for循环
function reverseString(str){
    var newStr = "";
    for(var i=str.length-1; i>=0; i--){
        newStr += str[i];
    }
    return newStr;
}
(3)使用递归
function reverseString(str){
    if(str===""){
        return "";
    }else{
        return reverseString(str.substr(1)) + str.charAt(0);
    }
}
//简写
function reverseString(str) {  
 return (str === "") ? "" : reverseString(str.substr(1)) + str.charAt(0);  
}   
10.重置(resetting)CSS 和 标准化(normalizing)CSS 的区别是什么?你会选择哪种方式,为什么?
重置(Resetting): 重置意味着除去所有的浏览器默认样式。你将必须重新定义各种元素的样式。
标准化(Normalizing): 标准化没有去掉所有的默认样式,而是保留了有用的一部分,同时还纠正了一些常见错误。
当需要实现非常个性化的网页设计时,我会选择重置的方式,因为我要写很多自定义的样式以满足设计需求,这时候就不再需要标准化的默认样式了。
11.请阐述块格式化上下文(Block Formatting Context)及其工作原理。
块格式上下文(BFC)是 Web 页面的可视化 CSS 渲染的部分,是块级盒布局发生的区域,也是浮动元素与其他元素交互的区域。
一个 HTML 盒(Box)满足以下任意一条,会创建块格式化上下文:
float的值不是none.
position的值不是static或relative.
display的值是table-cell、table-caption、inline-block、flex、或inline-flex。
overflow的值不是visible。
12.有哪些清除浮动的技术,都适用哪些情况?
空div方法:<div style="clear:both;"></div>。
Clearfix 方法:利用伪元素选择器::after清除浮动。
.clearfix::after { content: ''; display: block; clear: both; }
overflow: auto或overflow: hidden方法:上文已经提到。
在大型项目中,我会使用 Clearfix 方法,在需要的地方使用.clearfix。设置overflow: hidden的方法可能使其子元素显示不完整,当子元素的高度大于父元素时。
13.如何为功能受限的浏览器提供页面? 使用什么样的技术和流程?
优雅的降级:为现代浏览器构建应用,同时确保它在旧版浏览器中正常运行。
渐进式增强:构建基于用户体验的应用,但在浏览器支持时添加新增功能。
利用 caniuse.com 检查特性支持。
使用 autoprefixer 自动生成 CSS 属性前缀。
使用 Modernizr进行特性检测。
14.使用 CSS 预处理的优缺点分别是什么?
优点:
提高 CSS 可维护性。
易于编写嵌套选择器。
引入变量,增添主题功能。可以在不同的项目*享主题文件。
通过混合(Mixins)生成重复的 CSS。
将代码分割成多个文件。不进行预处理的 CSS,虽然也可以分割成多个文件,但需要建立多个 HTTP 请求加载这些文件。
缺点:
需要预处理工具。
重新编译的时间可能会很慢。
15.响应式设计与自适应设计有何不同?
响应式设计和自适应设计都以提高不同设备间的用户体验为目标,根据视窗大小、分辨率、使用环境和控制方式等参数进行优化调整。
响应式设计的适应性原则:网站应该凭借一份代码,在各种设备上都有良好的显示和使用效果。响应式网站通过使用媒体查询,自适应栅格和响应式图片,基于多种因素进行变化,创造出优良的用户体验。就像一个球通过膨胀和收缩,来适应不同大小的篮圈。
自适应设计更像是渐进式增强的现代解释。与响应式设计单一地去适配不同,自适应设计通过检测设备和其他特征,从早已定义好的一系列视窗大小和其他特性中,选出最恰当的功能和布局。与使用一个球去穿过各种的篮筐不同,自适应设计允许使用多个球,然后根据不同的篮筐大小,去选择最合适的一个。
16.什么情况下,用translate()而不用绝对定位?什么时候,情况相反。
translate()是transform的一个值。改变transform或opacity不会触发浏览器重新布局(reflow)或重绘(repaint),只会触发复合(compositions)。而改变绝对定位会触发重新布局,进而触发重绘和复合。transform使浏览器为元素创建一个 GPU 图层,但改变绝对定位会使用到 CPU。 因此translate()更高效,可以缩短平滑动画的绘制时间。
当使用translate()时,元素仍然占据其原始空间(有点像position:relative),这与改变绝对定位不同。
17.什么是闭包(closure),为什么使用闭包?
闭包是函数和声明该函数的词法环境的组合。词法作用域中使用的域,是变量在代码中声明的位置所决定的。闭包是即使被外部函数返回,依然可以访问到外部(封闭)函数作用域的函数。
为什么使用闭包?
利用闭包实现数据私有化或模拟私有方法。这个方式也称为模块模式(module pattern)。
部分参数函数(partial applications)柯里化(currying).
18..call和.apply有什么区别?
.call和.apply都用于调用函数,第一个参数将用作函数内 this 的值。然而,.call接受逗号分隔的参数作为后面的参数,而.apply接受一个参数数组作为后面的参数。一个简单的记忆方法是,从call中的 C 联想到逗号分隔(comma-separated),从apply中的 A 联想到数组(array)。
 function add(a, b) { return a + b; } console.log(add.call(null, 1, 2)); // 3 console.log(add.apply(null, [1, 2])); // 3
19.请尽可能详细地解释 Ajax。
Ajax(asynchronous Javascript and XML)是使用客户端上的许多 Web 技术,创建异步 Web 应用的一种 Web 开发技术。借助 Ajax,Web 应用可以异步(在后台)向服务器发送数据和从服务器检索数据,而不会干扰现有页面的显示和行为。通过将数据交换层与表示层分离,Ajax 允许网页和扩展 Web 应用程序动态更改内容,而无需重新加载整个页面。实际上,现在通常将 JSON 替换为 XML,因为JavaScript对 JSON 有原生支持优势。
XMLHttpRequest API 经常用于异步通信。此外还有最近流行的fetch API。
使用 Ajax 的优缺点分别是什么?
优点
交互性更好。来自服务器的新内容可以动态更改,无需重新加载整个页面。
减少与服务器的连接,因为脚本和样式只需要被请求一次。
状态可以维护在一个页面上。JavaScript变量和 DOM 状态将得到保持,因为主容器页面未被重新加载。
基本上包括大部分 SPA 的优点。
缺点
动态网页很难收藏。
如果JavaScript已在浏览器中被禁用,则不起作用。
有些网络爬虫不执行 Javascript,也不会看到 Javascript 加载的内容。
基本上包括大部分 SPA 的缺点。
20.请说明 JSONP 的工作原理,它为什么不是真正的 Ajax?
JSONP(带填充的 JSON)是一种通常用于绕过 Web 浏览器中的跨域限制的方法,因为 Ajax 不允许跨域请求。
JSONP 通过<script>标签发送跨域请求,通常使用callback查询参数,例如:https://example.com?callback=printData。 然后服务器将数据包装在一个名为printData的函数中并将其返回给客户端。
 <!-- https://mydomain.com --> <script> function printData(data) {  console.log(`My name is ${data.name}!`); } </script> <script src="https://example.com?callback=printData"></script>
 // 文件加载自 https://example.com?callback=printData printData({ name: 'Yang Shun' });
客户端必须在其全局范围内具有printData函数,并且在收到来自跨域的响应时,该函数将由客户端执行。
JSONP 可能具有一些安全隐患。由于 JSONP 是纯 Javascript 实现,它可以完成 Javascript 所能做的一切,因此需要信任 JSONP 数据的提供者。
现如今,跨来源资源共享(CORS) 是推荐的主流方式,JSONP 已被视为一种比较 hack 的方式。