2018美团前端面试题,两年经验,你能答对几道?

38,975 阅读2分钟

注意:部分答案为自己整理,正确性未知。代码运行结果部分亲手运行,没问题。

获取页面元素位置与宽高?

  • element.clientWidth = content + padding
  • element.clientHeight = content + padding
  • element.getBoundingClientRect() 返回值情况
    • left:包围盒左边 border 以外的边缘距页面左边的距离
    • right:包围盒右边 border 以外的边缘距页面左边的距离
    • top:包围盒上边 border 以外的边缘距页面顶部的距离
    • bottom:包围盒下边 border 以外的便于距页面顶部的距离
    • width: content + padding + border
    • height: content + padding + border
    • 注意,设置外边距时外边距合并的情况

requestAnimationFrame 原理?是同步还是异步?

异步,传入的函数在重绘之前调用 详细参考:

  • http://web.jobbole.com/91578/
  • https://my.oschina.net/bghead/blog/850692
  • http://www.zhangxinxu.com/wordpress/2013/09/css3-animation-requestanimationframe-tween-%E5%8A%A8%E7%94%BB%E7%AE%97%E6%B3%95/

js事件机制?点击屏幕上一个按钮,事件是如何传播的?

捕获 冒泡

下面代码输出结果?为什么?

Function.prototype.a = 'a';
Object.prototype.b = 'b';
function Person(){};
var p = new Person();
console.log('p.a: '+ p.a); // p.a: undefined
console.log('p.b: '+ p.b); // p.b: b

下面代码输出结果?为什么?

const person = {
  namea: 'menglinghua',
  say: function (){
    return function (){
      console.log(this.namea);
    };
  }
};
person.say()(); // undefined
const person = {
  namea: 'menglinghua',
  say: function (){
    return () => {
      console.log(this.namea);
    };
  }
};
person.say()(); // menglinghua

下面代码输出结果?为什么?

setTimeout(() => console.log('a'), 0);
var p = new Promise((resolve) => {
  console.log('b');
  resolve();
});
p.then(() => console.log('c'));
p.then(() => console.log('d'));
console.log('e');
// 结果:b e c d a
// 任务队列优先级:promise.Trick()>promise的回调>setTimeout>setImmediate
async function async1() {
    console.log("a");
    await  async2(); //执行这一句后,await会让出当前线程,将后面的代码加到任务队列中,然后继续执行函数后面的同步代码
    console.log("b");

}
async function async2() {
   console.log( 'c');
}
console.log("d");
setTimeout(function () {
    console.log("e");
},0);
async1();
new Promise(function (resolve) {
    console.log("f");
    resolve();
}).then(function () {
    console.log("g");
});
console.log('h');
// 谁知道为啥结果不一样?????????????
// 直接在控制台中运行结果:      d a c f h g b e
// 在页面的script标签中运行结果:d a c f h b g e

js bind 实现机制?手写一个 bind 方法?

// 代码来自书籍 《javaScript 模式》
if (typeof Function.prototype.bind === "undefined"){
  Function.prototype.bind = function (thisArgs){
    var fn = this,
        slice = Array.prototype.slice,
        args = slice.call(arguments, 1);
    return function (){
      return fn.apply(thisArgs, args.concat(slice.call(arguments)));
    }
  }
}

实现 vue 中的 on,emit,off,once,手写代码。

// 参照 vue 源码实现
var EventEmiter = function (){
  this._events = {};
};
EventEmiter.prototype.on = function (event, cb){
  if (Array.isArray(event)){
    for (let i = 0, l = event.length; i < l; i++){
      this.on(event[i], cb);
    }
  } else {
    (this._events[event] || (this._events[event] = [])).push(cb);
  }
  return this;
};
EventEmiter.prototype.once = function (event, cb){
  function on () {
    this.off(event, cb);
    cb.apply(this, arguments);
  }
  on.fn = cb;
  this.on(event, on);
  return this;
};
EventEmiter.prototype.off = function (event, cb){
  if (!arguments.length){
    this._events = Object.create(null);
    return this;
  }
  if (Array.isArray(event)){
    for (let i = 0, l = event.length; i < l; i++){
      this.off(event[i],cb);
    }
    return this;
  }
  if (!cb){
    this._events[event] = null;
    return this;
  }
  if (cb){
    let cbs = this._events[event];
    let i = cbs.length;
    while(i--){
      if (cb === cbs[i] || cb === cbs[i].fn){
        cbs.splice(i, 1);
        break;
      }
    }
    return this;
  }
};
EventEmiter.prototype.emit = function (event){
  let cbs = this._events[event];
  let args = Array.prototype.slice.call(arguments, 1);
  if (cbs){
    for (let i = 0, l = cbs.length; i < l; i++){
      cbs[i].apply(this,args);
    }
  }
};

用 js 实现双链表,手写代码?

vue 的双向绑定机制?详细介绍。

哪些操作会引起浏览器重绘和重排?

  • postion:absolute; left:100px;会不会引起?
  • translateX:100px;会不会引起?
  • getBoundingClientRect会不会引起?
  • getClientWidth、getClientHeight会不会引起?

页面性能监测?