noah的前端面試題(三)|掘金技術徵文

麻醬愛我發表於2018-04-15

上一篇 前端面試題(二)

1.JavaScript對於cookie的讀、寫操作

寫入 cookie

function setCookie(cName, cValue, days) {   
 var expires = new Date();    
 expires.setTime(expires.getTime() + parseInt(days) * 24 * 60 * 60 * 1000);    
 document.cookie = cName + "=" + escape(cValue) + ";expires=" +       expires.toGMTString()+";path=/;domain=xxx.cn"; 
 };複製程式碼
  • expires: cookie的過期時間,注意這裡要使用格林威治時間
  • path: 這個參數列示cookie儲存的路徑,如果沒有給出的話會儲存為當前站點的,如果給出值”/“的話會儲存到當前虛擬目錄
  • domain: 這個引數有點類似於session的儲存路徑,預設情況下儲存在當前客戶端,也可以自定義到其他位置

讀取cookie

function getCookie(name){     
 var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));   
 if(arr != null)   return decodeURI(arr[2]); 
 return null;  
}複製程式碼

分享一片關於cookie的文章  http://www.cnblogs.com/Darren_code/archive/2011/11/24/Cookie.html

2.setTimeout promise 和 await sync執行順序

async function async1() {
console.log("async1 start");
await  async2();
 console.log("async1 end");
}
async  function async2() {
 console.log( 'async2');
}
console.log("script start");
setTimeout(function () {
 console.log("settimeout");
},0);
async1();
new Promise(function (resolve) {
 console.log("promise1");
 resolve();
}).then(function () {
 console.log("promise2");
});
console.log('script end'); 複製程式碼
結果是:

script start async1 start async2 promise1 script end async1 end promise2 settimeout  

這裡涉及到同步非同步 Microtasks Macrotasks Microtasks優先順序別高於Macrotasks  其中Microtasks Macrotasks分別是

microtasks:

  • process.nextTick
  • promise
  • Object.observe
  • MutationObserver

macrotasks:

  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI渲染
  1. 一個事件迴圈(event loop)會有一個或多個任務佇列(task queue)
  2. task queue 就是 macrotask queue
  3. 每一個 event loop 都有一個 microtask queue
  4. task queue == macrotask queue != microtask queue
  5. 一個任務 task 可以放入 macrotask queue 也可以放入 microtask queue 中
因此事件迴圈的順序,決定了JavaScript程式碼的執行順序。它從script(整體程式碼)開始第一次迴圈。之後全域性上下文進入函式呼叫棧。直到呼叫棧清空(只剩全域性),然後執行所有的micro-task。當所有可執行的micro-task執行完畢之後。迴圈再次從macro-task開始,找到其中一個任務佇列執行完畢,然後再執行所有的micro-task,這樣一直迴圈下去。

3. 關於Vue.nextTick()的正確使用 什麼時候需要用的Vue.nextTick()

在下次 DOM 更新迴圈結束之後執行延遲迴調。在修改資料之後立即使用這個方法,獲取更新後的 DOM。

  1. 你在Vue生命週期的created()鉤子函式進行的DOM操作一定要放在Vue.nextTick()的回撥函式中。原因是什麼呢,原因是在created()鉤子函式執行的時候DOM 其實並未進行任何渲染,而此時進行DOM操作無異於徒勞,所以此處一定要將DOM操作的js程式碼放進Vue.nextTick()的回撥函式中。與之對應的就是mounted鉤子函式,因為該鉤子函式執行時所有的DOM掛載和渲染都已完成,此時在該鉤子函式中進行任何DOM操作都不會有問題 。

  2. 在資料變化後要執行的某個操作,而這個操作需要使用隨資料改變而改變的DOM結構的時候,這個操作都應該放進Vue.nextTick()的回撥函式中。

4. 關於陣列排序 任意數值相同的陣列混亂排序但是每次排出的順序都是一樣的 比如是【1,3,5,6】或者 【6,5,3,1】排除順序以後是 【3,6,1,5】

用陣列sort方法

5. es5 和 es6 class 有什麼區別 

用ES6定義class中的方法,定義在原型物件上的。與ES5不同的是,這些定義在原型物件的方法是不可列舉的。

ES6類和模組是嚴格模式下的;

不存在變數提升,保證子類父類的順序;

子類必須在父類的建構函式中呼叫super(),這樣才有this物件,因為this物件是從父類繼承下來的。而要在子類中呼叫父類的方法,用super關鍵詞可指代父類。

ES5中類繼承的關係是相反的,先有子類的this,然後用父類的方法應用在this上。

ES6類繼承子類的this是從父類繼承下來的這個特性,使得在ES6中可以構造原生資料結構的子類,這是ES5無法做到的。

ES6也可以定義類的靜態方法和靜態屬性,靜態的意思是這些不會被例項繼承,不需要例項化類,就可以直接拿來用。ES6中class內部只能定義方法,不能定義屬性。在方法名前加上static就表示這個方式是靜態方法,而屬性還是按照ES5的方式來實現。

7. es6 class內部箭頭函式寫法和普通函式寫法有什麼不同

class Person { 
 Run() {    //傳統形式的函式寫法  this; } 
 eat = () => {    //es6中的箭頭函式寫法  this; }     
}   複製程式碼

編譯之後的結果如下

var Person = (function () {
    function Person() {
        var _this = this;
        this.eat = function () {    //箭頭寫法直接掛到Person的this下
            _this;        
        };   
     }   
    Person.prototype.Run = function () {    //傳統寫法則掛到prototype中定義       
     this;
    };       
    return Person;
 }());  複製程式碼

這裡不僅展示了在方法的定義,還比較了在ES6中傳統函式和箭頭函式的區別,傳統函式的thises5函式的this指向完全一樣,但箭頭函式的this指向的是它外層物件的作用域,這裡不細說,想了解請點選


7.vue.js中的事件修飾符.self的用法

.self可以理解為跳過冒泡事件和捕獲事件,只有直接作用在該元素上的事件才可以執行。


8. pwa 快取策略

Service Worker 是一段指令碼,與 Web Worker 一樣,也是在後臺執行。作為一個獨立的執行緒,執行環境與普通指令碼不同,所以不能直接參與 Web 互動行為。Native App 可以做到離線使用、訊息推送、後臺自動更新,Service Worker 的出現是正是為了使得 Web App 也可以具有類似的能力。詳情連結

9. 混合開發中如何native的token

10. Vue 中如何使用 MutationObserver 做批量處理?

現在 Vue 的 nextTick 實現移除了 MutationObserver 的方式(相容性原因),取而代之的是使用 MessageChannel。至於 MutationObserver 如何模擬 nextTick 這點,直接看原始碼,其實就是建立一個 TextNode 並監聽內容變化



相關文章