二階段企業面試真題(2103+2104)
二階段企業面試真題
1、引用型別和基本型別的區別
基本型別有:Undefined、Null、Boolean、Number、String、Symbol
引用型別有:統稱為 Object 型別。
1)、記憶體的角度:
基本型別在記憶體中,佔據一塊空間,空間裡儲存的就是資料,獲取資料是直接獲取
引用型別在記憶體中,佔據兩塊空間,第一塊儲存的是地址,第二塊儲存的是資料,獲取資料是屬間接取值
2)、賦值的角度
基本型別賦的就是值,引用型別賦的就是地址
3)、函式傳參
基本型別傳的是值,引用型別傳的是地址
2、null和undefined區別
https://blog.csdn.net/jiang7701037/article/details/79303829
undefined:定義變數後,沒有賦值
null:物件沒有引用的值,即就是引用型別裡沒有儲存地址
3、js中的== 和 ===區是什麼
https://blog.csdn.net/jiang7701037/article/details/85200401
三等是資料和型別都相等, ==會嘗試進行型別轉換
4、Let ,const、var的區別[越詳細越好) 擴充套件;它們的儲存位置
https://blog.csdn.net/jiang7701037/article/details/83929296
https://blog.csdn.net/jiang7701037/article/details/83929371
相同點:都是用來定義變數的
不同點:
1)、宣告提升:var會宣告提升,let和const不會
2)、作用域:var是全域性作用域和函式作用域,let和const是塊級作用域(包括全域性和函式作用域)
var定義的全域性變數是window物件的屬性,let和const定義的全域性變數不是window的屬性
3)、多個同名的變數:var可以,let和const不行
4)、暫時性死區:var沒有,let和const有
5)、let在迴圈裡,可以暫存迴圈變數
6)、const定義的變數是常量,必須賦初始值而且不可修改
5、const 定義一個數組,改變下標0的值,會報錯嗎
不會報錯,const修飾的是陣列,而不是陣列的元素。
補充:const修飾引用型別時,都修飾的是地址。而不是資料。
6、for迴圈裡let換成var會發生什麼
① 如果換成var,for 迴圈定義的迭代變數會滲透到迴圈體外部
② let在迴圈裡會暫存變數,如果在迴圈的時候向外輸出定義的變數,得到的是當前的迭代變數,換成var向外輸出都是已經迴圈結束的結果
7、this的指向,箭頭函式的this
https://blog.csdn.net/jiang7701037/article/details/111837813
this是函式的內建物件,this是代名詞,所以,this代表哪個物件,要看函式屬於哪種情況。
this的指向有四種情況:
①當this所在函式是事件處理函式時,this代表事件源
②當this所在函式是建構函式時,this代表new出來的物件
③當this所在函式時類的方法時,this代表呼叫方法的物件。
④當this所在函式沒有明確的所屬物件,this代表window物件。
另外:箭頭函式根本沒有自己的this,它內部的this就是外層程式碼塊的this
補充:
其實,this表示什麼意思,更多要看呼叫,要看執行,不要只看函式的定義。因為在呼叫時,有可能this的指向會被改變。
8、call, apply,bind的區別[說一說基本原理]
相同點:三個函式都會改變this的指向(呼叫這三個函式的函式內部的this)
不同點:
1)、bind會產生新的函式,(把物件和函式繫結死後,產生新的函式)
2)、call和apply不會產生新的函式,只是在呼叫時,繫結一下而已。
3)、call和apply的區別,第一個引數都是要繫結的this,apply第二個引數是陣列(是函式的所有引數),call把apply的第二個引數單列出來。
9、普通函式和箭頭函式的區別
1.寫法格式不同
2.箭頭函式不能作為建構函式使用
3.箭頭函式中沒有this和arguments
4.箭頭函式不具有prototype原型物件
5.箭頭函式不具有super
10、箭頭函式的作用(跟普通函式的區別) 簡要描述下ES6中的箭頭函式以及其使用場景
①.箭頭函式使表達更加簡潔
②.最主要的目的就是解決this指標的問題
使用場景:
1.簡單的函式表示式,內部沒有this引用,沒有遞迴,事件繫結,解繫結
2.內層函式表示式,需要呼叫this,且this應與外層函式一致時(保證指向vue例項)
11、原型和原型鏈
1)、原型:
每個函式都會有一個屬性prototype。這個屬性就是原型屬性。JavaScript在實現面向物件時,會經常使用原型。每個物件(例項)的有一個屬性( __ proto __)指向建構函式的prototype屬性(prototype指向的記憶體區域)。prototype屬性裡儲存著所有物件(例項)共享的屬性和方法。
2)、原型鏈:當訪問一個物件的某個屬性時,會先在這個物件本身屬性上查詢,如果沒有找到,則會去它的 __ proto __ 隱式原型上查詢,即它的建構函式的prototype,如果還沒有找到就會再在建構函式的prototype的 __ proto __中查詢,這樣一層一層向上查詢就會形成一個鏈式結構,我們稱為原型鏈。
12、作用域和作用域鏈
https://blog.csdn.net/jiang7701037/article/details/101314293
作用域,就是變數起作用的區域(範圍)。或者說,js程式碼執行時,查詢變數的範圍。
作用域鏈是指:當js編譯器在尋找變數時,先在最近的作用域(花括號)裡找,如果找不到,則朝上一級作用域(花括號)裡找,依次類推,直到找到或者找不到為止。這就是作用域鏈。
13、Ajax的步驟與封裝 AJAX中的200和4分別是什麼意思
ajax的流程,readyState和status的意思
1、建立XMLHttpRequest
let xhr = new XMLHttpRequest()
2、設定(請求方式,請求路徑,請求引數)
xhr.open("get", "regSave.php?username=jzm&userpass=123", true)
3、設定回撥函式(後端有響應時,呼叫的回撥函式)
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
xhr.responseText //後端響應的內容,如:php中的echo 後面跟的內容
}
}
4、傳送
xhr.send();
//readyState:請求響應的狀態(請求響應進行到哪一步了)
//status:響應結果的描述,是個狀態碼(數字)
readyState==4:表示請求響應的過程完畢
status==200:表示請求響應的結果----拿到了值
14、深淺拷貝 區別以及如何進行深拷貝
https://blog.csdn.net/jiang7701037/article/details/98738487
場景:
說深拷貝和淺拷貝,特指引用型別。
區別:
深拷貝: 把引用型別的地址及其它的資料都拷貝一份
淺拷貝: 只拷貝了引用型別的地址
如何進行深拷貝:
深拷貝的思路:
建立空物件,迴圈原物件的每個鍵,一一賦值給空物件,並使用遞迴的方式,把物件屬性也進行復制,以下為示例程式碼:
// 功能:封裝一個深拷貝的函式
// 引數:被拷貝的物件
// 返回值:拷貝的物件
function copyObj(obj){
let newObj ={};
for(let key in obj){
if(typeof obj[key] == "object"){ //如果說當前屬性是物件的話,那麼再做深拷貝
newObj[key] = copyObj(obj[key]);
}else{
newObj[key] = obj[key];
}
}
return newObj;
}
var obj1= {
name:"張三瘋",
sex:"男",
address:{
province:"陝西",
city:"西安"
}
}
let obj2 = copyObj(obj1);
https://blog.csdn.net/jiang7701037/article/details/98738487
15、promise promise都有哪幾種狀態 其執行狀態
概述:Promise是非同步程式設計的一種解決方案,從語法上講,Promise是一個物件,可以獲取非同步操作的訊息
作用: (1)、避免回撥地獄的問題(2)、Promise物件提供了簡潔的API,使得控制非同步操作更加容易
Promise有三種狀態:
pendding :正在進行中,
rejected :失敗,
resolved : 成功
基礎用法:new Promise(function(resolve,reject){ })
16、陣列去重的方法
①利用陣列indexof方法
function unique(arr) {
var arr1 = [];
for (var i = 0; i < arr.length; i++) {
if (arr1.indexOf(arr[i]) == -1) {
arr1.push(arr[i]);
}
}
return arr1;
}
console.log([1,1,2,2,3,3,3,4,5,6,6,6,7]);//1,2,3,4,5,6,7
②ES6的Set
function unique(arr){
return [...new Set(arr)]
}
console.log(unique([1,2,1,2,2,3,2,1]));
17、js如何建立陣列,js陣列都有哪些方法?
1、有兩種建立方式:
①字面量建立: var arr=[];
②建構函式建立: var arr1=new Array();
2、js陣列的方法:
push 尾增
pop 尾刪
unshift 頭增
shift 頭刪
concat 陣列拼接
join 陣列轉字串
reverse 逆序
sort 按字串UniCode碼排序
map 對陣列的每個元素做某個處理,引數是回撥函式,並且有返回值
slice 複製
indexOf 查詢陣列中的元素,找到返回該元素下標, 沒找到返回-1
splice 擷取
filter 過濾
every 對陣列中的每一項進行判斷,若都符合則返回true,否則返回false
some 對陣列中的每一項進行判斷,若都不符合則返回false,否則返回true(有沒有?)
reduce:將陣列所有數值進行疊加返回
forEach 對陣列的每個元素做某個處理,引數是回撥函式
18、同一個陣列,同樣的限制條件,map和filter find返回值有什麼區別
相同點:都不會改變原陣列
不同點:
map返回值是一個新的陣列,新陣列中的元素為原始陣列中的元素呼叫函式處理後的值。
find返回值:返回陣列中符合條件的第一個元素的值! 返回值不是陣列!
filter返回值:返回一個新陣列 是原陣列中符合條件的所有元素。
19、延時器(巨集任務微任務)
https://blog.csdn.net/jiang7701037/article/details/95887439
1)、巨集任務(macrotask )
巨集任務一般包括: setTimeout,setInterval,I/O 操作(包括AJAX請求),即上面的示例中setTimeout是巨集任務。
2)、微任務(microtask )
微任務一般包括:promise.then() 裡的操作
20、閉包 什麼情況下會使用閉包
概念:定義在一個函式內部的函式,並且這個內部函式能夠在外層函式外訪問到外層函式中定義的變數
作用:
①讓在外部訪問函式內部變數成為可能
②區域性變數會常駐在記憶體中
③可以避免使用全域性變數,防止全域性變數汙染
缺點:
會造成記憶體洩露(記憶體空間長期被佔用,而不被釋放)
21、網路協議
網路協議為計算機網路中進行資料交換而建立的規則、標準或約定的集合。
常見的協議有:HTTP,HTTPS、TCP/IP
HTTP和HTTPS的區別?
HTTP(HyperText Transfer Protocol:超文字傳輸協議) 簡單來說就是一種釋出和接收 HTML 頁面的方法,被用於在 Web 瀏覽器和網站伺服器之間傳遞資訊。
HTTP 預設工作在 TCP 協議 80 埠,使用者訪問網站 http:// 打頭的都是標準 HTTP 服務。
HTTP 協議以明文方式傳送內容,不提供任何方式的資料加密,如果攻擊者截取了Web瀏覽器和網站伺服器之間的傳輸報文,就可以直接讀懂其中的資訊,因此,HTTP協議不適合傳輸一些敏感資訊,比如:信用卡號、密碼等支付資訊。
HTTPS(Hypertext Transfer Protocol Secure:超文字傳輸安全協議)是一種通過計算機網路進行安全通訊的傳輸協議。HTTPS 經由 HTTP 進行通訊,但利用 SSL/TLS(安全套接層/傳輸層安全協議) 來加密資料包。HTTPS 開發的主要目的,是提供對網站伺服器的身份認證,保護交換資料的隱私與完整性。
區別:
- HTTP 明文傳輸,資料都是未加密的,安全性較差,HTTPS(SSL+HTTP) 資料傳輸過程是加密的,安全性較好。
- 使用 HTTPS 協議需要到 CA(Certificate Authority,數字證書認證機構) 申請證書,一般免費證書較少,因而需要一定費用。證書頒發機構如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
- HTTP 頁面響應速度比 HTTPS 快,主要是因為 HTTP 使用 TCP 三次握手建立連線,客戶端和伺服器需要交換 3 個包,而 HTTPS除了 TCP 的三個包,還要加上 ssl 握手需要的 9 個包,所以一共是 12 個包。
- http 和 https 使用的是完全不同的連線方式,用的埠也不一樣,前者是 80,後者是 443。
- HTTPS 其實就是建構在 SSL/TLS 之上的 HTTP 協議,所以,要比較 HTTPS 比 HTTP 要更耗費伺服器資源。
22、函式節流和事件防抖
https://blog.csdn.net/jiang7701037/article/details/99976154
函式節流:
意思:不要呼叫太頻繁,如每隔多少毫秒就呼叫一次
使用場景: 比如頁面無數次的滾動時就會觸發無數次的onscroll,但是我希望呼叫函式不要那麼頻繁
解決思路:只要頁面一滾動,就啟動一個定時器,在很多次滾動過程中,如果計時器還沒有停,則不呼叫函式,如果計時器停了,那就函式就已經呼叫一次完畢,然後再重新啟動一個定時器
let i = 0;
let myTimer = null;
window.onscroll = function(){
//無數次的滾動過程中,
//1、如果計時器還沒有停(myTimer!=null),則不執行下面的程式碼(即:直接return)。
//2、如果計時器停了(myTimer==null),說明一次執行完畢,則重新再啟動定時器。
if(myTimer!=null){
return;
}
//啟動定時器,時間間隔是200ms。
myTimer = setTimeout(()=>{
console.log(i++);
myTimer =null;
},200);
}
事件防抖:
概念:
有一些事件的觸發比較頻繁,但是,我們只希望這無數次的事件觸發中,有部分事件是有效的(如:使用者有短暫的停止時才呼叫函式)。特別是在觸發一次,就發一次請求,會有無數次的抖動。
如: 鍵盤事件:onkeydown,onkeyup,onkeypress,oninput,都是按一次鍵,觸發一次.觸發非常頻繁。
使用場景:
搜尋框(百度搜索框,淘寶,京東等等),每次使用者輸入內容都需要發一次請求,從後端拿到關鍵字對應的內容.
特別是輸入漢字時:我們希望使用者輸入完成漢字時再觸發(傳送請求),但是,實際情況是:當用戶輸入一個字母時,就會觸發一次事件(傳送一次請求)
記住:使用者的輸入習慣:當輸入完一個漢字後,或者若干個漢字後,會有短暫的停頓。而在連續輸入字母的過程中,不會有停頓。事件防抖的思路就是利用這個短暫停。
解決思路:
我們可以設定一個定時器,在每次輸入時,先清除上一次的定時器,如果本次輸入和上次輸入之間的時間間隔大於我們設定的毫秒數時,上次輸入的內容就會發送請求。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
}
</style>
</head>
<body>
<input type="text" id="querystr">
<input type="submit" value="百度一下">
</body>
</html>
<script>
let myTimer = null;
$("querystr").oninput = function(){
//在每次輸入時,先清除上一次的定時器,清除了定時器後,就不會發送請求了。
//即本次輸入和上次輸入的間隔非常短(小於100ms)時,上次定時器的程式碼就不會執行,也就不會發請求了。
//如果本次輸入和上次輸入之間的時間間隔大於100ms時,上次輸入的內容就會發送請求。
if(myTimer!=null){
window.clearTimeout(myTimer);
}
myTimer = setTimeout(()=>{
let scriptDom = document.createElement("script");
scriptDom.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=' + this.value + '&json=1&p=3&sid=1438_24869_21080_18560_17001_25177_22160&req=2&bs=1%2B&pbs=1%2B&csor=2&pwd=1%3D&cb=f&_=1511334117083';
document.body.appendChild(scriptDom);
scriptDom.remove();
},100);
}
function f(data){
console.log(data);
let htmlStr = "";
data.s.forEach((item)=>{
htmlStr+=`<li>${item}</li>`;
});
$("search-list").innerHTML = htmlStr;
}
</script>
23、跨域的解決方案
1、jsonp
可以使用jsonp來完成跨域,本質上是利用HTML標籤的 src屬性可以跨域的特性
2、CORS
3、反向代理
24、統計字串中字母個數
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
請輸入原始字串:
<input id="textId" type="text" value="aabccdeefff" /><br/>
<input type="button" value="壓縮" onclick="compress()" /><br/>
壓縮後的字串:<input id="resultId" type="text" /><br/>
</body>
</html>
<script type="text/javascript">
function $(id){
return document.getElementById(id);
}
//統計字串中每個字元的個數。(“aabccdeefff”,a2 b1 c2 d1 e2 f3)
function compress(){
//1、獲得使用者輸入
var str = $("textId").value;
//2、邏輯
//定義變數(當前字元,坐莊的字元)
var currChar = str.charAt(0);
//定義變數(記錄當前字元重複的次數,坐莊的次數)
var count = 1;
var resultStr="";//儲存結果
for(var i=1;i<str.length;i++){
if(str.charAt(i)==currChar){//如果當前字元和莊家一樣,就計數
count++;
}else{//換莊家了
//把前一個莊家和數量拼接到resultStr。
resultStr += currChar+count;
//換莊家
currChar = str.charAt(i);
//把計數器重新置為1.
count=1;
}
}
//把最後一個莊家的字元和數量進行拼接
resultStr += currChar+count;
//3、輸出
$("resultId").value =resultStr;
}
</script>
25、js執行機制
從上到下開始執行,同步程式碼一直往下走,非同步程式碼放到隊列當中,然後繼續走同步,同步走完之後,然後是事件迴圈,走事件佇列,執行滿足條件的回撥,並根據情況決定執行完成之後是否登出回撥
26、事件流,講講事件冒泡與事件捕獲、事件委託是事件冒泡還是事件捕獲,為什麼)
當某個事件執行時,從子元素向父元素觸發 或 從父元素向子元素觸發 稱為事件流
事件流分為三個階段:捕獲階段,事件源,冒泡階段
事件流的兩種模式:
事件冒泡:從子元素向父元素觸發 -->當某個事件觸發時,同樣的事件會向父元素觸發。
事件捕獲:從父元素向子元素觸發
事件委託是利用事件的冒泡原理來實現的
原理:當我們想給很多個子標籤新增同一個事件的時候,可以給它的父級元素新增對應的事件,當觸發任意子元素時,會冒泡到父級元素裡,這時繫結在父級元素的事件就會被觸發,這就是事件代理(委託),委託他們的父級代為執行事件。
作用:程式碼簡潔;減少瀏覽器記憶體的使用
27、cookie存在即合理,為什麼存在這個?這個是請求服務端 還問為什麼localStorage能永久性儲存
1)、cookie是在HTML4中使用的給客戶端儲存資料的,也可以和session配合實現跟蹤瀏覽器使用者身份,
2)、localstorage 永久性儲存是因為它是在硬碟中儲存的
28、cookie,localStorage,sessionStorage 的區別
https://blog.csdn.net/jiang7701037/article/details/89118086
相同點:
都是在客戶端儲存資料的,儲存資料的型別都是字串
不同點:
- 生命週期:
1)、cookie如果不設定有效期,那麼就是臨時儲存(儲存在記憶體中),是會話級別的,會話結束後,cookie也就失效了,如果設定了有效期,那麼cookie儲存在硬盤裡,有效期到了,就自動消失了。
2)、localStorage的生命週期是永久的,除非主動刪除資料,否則資料永遠不會消失。
3)、sessionStorage,可以理解成沒有設定有效期的cookie,也是會話級別的,只要瀏覽器視窗不關閉,資料就會一直存在
-
大小限制:
cookie大小限制在4KB,非常小;webstorage在5M
-
網路流量:
cookie的資料每次都會發給伺服器端,webstorage不會與伺服器端通訊,所以,webstorage更加節約網路流量
- 安全性:
WebStorage不會隨著HTTP header傳送到伺服器端,所以安全性相對於cookie來說比較高一些,不會擔心截獲。
- 使用方便性上:
WebStorage提供了一些方法,資料操作比cookie方便;
28、釋出者,訂閱者模式
29、map、set是什麼 map中怎樣把value改為陣列????
1)、
map是集合,儲存的每個元素是鍵值對。
set也是集合,但是儲存的元素不能重複(相當於沒有重複元素的陣列)
2)、map怎樣把value改為陣列:
map物件的values方法
30、es6面向物件 面向物件程式設計思想(說一下一對一和一對多)
-
es5和es6的繼承 es5和es6的區別
-
氣泡排序
-
獲取dom元素
-
如有兩個字串的版本號比如V2.12.0和V2.7.0,如何比對它兩的大小
-
請求方式get和post的區別
-
如何判斷請求成功或者失敗
-
getTime,parseInt,parFloat
-
請解釋—下JavaScript的同源策略
-
為驗證手機號寫一個正則
-
用js遞迴的方式寫1到100求和
-
如何中斷 ajax 請求
-
javascript事件中,event.preventDefaut()、event stopPropagation()有什麼區別?
阻止預設 event.stopPropagation()
阻止預設行為 event.preventDefault()
-
http請求過程
-
簡述你常用的程式碼命名規範的主要內容
-
簡單解釋一下什麼是CSRF攻擊,並給出常用的防範措施
-
你所瞭解的CSS 前處理器都有哪些?它們與傳統CSS相比的優點是什麼?
-
forEach和map的區別
-
除了閉包還有什麼可以 造成記憶體洩露
記憶體洩漏:記憶體空間長期被佔用,而不被釋放
閉包:函式內部定義函式,並且這個內部函式能夠訪問到外層函式中定義的變數(準確的說是宣告的引數和變數)
特點
1、讓外部訪問函式內部變數成為可能。
2、區域性變數會常駐在記憶體中。
3、可以避免使用全域性變數,防止全域性變數汙染。
4、會造成記憶體洩漏(記憶體空間長期被佔用,而不被釋放)
在位址列輸入一個url會發生什麼
https://blog.csdn.net/jiang7701037/article/details/85462359
1.使用者在瀏覽器中打回車
2.瀏覽器讀取位址列中讀取到url
瀏覽器開始識別url中的協議(http,https,ftp等等)
域名解析
查詢本地的hosts檔案,本地host有對應的ip地址,就向該ip地址傳送請求(解釋:hosts檔案是一個沒有副檔名的系統檔案,它的主要作用是能加快域名解析,還可以遮蔽網站等。)
如果本地hosts沒有,就找本地的域名伺服器(DNS),如果本地域名伺服器沒有,沒有就找根域名伺服器。(解釋:本地DNS一般是指你電腦上網時IPv4或者IPv6設定中填寫的那個DNS。這個有可能是手工指定的或者是DHCP自動分配的)
根據ip地址訪問伺服器
3.瀏覽器訪問伺服器:
瀏覽器根據解析後的ip地址訪問伺服器:瀏覽器傳送tcp連線(三次握手),建立tcp連線後,傳送http請求。- 伺服器處理請求,並響應給前端:
伺服器接收到瀏覽器端的請求後,
會根據請求的地址,找對應的檔案
如果是動態的資源(如:php,jsp,py等等),則伺服器端會執行該檔案的程式碼,把執行的結果,發給瀏覽器端
如果是靜態資源(HTML,CSS,JS,圖片,聲音等等),則直接發給瀏覽器端
5. 瀏覽器接收伺服器端的響應
瀏覽器端接收到伺服器響應的結果,開始進行解析HTML程式碼,解析時,如果碰到靜態資源的連線(如:,),則再次傳送請求。6.瀏覽器最終顯示出了頁面
關於瀏覽器如何解析HTML程式碼和渲染過程,我在後續文章中再寫 - 伺服器處理請求,並響應給前端:
-
事件委託
事件委託是利用事件的冒泡原理來實現的
當我們想給很多個子標籤新增同一個事件的時候,可以委託他們的父級代為執行事件
作用:程式碼簡潔;減少瀏覽器記憶體的使用
-
判斷一個物件是空物件的方法
-
Dom建立,新增,複製,刪除節點
-
display:none visibility hidder的區別
-
偽類和偽元素都有哪些
-
Promise和 Callback有什麼區別?
-
瀏覽器的核心分別是什麼?經常遇到的瀏覽器的相容性有哪些?
-
JavaScript 中趣何檢測一個變數是一個String型別?請寫函式實現
-
split() join()的區別
split()
將字串以某個字元分割成陣列join()
將陣列以某個字元組合成一個字串 -
簡述同步和非同步的區別?
-
前端頁面有哪三層構成,分別是什麼?作用是什麼? 答:html css javascript 結構 樣式 行為