2018美團前端面試題,兩年經驗,你能答對幾道?

linghuam發表於2019-03-04

注意:部分答案為自己整理,正確性未知。程式碼執行結果部分親手執行,沒問題。

獲取頁面元素位置與寬高?

  • 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會不會引起?

頁面效能監測?

相關文章