1. 程式人生 > >28-撩課大前端-面試寶典-第二十八篇

28-撩課大前端-面試寶典-第二十八篇

1.用setTimeout()方法來模擬setInterval()與setInterval()之間的什麼區別?


首先來看setInterval的缺陷,使用setInterval()建立的定時器確保了定時器程式碼規則地插入佇列中。
這個問題在於:
如果定時器程式碼在程式碼再次新增到佇列之前還沒完成執行,
結果就會導致定時器程式碼連續執行好幾次。
而之間沒有間隔。

不過幸運的是:
javascript引擎足夠聰明,能夠避免這個問題。
當且僅當沒有該定時器的如何程式碼例項時,
才會將定時器程式碼新增到佇列中。
這確保了定時器程式碼加入佇列中最小的時間間隔為指定時間。

這種重複定時器的規則有兩個問題:
1.某些間隔會被跳過 
2.多個定時器的程式碼執行時間可能會比預期小。

下面舉例子說明:
假設,某個onclick事件處理程式使用啦setInterval()來設定了一個200ms的重複定時器。
如果事件處理程式花了300ms多一點的時間完成。

示意圖如下:


這個例子中的第一個定時器是在205ms處新增到佇列中,
但是要過300ms才能執行。
在405ms又添加了一個副本。
在一個間隔,605ms處,第一個定時器程式碼還在執行中,
而且佇列中已經有了一個定時器例項,
結果是605ms的定時器程式碼不會新增到佇列中。
結果是在5ms處新增的定時器程式碼執行結束後,
405處的程式碼立即執行。

function say(){
  //something
  setTimeout(say,200);
}
  setTimeout(say,200)

或者

setTimeout(function(){
   //do something
   setTimeout(arguments.callee,200);
},200);

2…js怎麼控制一次載入一張圖片,載入完後再載入下一張?


(1)方法1
<script type="text/javascript">
var obj=new Image();
obj.src="https://dwz.cn/jbVvWYJr";
obj.function(){
alert('圖片的寬度為:'+obj.width+';圖片的高度為:'+obj.height);
document.getElementById("mypic").innnerHTML="<img src='"+this.src+"' />";
}
</script>
<div id="mypic">onloading……</div>

(2)方法2
<script type="text/javascript">
var obj=new Image();
obj.src="https://dwz.cn/jbVvWYJr";
obj.onreadystatechange=function(){
if(this.readyState=="complete"){
alert('圖片的寬度為:'+obj.width+';圖片的高度為:'+obj.height);
document.getElementById("mypic").innnerHTML="<img src='"+this.src+"' />";
}
}
</script>

<div id="mypic">onloading……</div>

3.簡單實現Node的Events模組?


簡介:
觀察者模式或者說訂閱模式,
它定義了物件間的一種一對多的關係,
讓多個觀察者物件同時監聽某一個主題物件,
當一個物件發生改變時,
所有依賴於它的物件都將得到通知。

node中的Events模組就是通過觀察者模式來實現的:
var events=require('events');
var eventEmitter=new events.EventEmitter();
eventEmitter.on('say',function(name){
    console.log('Hello',name);
})
eventEmitter.emit('say','Jony yu');

這樣,eventEmitter發出say事件,
通過On接收,並且輸出結果,
這就是一個訂閱模式的實現,
下面我們來簡單的實現一個Events模組的EventEmitter。

(1)實現簡單的Event模組的emit和on方法
function Events(){
this.on=function(eventName,callBack){
  if(!this.handles){
    this.handles={};
  }
  if(!this.handles[eventName]){
    this.handles[eventName]=[];
  }
  this.handles[eventName].push(callBack);
}
this.emit=function(eventName,obj){
   if(this.handles[eventName]){
     for(var i=0;o<this.handles[eventName].length;i++){
       this.handles[eventName][i](obj);
     }
   }
}
return this;
}

這樣我們就定義了Events,
現在我們可以開始來呼叫:
 var events=new Events();
 events.on('say',function(name){
    console.log('Hello',nama)
 });
 events.emit('say','Jony yu');
 //結果就是通過emit呼叫之後,輸出了Jony yu

(2)每個物件是獨立的
因為是通過new的方式,每次生成的物件都是不相同的,因此:
var event1=new Events();
var event2=new Events();
event1.on('say',function(){
    console.log('Jony event1');
});
event2.on('say',function(){
    console.log('Jony event2');
})
event1.emit('say');
event2.emit('say');
//event1、event2之間的事件監聽互相不影響
//輸出結果為'Jony event1' 'Jony event2'

4.箭頭函式中this指向舉例?


var a=11;
function test2(){
  this.a=22;
  let b=()=>{console.log(this.a)}
  b();
}
var x=new test2();
//輸出22

5.https協議的工作原理?


客戶端在使用HTTPS方式與Web伺服器通訊時有以下幾個步驟:

客戶使用https url訪問伺服器,則要求web 伺服器建立ssl連結。
web伺服器接收到客戶端的請求之後,會將網站的證書(證書中包含了公鑰),
返回或者說傳輸給客戶端。
客戶端和web伺服器端開始協商SSL連結的安全等級,也就是加密等級。
客戶端瀏覽器通過雙方協商一致的安全等級,建立會話金鑰,
然後通過網站的公鑰來加密會話金鑰,並傳送給網站。
web伺服器通過自己的私鑰解密出會話金鑰。
web伺服器通過會話金鑰加密與客戶端之間的通訊。