萌妹子的前端面試

1.css中link和@import的區別

區別1:link是XHTML標籤,除了加載CSS外,還能夠定義RSS等其餘事務;@import屬於CSS範疇,只能加載CSS
區別2:link引用CSS時,在頁面載入時同時加載;@import須要頁面網頁徹底載入之後加載。
區別3:link是XHTML標籤,無兼容問題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。
區別4:link支持使用Javascript控制DOM去改變樣式;而@import不支持。
複製代碼

2.請根據優先級爲選擇器排序:id,class,tag,style,!important

!important > style > id > class > tag
複製代碼

3.請寫一個正則表達式知足這樣的規則:15到20位的大寫字母或數字

/([A-Z]|[0-9]){15,20}/
複製代碼

4.雙向數據綁定的實現原理

// Object.defineProperty 方式
var obj = {}
Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function(){
        return obj[key]
    },
    set: function(newVal){
        obj[key] = newVal
    }
})
// proxy方式
const obj = {};
const newObj = new Proxy(obj, {
  get: function(target, key, receiver) {
    return Reflect.get(target, key, receiver);
  },
  set: function(target, key, value, receiver) {
    return Reflect.set(target, key, value, receiver);
  },
})

複製代碼

5.下面的代碼會輸出什麼結果?

var fullname ='a';
var obj = {
    fullname: 'b',
    prop:{
        fullname: 'c',
        getFullName:function(){
            return this.fullname;
        }
    }
};
console.log(obj.prop.getFullName()); // =>c
var test = obj.prop.getFullName;
console.log(test())  // => a
複製代碼

6.如下代碼輸出的結果依次是

setTimeout(() => {
  console.log(1)
}, 0)
new Promise(function exectutor(resolve) {
  console.log(2)
  for (var i = 0; i < 10000; i++) {
    i == 9999 && resolve()
  }
  console.log(3)
}).then(function() {
  console.log(4)
})
console.log(5)

// => 2,3,5,4,1

Promise.resolve().then(()=>{
  console.log('Promise1')  
  setTimeout(()=>{
    console.log('setTimeout2')
  },0)
})
setTimeout(()=>{
  console.log('setTimeout1')
  Promise.resolve().then(()=>{
    console.log('Promise2')    
  })
},0)

// => Promise1,setTimeout1,Promise2,setTimeout2

console.log('start');
setTimeout(() => {
  console.log('setTimeout');
}, 0)
new Promise((resolve, reject) =>{
  for (var i = 0; i < 5; i++) {
    console.log(i);
  }
  resolve();  // 修改promise實例對象的狀態爲成功的狀態
}).then(() => {
  console.log('promise實例成功回調執行');
})
console.log('end');


// => start,0,1,2,3,4,end,promise實例成功回調執行,setTimeout

複製代碼

7.請寫一個函數對比兩個版本號的大小,如 1.2.3 和 2.1.5

function que(param1,param2) {
  var param1Arr = param1.split('.').join('')
  var param2Arr = param2.split('.').join('')
  return Number(param1Arr)>Number(param2Arr)
}
複製代碼

8.深拷貝方案有哪些,手寫一個深拷貝

// 1.JSON.parse(JSON.stringify())
// 2.手寫遞歸方法
//定義檢測數據類型的功能函數
function checkedType(target) {
  return Object.prototype.toString.call(target).slice(8, -1)
}
//實現深度克隆---對象/數組
function clone(target) {
  //判斷拷貝的數據類型
  //初始化變量result 成爲最終克隆的數據
  let result, targetType = checkedType(target)
  if (targetType === 'Object') {
    result = {}
  } else if (targetType === 'Array') {
    result = []
  } else {
    return target
  }
  //遍歷目標數據
  for (let i in target) {
    //獲取遍歷數據結構的每一項值。
    let value = target[i]
    //判斷目標結構裏的每一值是否存在對象/數組
    if (checkedType(value) === 'Object' ||
      checkedType(value) === 'Array') { //對象/數組裏嵌套了對象/數組
      //繼續遍歷獲取到value值
      result[i] = clone(value)
    } else { //獲取到value值是基本的數據類型或者是函數。
      result[i] = value;
    }
  }
  return result
}
// 3.函數庫lodash 該函數庫也有提供_.cloneDeep用來作 Deep Copy
var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);  // false
複製代碼

9.請儘可能簡單的實現一個發佈訂閱模式,要求知足:發佈、訂閱、移除

const Event = {
  clientList: {},

  // 綁定事件監聽
  listen(key, fn){
    if(!this.clientList[key]){
      this.clientList[key] = [];
    }
    this.clientList[key].push(fn);
    return true;
  },

  // 觸發對應事件
  trigger(){
    const key = Array.prototype.shift.apply(arguments),
      fns = this.clientList[key];
    
      if(!fns || fns.length === 0){
        return false;
      }

      for(let fn of fns){
        fn.apply(null, arguments);
      }

      return true;
  },

  // 移除相關事件
  remove(key, fn){
    let fns = this.clientList[key];

    // 若是以前沒有綁定事件
    // 或者沒有指明要移除的事件
    // 直接返回
    if(!fns || !fn){
      return false;
    }
    
    // 反向遍歷移除置指定事件函數
    for(let l = fns.length - 1; l >= 0; l--){
      let _fn = fns[l];
      if(_fn === fn){
        fns.splice(l, 1);
      }
    }

    return true;
  }
}

// 爲對象動態安裝 發佈-訂閱 功能
const installEvent = (obj) => {
  for(let key in Event){
    obj[key] = Event[key];
  }
}

let salesOffices = {};
installEvent(salesOffices);

// 綁定自定義事件和回調函數

salesOffices.listen("event01", fn1 = (price) => {
  console.log("Price is", price, "at event01");
})

salesOffices.listen("event02", fn2 = (price) => {
  console.log("Price is", price, "at event02");
})

salesOffices.trigger("event01", 1000);
salesOffices.trigger("event02", 2000);

salesOffices.remove("event01", fn1);

// 輸出: false
// 說明刪除成功
console.log(salesOffices.trigger("event01", 1000));
複製代碼

掃一掃,關注我吧 css

相關文章
相關標籤/搜索