Web前端面试题中的那些套路

2,048 阅读7分钟
原文链接: www.shuaihua.cc

(1) 请谈谈对px、em、rem、vh、wh等单位的理解。你还用过哪些单位。

  • px,如果显示器屏幕分辨率相同则可看做是绝对单位,如果显示器屏幕分辨率不同则相对于显示器屏幕分辨率。

  • em,相对于该元素font-size属性值,由于font-size是可继承属性,因此如果该元素未被显式设置font-size属性值,则会继承该元素的父元素的font-size值,如果该元素的父元素也未显式设置font-size属性值… …最终继承自根元素(HTML元素),如果根元素也没有被显示设置font-size属性值,则使用用户代理默认的font-size属性值。

  • rem,root em, 是CSS3新增的一个相对单位,与em的区别在于:使用rem为元素设置font-size属性值时,仅相对于根元素(HTML元素)。

  • vh,viewpoint height,视窗高度,1vh等于视窗高度的1%。

  • vw,viewpoint width,视窗宽度,1vw等于视窗宽度的1%。

(2) 以下程序输出的结果是什么?说出你的理由。

var length = 10;
function fn() {
  console.log(this.length);
}
var obj = {
  length: 5,
  method: function(fn) {
    fn();
    arguments[0]();
  }
}
obj.method(fn);

答案:控制台分别输出10和1。

将题目更改为:

var length = 10;
const fn = () => {
  console.log(this.length);
}
var obj = {
  length: 5,
  method: function(fn) {
    fn();
    arguments[0]();
  }
}
obj.method(fn);

则控制台分别输出10和10。

本题共涉及3种情况下的this指向:

1、对象调用方法时,方法中的this指向调用该方法的对象。

2、执行自由函数时,严格模式下函数中的this为undefined,非严格模式下为宿主对象(浏览器中的window)。

3、S6中箭头函数中的this指向由词法作用域规定。

本题中,输出“10”符合第2种情况,输出“1”符合第1种情况。

知识延伸:

  • js中的原始值、引用值

(3) 请分别写出下方两则代码片段执行后的输出结果。

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]();
let a = [];
for (let i = 0; i < 10; i++) {
  a[i] = () => {
    console.log(i);
  };
}
a[6]();

分别输出10和6。

知识延伸:

  • 作用域、作用域链。

  • ES6块级作用域

(4) 请解释cookie、sessionStorage和localStorage三者的区别。

三者都受同源策略的制约。

  • 客户端向服务端发送请求时和服务端向客户端发送响应时,cookie会已请求头、响应头的形式在客户端、服务端流动;cookie数据有大小限制,不能超过5KB;cookie期限可配置;常用于识别用户身份、记录用户浏览信息等情况。

  • sessionStorage和localStorage存储于客户端,HTML5新标准中的API,不会随请求主动发往服务端,此两者的可用存储空间在理论上未设上限,由用户代理规定存储空间上限,。

  • sessionStorage为会话存储,理论上存储的数据有期限,与标签页生命周期一致,刷新不会丢失,部分浏览器有恢复上一次关闭的标签功能,亦会恢复会话时存储的数据。

  • localStorage理论上在用户不主动清除浏览器缓存时会永久存储在本地,理论上存储的数据无期限。

(5) 请在下方代表浏览器窗口的黑色矩形中绘制出下方HTML/CSS代码片段在浏览器中渲染后的样子。并再写出至少一种常用的定位方式。

<style>
  .box {
    width:100px;  
    height:100px;  
    border: 1px solid #111;  
  }
  .box:first-child {
    position: relative;
    left: 50px;
    top: 50px;
  }
  .box:nth-child(3) {
    position: fixed;
    right: 0;
    top: 0;
  }
</style>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>

考察:

1、relative、absolute、fixed3种定位方式中各自的top、right、bottom、left属性是相对于谁定位,它们各自是否脱离文档流。

2、块级元素独占一行

(6) 请按顺序写出执行下方代码后控制台的输入结果。

function fn(cb) {
    setTimeout(function () {
        cb(a);
        console.log('print:', b);
    }, 0)
    var b = a,
        a = 2;
    console.log('print:', a);
    return
}
var a = 3;
var foo = function(arg){
    console.log('print:', arg);
}
fn(foo);
console.log('print:', a);

控制台输出结果:

print: 2
print: 3
print: 2
print: undefined

考察:

  • 理解变量声明表达式、变量赋值语句、函数声明语句。

  • 了解javascript单线程、理解事件循环队列运作机制、了解过Promise类结果事件回调冲突。

  • 作用域、作用域链、闭包、高阶函数。

  • 了解哪些情况会导致内存泄漏,如何规避泄漏的发生。


(7) 请阅读下方未完成的HTML/JS代码片段:

<body>
    <aside></aside>
    <main>
        <div>
            <a id="XUELI" href="http://www.edu2act.net/">雪梨教育</a>
        </div>
    </main>
</body>
<script>
  var button = document.getElementById('XUELI');
  document.addEventListener('click', function () {
    console.log('雪');
  }➀);
  document.addEventListener('click', function (➁) {
    console.log('提升品牌影响力');
    ➂
  }➃);
  document.getElementsByTagName('main')[0].addEventListener('click', function(➄){
    ➅
  }➆);
  button.addEventListener('click', function(➇){
    ➈
  }➉);
</script>

请补全上方JS代码中10处(你认为有必要补全的位置)。要求用户单击“雪梨教育”超链接后,控制台共输出3次,每次输出内容如下:

雪
梨
教育

(8) 请谈一谈前端同源策略。请写出你知道的解决同源策略限制的方法。

协议相同(TCP/IP、HTTP、HTTPS、FTP等不同协议)
域名相同(www.shuaihua.cc、shuaihua.cc等不同级别域名)
端口相同(80、8080、3000,443等不同端口号)

Cookie、LocalStorage 和 IndexDB 无法读取。
DOM 无法获得。
AJAX 请求不能发送。

1、浏览器允许使用 document.domain 共享 Cookie。

2、父窗口可以把信息,写入子窗口的片段标识符(URL的#号后面的部分),子窗口可以通过 hashchange 事件读取 # 后的数据,从而实现跨域资源共享。

3、浏览器窗口有window.name属性。这个属性的最大特点是,无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它。

4、HTML5为了解决这个问题,引入了一个全新的API:跨文档通信 API(Cross-document messaging),使用 window.postMessage 方法,允许跨窗口通信,不论这两个窗口是否同源。

5、JSONP、websocket、CORS

(9) 请用使用HTML和CSS实现一个自适应的正方形。

  • 代码片段字迹清晰、易读,使用何种背景色值。
  • 避免使用内联样式;了解内联样式、内部样式、外联样式;对样式规则优先级了解程度。
  • 如果元素的padding或margin值是百分比值,那么该元素最终计算值是根据父元素的宽度来的。
  • 伪元素及如何使用。
  • 分得请伪类和伪元素。
  • 垂直外边距重叠行为,产生原因、意义以及如何解决(考察是否了解BFC)。
  • 对一个问题能提出多种解决方案。

方法1:

<style>
  .box{
    width: 50%;
    padding-top: 50%;
    background-color: black;
  }
</style>
<div class="box"></div>

方法2:

<style>
  .box{
    width:50%;
    background-color: black;
    overflow: hidden;
  }
  .inner{
    margin-top: 100%;
  }
</style>
<div class="box">
  <div class="inner"></div>
</div>

方法3:

<style>
  .box{
    width:50%;
    background-color: black;
  }
  .box:before{
    content: '';
    padding-top: 100%;
    display: block;
  }
</style>
<div class="box"></div>

方法4:局限性,只能相对于视窗。

<style>
  .box {
    width: 50%;
    height: 50vw;
    background: red;
  }
</style>
<div class="box"></div>

(10) 故意出一道题干本身存在问题的题目,考察应试者是否有敢于提出质疑、对知识有大破砂锅问到底的韧劲、对问题有独到见解和直舒己见开门见山的直爽性格。

(11) 请用JavaScript实现一个函数,其接受一个可能包含嵌套的数组,返回一个展开的数组。

var arr = [1, [2, [3, 4]]];

方法1:递归

function flatten(arr){
  var res = [];
  for(var i=0;i<arr.length;i++){
    if(Array.isArray(arr[i])){
      res = res.concat(flatten(arr[i]));
    }else{
      res.push(arr[i]);
    }
  }
  return res;
}

方法2:reduce

function flatten(arr){
  return arr.reduce(function(prev,item){
    return prev.concat(Array.isArray(item)?flatten(item):item);
  },[]);
}