前言:正所谓金三银四,我也在三月份面了一次荔枝FM,初试是作一套比较简单的笔试题,发出来跟你们简单探讨一下,面试时的一些问题主要是经过这些笔试题进行拓展,例如flex布局、改变正则条件,promise事件机制等等,会在下一篇文章中提到,这篇文章仅为初面的笔试题javascript
function outter () {
return inner;
function inner () {}
var inner;
inner = 9;
}
//问题是下面代码执行输出值是什么:
typeof outter();
复制代码
答案:这道题不单只是考变量提高,由于这里还有函数提高,那就是还要考函数提高和变量提高究竟谁优先级更高了。css
根据 《你不知道的JavaScript(上卷)》 里的说法,js引擎在解释代码以前会先进行编译,编译阶段会将全部的变量声明和函数声明与相关做用域关联起来,而且将这些声明提高到做用域顶部,而后到代码执行阶段才会进行变量赋值。html
虽然第一行代码就是return inner
, 可是根据上面的结论,var inner
的变量声明和function inner() {}
的函数声明会第一时间被提高到顶部。java
那么剩下的问题就是究竟函数优先仍是变量优先,答案天然也在书中找获得,那就是函数优先,函数优先提高后,因为inner
已经被声明为函数变量,后面var inner
时编译器进行LHS,也就是左查询,发现同一做用域中已经有该值会忽略该变量声明,所以这题的答案是字符串'function'
;面试
<html>
<div class="box"></div>
</html>
<style> .box { width: 45vw; height: 45vw; } </style>
复制代码
我这是使用最新标准也最简单的实现方式了,你们能够在评论写一写本身的实现方式。正则表达式
html:数组
<div class="one">
<div class="two"></div>
<div class="three"></div>
</div>
<div class="four">
<div class="five"></div>
<div class="six"></div>
</div>
复制代码
css:promise
.one {
position: relative;
z-index: 2;
.two {
z-index: 6;
}
.three {
position: absolute;
z-index: 5;
}
}
.four {
position: absolute;
z-index: 1;
.five {}
.six {
position: absolute;
top: 0;
left: 0;
z-index: -1;
}
}
复制代码
PS:其实这道题代码写的不大好,由于没有div宽度和高度,甚至.one和.four也不重叠,就算本身把代码跑起来也是没法看出是否重叠的,所以须要本身去加点东西,不过主要知道考点是什么就行了。app
解析以下:从w3c的文档能够知道,z-index属性设置一个定位元素沿 z 轴的位置,z 轴定义为垂直延伸到显示区的轴。若是为正数,则离用户更近,为负数则表示离用户更远。异步
经过上面几点能够得出答案是 .three .two .one .five .six .four,可是这只是元素层叠顺序的冰山一角,更深刻的了解能够读一下张旭鑫大神的文章。
还有疑问的能够直接经过代码看效果:元素z-index的堆叠顺序
拓展阅读:深刻理解CSS中的层叠上下文和层叠顺序
(1)字符串长度为8-12
(2)字符串只包含英文和数字
这道题算是送分题,只要对正则有所了解就能答出,并且答案不止一个,你们能够写写看本身的答案
/(\d|[A-z]{8,12})/
复制代码
function a () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('/a');
}, 1000);
});
}
function b () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('/b');
}, 2000);
});
}
function c () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('/c');
}, 500);
});
}
function d () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('/d');
}, 3000);
});
}
// Promise.race竞赛方法在第一个请求resolve后就立马进入then,能够算出最快接口的时间
const startTime = new Date / 1;
Promise.race([a(), b(), c(), d()]).then(o => {
const endTime = new Date / 1;
console.log(`接口${o}最快完成请求,请求时长为${endTime - startTime}`);
});
复制代码
要求:构造函数不能直接执行,必须使用new,每一个实例不互相影响参数列表以下
参数名 | 类型 | 默认值 |
---|---|---|
title | String | XXXX(不记得了) |
body | String | '' |
cancelText | String | 取消 |
okText | String | 确认 |
具备show和close方法,能够经过on绑定相关事件,off解绑相关事件。
须要达成效果以下:
let dialog = new Dialog();
dialog.on('show', () => {
console.log('Dialog Show');
});
dialog.on('close', () => {
console.log('Dialog Close');
});
dialog.show(); // 输出Dialog Show;
setTimeout(() => {
dialog.close(); // 输出Dialog Close;
}, 3000);
复制代码
答案:这道题看起来也是少了不少细节, 不过这是一种经常使用的弹窗组件,所以咱们能够本身给它补上应有的功能。
class Dialog {
// show方法的回调函数数组
showCallbacks = [];
// close方法的回调函数数组
closeCallbacks = [];
// 构造函数初始化参数
constructor(options) {
this.options = Object.assign(
{
title: "title",
body: "是否确认是一个dialog",
cancelText: "取消",
okText: "确认"
},
options
);
document.body.appendChild(this.renderTemplate());
this.initEvent();
}
// 渲染弹窗模板方法
renderTemplate() {
const { title, body, cancelText, okText } = this.options;
this.container = document.createElement("div");
this.container.classList = "dialog-container";
this.container.innerHTML = `<div class="dialog-title">${title}</div> <div class="dialog-body">${body}</div> <div class="dialog-footer"> <div class="dialog-confirm">${okText}</div> <div class="dialog-cancel">${cancelText}</div> </div>`;
return this.container;
}
// 初始化事件
initEvent() {
this.container
.querySelector(".dialog-confirm")
.addEventListener("click", () => {
this.close();
});
this.container
.querySelector(".dialog-cancel")
.addEventListener("click", () => {
this.close();
});
}
// 事件绑定
on(type, callback) {
if (!callback || typeof callback !== "function")
throw new Error("callback必须是函数");
this[`${type}Callbacks`].push(callback);
}
// 事件解绑
off(type, callback) {
if (callback && typeof callback === "function") {
// 将函数toString后在回调数组中查找对比。
callback = callback.toString();
this[`${type}Callbacks`].forEach((v, i) => {
// 一样的回调函数将一次性所有解绑
if (v.toString === callback) {
// 删除事件回调数组中的值
this[`${type}Callbacks`].splice(i, ++i);
}
});
return;
}
// 若是不传callback,清空整个回调函数数组
this[`${type}Callbacks`] = [];
}
// show方法,执行show回调函数数组
show() {
this.container.style.display = "block";
this.showCallbacks.forEach(callback => {
callback();
});
}
// close方法,执行close回调函数数组
close() {
this.container.style.display = "none";
this.closeCallbacks.forEach(callback => {
callback();
});
}
}
复制代码
示例代码:实现一个Dialog弹窗
最后这道题其实有两道题,选择其中之一做答,不过期间有限,我没作另外一道题因此没记住问题是什么,顺便吐槽一下那个答题页面打代码时真的很不顺手,严重影响答题效率。
上面的答案可能并不必定对或者并非最佳答案,毕竟我的答案或有缺漏,但愿有更好答案的朋友能够在评论写一下,谢谢你们的阅读。