坐标杭州,18年毕业,算上实习一年半开发经验。是外派的面试,后面两面都是阿里的面试官。css
原本是给我发的在线测评,可是那边服务器出现问题,我一直打不开网页,最后只好以电话问答的形式。下面我写的大部分都是测评里的题目,部分是电话里新增的题目。。。html
<div class="father">
<div class="child">
</div>
</div>
<style> .father { width: 300px; height: 300px; } .child { } </style>
复制代码
child分不少种状况,大体说一下react
.father{
text-align: center;
line-height: 300px;
}
复制代码
.father{
position: relative;
}
.child{
position: absolute;
top: 50%;
left: 50%;
margin: -150px 0 0 -150px;
}
/* 或者 */
.child{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
复制代码
.father{
position: relative;
}
.child{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
复制代码
.father{
display: flex;
}
.child{
margin:auto;
}
/* 或者 */
.child{
justify-content: center;
align-items: center;
}
复制代码
.father{
display: table;
}
.child{
display: table-cell;
text-align: center;
vertical-align: middle;
}
复制代码
<div class="container">
<div class="main"></div>
<div class="sub"></div>
<div class="extra"></div>
</div>
复制代码
console.log(+false) // 0, 这里是一元运算符进行的弱类型转换,相对应的 +true 则返回 1
console.log('1' + 2 + '3' + 4) // '1234' 遇到字符串就会拼接
console.log(4 + 3 + 2 + '1') // '91' 先加在一块儿再拼接
复制代码
var x = 3;
var foo = {
x: 2,
baz: {
x: 1,
bar: function() {
return this.x;
}
}
}
var go = foo.baz.bar;
console.log(go()); // 3
console.log(foo.baz.bar()); // 1
复制代码
这题考的是this的指向:面试
this由调用者提供,由调用函数的方式来决定。若是是一个对象调用的函数,则this指向该对象,好比
foo.baz.bar()
。若是函数独立调用好比go()
,那么该函数内部的this,则指向undefined。可是在非严格模式中,它会被自动指向全局对象window。算法
function reverse(str) {
let res = str.split('');
return res.reverse().join('');
}
reverse('hello world!'); // output: '!dlrow olleh'
复制代码
进阶问题编程
'hello world!'.reverse(); // output: '!dlrow olleh'
复制代码
String.prototype.reverse = function reverse() {
let res = this.split('');
return res.reverse().join('');
}
复制代码
要求用法:redux
/** - 使当前运行的异步操做(promise 或者 async)中止等待若干秒 - - @param ms */
(async () => {
console.log('hello')
await sleep(2000) // 等待两秒
console.log('world')
})()
复制代码
const sleep = (ms) => {
new Promise(resolve, reject) {
setTimeOut(() => {
resolve(); // 大体这样?
}, ms)
}
}
复制代码
用法:api
const throFun = () => console.log('hello');
const thro = throttle(throFun, 300);
document.body.onscroll = () => {
thro(); // 调用至少间隔 300 毫秒才会触发一次
}
复制代码
/** - 频率控制,返回函数连续调用时,action 执行频率限定为 1次 / delay - @param delay {number} 延迟时间,单位毫秒 - @param action {function} 请求关联函数,实际应用须要调用的函数 - @return {function} 返回客户调用函数 */
function throttle(action, delay) {
var previous = 0;
// 使用闭包返回一个函数而且用到闭包函数外面的变量previous
return function() {
var _this = this;
var args = arguments;
var now = new Date();
if(now - previous > delay) {
action.apply(_this, args);
previous = now;
}
}
}
复制代码
用法:数组
const throFun = () => console.log('hello');
const thro = debounce(throFun, 300);
document.body.onscroll = () => {
thro(); // 若一直调用则不会执行,空闲时间大于 300 毫秒才会执行
}
复制代码
/** - 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 delay,action 才会执行 - @param delay {number} 空闲时间,单位毫秒 - @param action {function} 请求关联函数,实际应用须要调用的函数 - @return {function} 返回客户调用函数 */
function debounce(action, delay) {
var timer; // 维护一个 timer
return function () {
var _this = this; // 取debounce执行做用域的this
var args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
action.apply(_this, args); // 用apply指向调用debounce的对象,至关于_this.action(args);
}, delay);
};
}
复制代码
const arr = [1,2,3,4,4,3,2,1];
// 方法一:new Set ES6
return [...new Set(arr)]; // 这里又问到我...的用法
// 方法二:双层for循环 (而后说这样性能很差,让我只用一层for循环的方法)
function unique(arr){
var res=[];
for (var i = 0; i < arr.length; i++) {
for (var j = i+1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
++ i;
j = i;
}
}
res.push(arr[i]);
}
return res;
}
// 方法三:单层for循环 + indexOf
function unique(array){
var res = [];
for(var i = 0; i < array.length; i++) {
//若是当前数组的第i项在当前数组中第一次出现的位置是i,才存入数组;不然表明是重复的
if (array.indexOf(array[i]) === i) {
res.push(array[i])
}
}
return res;
}
// 方法三点三:或者这样
function unique(array){
let res = [];
for(var i = 0; i < array.length; i++) {
if (res.indexOf(array[i]) === -1) {
res.push(array[i]);
}
}
return res;
}
// 方法四:面试官说若是能够容忍改变原有数组的状况下,怎么改进性能更好
function unique(array){
// 注意这里必定要倒叙for循环,不然会出现问题
for(var i = array.length - 1; i > 0; i--) {
if (array.indexOf(array[i]) !== i) {
array.splice(i, 1);
}
}
// 由于少声明一个变量,节省了内存空间(虽然能够忽略不计,可是面试嘛~)
return array;
}
复制代码
题目描述:promise
实现思路:
面试事后整理的代码:
window.addEventListener('click', (e) => {
let targetNode = e.target
while (targetNode !== document) { // 只要当前节点不是最外层document
console.log(targetNode)
if (targetNode.getAttribute('data-href')) { // 其实用hasAttribute更合适
window.open(targetNode.dataset.href)
break
} else { // 没找到就继续往上找
targetNode = targetNode.parentNode
}
}
})
复制代码
总结:
contains()
方法,而后面试官考虑性能,最好用原生api。而后我就说用parentNode。后来我查了一下MDN,发现contains
这个方法就是原生的api,IE5以上就支持了:
getAttribute()
。1.Redux 鼓励一个应用只用一个 Store,Mobx 鼓励使用多个 Store; 2.Redux 是函数式编程,而Mobx的模式是面向对象的; 3.Redux 使用“拉”的方式使用数据,这一点和 React是一致的,但 Mobx 使用“推”的方式使用数据; 4.Redux 鼓励数据范式化,减小冗余,Mobx 允许数据冗余,但一样能保持数据一致。 5.Redux更严格,必须调用reducer触发action来改变state, Mobx 最初的一个卖点就是直接修改数据,可是实践中你们仍是发现这样无组织无纪律很差,因此后来 Mobx 仍是提供了 action 的概念。和 Redux 的 action 有点不一样,Mobx 中的 action 其实就是一个函数,不须要作 dispatch。若是想强制要求使用 action,禁止直接修改 observable 数据,使用 Mobx 的 configure,以下:
import {configure} from 'mobx'; configure({enforceActions: true}); 复制代码