2020-05-14 面經(jīng)1

① for...in for...of(es6引入)

  • for...in 循環(huán)遍歷key
  • for...of 循環(huán)遍歷item,對象默認(rèn)無法使用,因為沒有部署Iterator遍歷器接口。如果和Object.keys()搭配使用,即使不部署iterator接口也可以遍歷。

② async await理解

  • 引入promise,是異步編程的一種方式,解決了ES6之前的回調(diào)地獄的問題。
  • async 返回的是一個promise對象。
  • async 函數(shù)中可以不包含await , 但是await 必須在 async函數(shù)中,await后面的表達(dá)式可以是promise,也可以是非promise,如果是promise,則返回值就是promiseresolve()的值,如果promiserejecte(),那么需要使用try catch來捕獲異常,如果是非promise值,返回值就是表達(dá)式的返回值。
  • asyncawait 算是promise的語法糖,真正實現(xiàn)了沒有回調(diào)函數(shù)獲取到值。ps : then()也算是回調(diào)函數(shù)。

③ v-model 雙向綁定原理

  • 本質(zhì)上是 v-bindv-on的結(jié)合體
  • 通過訂閱發(fā)布結(jié)合 Object.defineProperty()實現(xiàn)雙向綁定。
    • Object.defineProperty()劫持了屬性的get,set方法,一旦數(shù)據(jù)發(fā)生改變,則會通知訂閱者發(fā)布更新(update),從而更新視圖。

④ vue的通信方式

④ - ① 組件間通信的方式

  • 父子組件通信
    1. props(父 -> 子) $emit(子 -> 父)
    2. $parent $children , 訪問父組件實例,或子組件實例
    3. provide/ inject, 是vue2.2.0新增的api,父組件中配置了provide,子組件配置inject注入即可。(示例代碼如下:C 是 B 的子組件,B 是 A 的子組件)
// A.vue

<template>
  <div>
    <comB></comB>
  </div>
</template>

<script>
  import comB from '../components/test/comB.vue'
  export default {
    name: "A",
    provide: {
      for: "demo"
    },
    components:{
      comB
    }
  }
</script>
// B.vue

<template>
  <div>
    {{demo}}
    <comC></comC>
  </div>
</template>

<script>
  import comC from '../components/test/comC.vue'
  export default {
    name: "B",
    inject: ['for'],
    data() {
      return {
        demo: this.for
      }
    },
    components: {
      comC
    }
  }
</script>
// C.vue
<template>
  <div>
    {{demo}}
  </div>
</template>

<script>
  export default {
    name: "C",
    inject: ['for'],
    data() {
      return {
        demo: this.for
      }
    }
  }
</script>
  • ref refs
    • 如果在普通的DOM元素上使用,則引用是DOM元素,如果是子組件使用,引用則是子組件的實例,可以通過實例直接調(diào)用組件方法或者訪問組件數(shù)據(jù)。
  • EventBus 不推薦使用,當(dāng)項目過大時,難以維護(hù)
  • VueX
  • localStorage / sessionStorage

④ - ② 路由間傳參

⑤ vue計算屬性緩存原理?

⑥ 深拷貝淺拷貝

  • 深淺拷貝一般發(fā)生在引用類型上面,普通數(shù)據(jù)類型永遠(yuǎn)都是深拷貝。當(dāng)拷貝引用類型時,拷貝的僅僅是引用,內(nèi)存中的地址值還是相同的。即改變拷貝后的數(shù)據(jù),會對原數(shù)據(jù)發(fā)生影響。
  • 修改副本數(shù)據(jù)影響原數(shù)據(jù)的是淺拷貝,不影響源數(shù)據(jù)的是深拷貝。
  • 深拷貝的實現(xiàn):
    1. lodash函數(shù)庫
    2. 遞歸實現(xiàn)、
    3. JSON.parse(JSON.stringify())、如果對象中有function,undefined,regExp則會忽略
    4. concatslice也可以實現(xiàn)(僅對基本類型的數(shù)據(jù)生效)

⑦ 介紹一下http,https,為什么https比http更安全?

  • http:超文本傳輸協(xié)議,以明文的形式傳輸內(nèi)容,不提供任何加密。攻擊者一旦獲取到傳輸報文,就可以讀取到報文信息
  • https:安全套接字層超文本傳輸協(xié)議,在http的基礎(chǔ)上添加了SSL協(xié)議,SSL依靠證書來驗證服務(wù)器的身份,并未瀏覽器和服務(wù)器之間的通信加密。
https的原理
  1. 發(fā)送HTTPS請求,連接到server的433端口
  2. 在服務(wù)端配置數(shù)字證書
  3. 傳送證書
  4. 客戶端解析并驗證證書的有效性
  5. 加密信息(用的是證書加密后的隨機(jī)值,客戶端和服務(wù)端的通信就可以進(jìn)行加密了)
  6. 服務(wù)端解析加密信息
  7. 傳輸加密信息
  8. 客戶端接收信息
https的優(yōu)缺點
  • 優(yōu)點:安全,SEO(搜索排名靠前)
  • 缺點:費用,SEO(頁面加載變慢,功耗增大,并非絕對安全)

⑧ forEach 和 map 的區(qū)別

  • forEch沒返回值,或者說返回值是undefined,直接在函數(shù)內(nèi)操作循環(huán)項目。會改變原數(shù)組。
  • map 返回一個操作后的數(shù)組,不會改變原數(shù)組。一般在函數(shù)內(nèi)return

⑨ 垂直居中方式

  • 定位
  • flex布局
  • grid布局
  • vertical-align:middel (圖片垂直居中)
  • line-height: (文字圖片垂直居中)

⑩ Tcp三次握手,四次揮手原理

? 輸出url到頁面完成的整個過程?

  1. 查找緩存,看是否有緩存好的資源可以提高加載速度。
  2. DNS解析,將域名解析成IP地址。
  3. TCP三次握手(雙方發(fā)包的過程)
  4. 發(fā)送HTTP請求
  5. 服務(wù)端處理HTTP請求,并返回響應(yīng)報文
  6. 瀏覽器接受響應(yīng)報文并解析,并且渲染
  7. 斷開連接(TCP四次揮手)
關(guān)于第六步:

如果返回的是HTML頁面,瀏覽器會將html解析成dom樹,css解析成css規(guī)則樹,結(jié)合dom樹和規(guī)則樹形成渲染樹。根據(jù)渲染樹中的每一個DOM節(jié)點計算出相應(yīng)的位置后開始渲染。

? 排序算法,冒泡排序?

  • Array.prototype.sort(),使用的是快速排序。
冒泡排序(思路如下)
  • 數(shù)組中有n個數(shù),比較相鄰的的兩個數(shù),如果前者大于后者,就把兩個數(shù)字交換位置。這樣一來,第一輪就可以選出一個最大的數(shù)放在最后面;那么經(jīng)過(n-1)輪,就完成了所有數(shù)的排序。
冒泡排序
// 冒泡排序?qū)懛?const arr = [1, 20, 10, 30, 22, 11, 55, 24, 31, 88, 12, 100, 50];

function swap(arr, i, j){
  const temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
}

for(let i = 0; i < arr.length - 1; i++){
  let flag = false;
  for(let j = 0; j < arr.length - 1 - i; j++){
    if(arr[j] > arr[j+1]){
      swap(arr, j, j+1);
      flag = true;
    }
  }

  if(!flag){
    break;
  }
}

? web安全性?

  • xss攻擊 :兩大要素:攻擊者提交惡意代碼,瀏覽器執(zhí)行惡意代碼。解決方案:防止用戶注入惡意代碼。
  • csrf攻擊 : 使用cookie冒充用戶發(fā)送請求,導(dǎo)致目標(biāo)網(wǎng)站錯誤響應(yīng)
  • dns劫持 : dns涉嫌違法,較少
  • http劫持 : 使用https

? 變量提升?

  • var會變量提升
  • function 聲明也會函數(shù)提升

? Node.js理解?文件讀寫?

  • 理解 : 既是開發(fā)平臺,也是運行環(huán)境。基于v8引擎開發(fā)的,所以編程時使用javascript,可以理解為 讓js在服務(wù)器上運行的平臺。
  • 文件讀寫: 引入require('fs')模塊,fs.writeFile() 、 fs.readFile()

? 手寫Map方法

  • 第一個參數(shù)是函數(shù),第二個參數(shù)可指定函數(shù)中的this
Array.prototype._map = function(fn,thisValue){
  // 賦值數(shù)組給arr
  let arr = thisValue || this
  // 聲明一個空數(shù)組,作為將要返回的結(jié)果
  let result = []
  // 判斷第一個參數(shù)是否為函數(shù)
  if(typeof fn !== 'function'){
    throw new Error(fn + '該參數(shù)必須要為函數(shù)')
  }
  // 進(jìn)行循環(huán)并且將執(zhí)行結(jié)果返回
  for (let i = 0; i < arr.length ; i ++){
    let r = fn.call(arr , arr[i] , i , arr)
    result.push(r)
  }
  return result
}
let myMapVal = [1,2,8,6]._map((item)=>{
  return item * 2
})
console.log(myMapVal)  //  [2, 4, 16, 12]

? 箭頭函數(shù)與普通函數(shù)的區(qū)別?

  • 箭頭函數(shù)寫法更為簡潔
  • 箭頭函數(shù)內(nèi)部沒有this,箭頭函數(shù)中的this執(zhí)行編寫時的環(huán)境。
  • call、apply、bind無法改變 this的指向
  • 箭頭函數(shù)繼承而來的this,指向永遠(yuǎn)不會改變
  • 構(gòu)造函數(shù)不能使用箭頭函數(shù)
  • 箭頭函數(shù)沒有自己的arguments
  • 箭頭函數(shù)沒有原型 prototype
  • 箭頭函數(shù)不能用作Generator函數(shù),不能使用yeild關(guān)鍵字

? 何時用Object,何時用Map

  • 當(dāng)我們只需要用到一個簡單,便于操作的鍵值對數(shù)據(jù)結(jié)構(gòu)時,用Map更具有優(yōu)勢。因為Map具有各種操作數(shù)據(jù)的方法,get set has delete等。但是Object始終是基石,因為JSON是直接支持轉(zhuǎn)換為Object的,JSON暫未支持Map結(jié)構(gòu)。

? 原型鏈理解

  • 當(dāng)訪問實例對象的屬性或者方法時,首先會在自身查找看是否有定義,如果沒有就去__proto__屬性查找,一直到原型鏈的頂端(null),因為Object.proto為null,如果還沒有則報錯(屬性是輸出undefined,函數(shù)是 xxx is not a function)。
  • 首先說原型 、 再說原型與實例的關(guān)系。

? new 關(guān)鍵字背后所做的事情

  1. new 執(zhí)行的構(gòu)造函數(shù),函數(shù)內(nèi)部默認(rèn)生成了一個對象。
  2. 函數(shù)內(nèi)部的this,指向新生成的對象。
  3. new 執(zhí)行后生成的對象,默認(rèn)是該構(gòu)造函數(shù)的返回值。

? 介紹一下 Set 和 Map 結(jié)構(gòu)

Set
  • 類似于數(shù)組,只不過該結(jié)構(gòu)內(nèi)的成員是不重復(fù)的。比數(shù)組豐富的操作方法,如 add,delete,has,clear , 屬性:size
  • 遍歷方法(注意:set結(jié)構(gòu)沒有key,或者說key和value是同一個值)
    1. Set.prototype.keys() 遍歷鍵名
    2. Set.prototype.values() 遍歷鍵值
    3. Set.prototype.entries() 遍歷鍵值對
    4. Set.prototype.forEach(()=>{}) 使用回調(diào)函數(shù)的方法遍歷
weakSet
  • 使用 new weakSet() , 參數(shù)只能是數(shù)組,數(shù)組中成員必須是對象。
Map
  • 類似于對象,有比對象豐富的操作方法,如 add,get,set,delete,has,屬性:size
  • 遍歷方法
    1. Set.prototype.keys() 遍歷鍵名
    2. Set.prototype.values() 遍歷鍵值
    3. Set.prototype.entries() 遍歷鍵值對
    4. Set.prototype.forEach(()=>{}) 使用回調(diào)函數(shù)的方法遍歷

???????????????????????????????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容