日常複習

// 判斷數組對象特定屬性是否相同
function isEqualObj(arr, key) {
  const newArr = arr.map(item => item[key])
  const arrSet = new Set(newArr)
  return arrSet.size !== newArr.length
}

// js 繼承有四種 原型鏈繼承, 構造函數繼承, 組合繼承,寄生繼承
// 原型繼承,改了其中一個實例會影響其它的,構造函數繼承不到父類的屬性和方法

//組合繼承
function chidren(name) {
  this.name = name
}
chidren.prototype.getName = function() {
  return this.name
}


function inhert() {
  // 構造函數繼承
  chidren.call(this,'王二')
}

inhert.prototype = new chidren()
// inhert.prototype = Object.create(chidren.prototype) //將指向父類實例改爲指向父類原型 爲寄生繼承
inhert.prototype.constructor = inhert

// 使用
const inhert1 = new inhert()
inhert1.name  // ['王二']


// 數組去重
function removeDuplicate(arr, key) {
  let obj = {}
  const curArr = arr.reduce((pre, cur)=> {
    obj[pre[key]] ? '' : obj[pre[key]] = true && pre.push(cur)
    return pre
  },[])
  return curArr
}

// 實現sleep(1000)
const sleep = time => {
  return new Promise((resolve) => {
    resolve(setTimeout(() => {
      console.log('time');
    }, time))
  })
}
// 使用
sleep(1000).then(res => {
  console.log(res);
})

// 手動實現bind  
Function.prototype.myBind = function() {  // 不能使用箭頭函數,應爲this的指向不同
  // arguments 可以獲取函數的所有參數,是一個僞數組, 使用Array.from() 將 僞數組轉換成數組
  const arg = Array.from(arguments)
  // 獲取this 指向取出數組的第一項,數組剩餘的就是傳遞的參數
  const self = this 
  return () => {
    return self.apply(_this,arg)
  }
}

// 使用
function fn1(a, b, c) {
  console.log('this',this);
  console.log(a,b,c);
}
const fn2 = fn1.myBind(10,20,30)
console.log(fn2);

// 手動實現call
Function.prototype.myCall = function() {
  const fn = Symbol('fn')                // 聲明一個獨有的symbol屬性,防止fn覆蓋已有屬性
  thisArg = thisArg || window           // 如沒有傳入this,默認綁定到window
  thisArg[fn] = this                   // this 指向調用call的對象,即我們要改變this指向的函數
  const result = thisArg[fn](...args) // 指向當前函數
  delete thisArg[fn]                 // 刪除聲明的fn屬性
  return result
}

// 並集,交集,差集
let set1 = new Set([1,2,3])
let set2 = new Set([2,3,4])
// 並集
let union = new Set([...set1, ...set2])
// 交集
let interset = new Set([...set1].filter(x => set2.has(x)))
// 差集
let difference = new Set([...set1].filter(x=> !set2.has(x)))

// 克隆
function deepClone(obj) {
  if (!obj || typeof obj !== 'object') return
  const data = Array.isArray(obj) ? [] : {}
  for (let i in obj) {
    data[i] = typeof(obj[i]) === 'object' ? deepClone(obj[i]) : obj[i]
  }
  return data
}

// 去重
function removeRepeat(arr, key) {
  let obj = {}
  const cur = arr.reduce((pre,cur) => {
    obj[cur[key]] ? '' : obj[cur[key]] = true && pre.push(cur)
    return pre
  },[])
  return cur
}

// 求和
function sum(arr) {
  let data = arr.reduce((pre,cur) => {
    return pre + cur
  },0)
}

// 防抖是在事件觸發後n秒再去執行回調,如果n秒內再次被觸發,則重新計算,最常用 搜鎖框輸入查詢,表單提交
function debouce(fn, wait) {
  let time = null
  return function() {
    time && clearTimeout(time)
    time = setTimeout(() => {
      fn.apply(this, arguments)
    }, wait);
  }
}

// 節流 是指如果頻繁觸發一個事件,則n秒後執行一次
function throttle(fn, wait) {
  let flag = true
  return function() {
    if (!flag) return
    flag = false
    setTimeout(() => {
      fn.apply(this, arguments)
      flag = true
    }, wait);
  }
}

// 計算 1+2+3...100
function sumByValue(val) {
  if (val === 1) return 
  return sumByValue(val -1) + val
}

// Set 和Map的區別是,Set類似於數組,每一個值是唯一的,Map類似於對象,是鍵值對的集合
// AMD require 是運行時調用,可以用在任何地方,是賦值的過程可以是數組,對象,字符串
// CMD import  是編譯是調用,所以必須用於開頭,是解構的過程


// 通常緩存,分爲協商緩存和強制緩存
// 強制緩存: 1.瀏覽器控制 2.後端把過期時間和資源發過來,瀏覽器每次獲取資源看一下過期時間到了沒
// 協商緩存: 1.服務器控制 2.後端把資源標識,和資源發送過來,瀏覽器每次用的時候,就會拿標識和後端存儲的對比一下不一樣就更新
// 強制緩存使用時間來判斷,時間分爲相對時間和絕對時間
// 絕對時間 expires字段
// 相對時間 後端給有效時長,瀏覽器自己倒計時,對應着請求的cach-control字段,同時存在。cach-control優先級更高

// js垃圾回收,就是標記清除和引用計數
// js中 ! 和 !! !將變量轉換成boolen類型,!!常常用來做類型判斷,在第一步!之後再做邏輯取反運算, ??只有在左側爲null和undefiend時,纔會返回右側數據
// 漸進式圖片加載 antimoderate
// aligin-self: baseline
// vue中定義props類型,Proptype
// [1,2,3].map(parseInt) 結果時[1,NAN,NAN]  原因是,最終會轉換成 arr.map((value,index, array) => parseInt(value,index))
// flex:1 對應這flex-grow(拉伸佔比) flex-shrink(收縮規則,0 爲不收縮) flex-basis(主軸方向初始大小)
// 迴流,當元素尺寸,位置發生變化需要重新計算。 重繪: 當元素DOM樣式發生變化,沒有影響到DOM的幾何尺寸
// GET和POST 請求的區別: 1. get請求在url上,post在請求體中 2.get請求有長度限制(瀏覽器限制的) 3.post請求相對安全點,get請求在url上,且有歷史記錄 4. get請求能緩存,post不能
// HTTPS使用443端口,HTTP使用80端口  2. http是超文本傳輸協議,是明文傳輸,https是經過SSL加密協議,傳輸更安全,不過要申請證書  3. https比http慢因爲,除了tcp握手的三個包,還有ssl加密的9個包
// http1.1和http2.0區別: 1.1使用基於文本的格式傳輸,2.0使用二進制傳輸, 1.1不支持header數據壓縮,2.0使用hpack算法對header進行數據壓縮,體積更小,傳輸更快
// http 請求狀態碼總結
// 1**  服務器接收請求,需要請求者接着操作
// 2**  請求成功
// 3**  重定向,需要進一步操作
// 4**  客戶端錯誤,請求包含語法錯誤,無法完成請求
// 5**  服務器錯誤
// 從瀏覽器輸入url頁面發生了什麼? 
// 1. DNS查詢,解析url中對應的ip地址 2.tcp鏈接 3.發送http請求 4.server處理http請求,並返回http保文 5. 瀏覽器解析,render頁面 6. http斷開鏈接

// VUE中diff算法:
// VUE根據真實dom生成一個virtural DOM ,當virtral DOM 的某個節點數據改變後會生成一個新的Vnode,然後Vnode和 oldVnode做對比,發現不一樣就直接更新dom,然後oldVnode的職位Vnode,
// 來實現節點更新。 具體是: 1.同級比較再比較字節點 2. 先判斷一方是否有子節點,如果新的的沒有子節點,就將舊的字節點移除掉 3.都有子節點的情況,遞歸比較子節點
// VUE中key的作用,儘可能的複用dom元素,新舊節點如果只有順序不同,最佳是通過移動位置達到更新目的,需要再節點保持映射關係,key就是節點中的唯一標識
// VUE中template的編譯原理 1. 將模板字符串轉換成element Asts解析器 2. 對ast進行靜態節點標記,主要用來虛擬dom的優化 3.使用element ast生成render函數代碼字符串
// nextTick 是更新執行完成之後的回調,主要是宏任務和微任務,根據不同的情況,採用 promise MutationServer 微任務 promise 都不用就使用setTimeout
// .stop禁止事件冒泡, .prevert 阻止默認事件, .self 只有點擊元素本身才會執行 .capture事件觸發,會先執行大盒子的事件再執行小盒子的事件,.once只觸發一次
// data爲什麼是一個函數,對象再棧中存放的都是對象的地址,函數的作用,就是屬性私有化,保證組件修改自身的屬性不會影響到其它組件
// VUE中keep-alive實現原理和緩存策略:
// 1.獲取keep-alive的第一個組件 2. 根據include和 exclude名單進行匹配,決定是否緩存,不匹配直接返回組件實例,匹配進行第3步 3. 根據組件id和tag生成緩存組件的key,再去判斷cache中是否存在這個key,如果存在,則用緩存的實例代替Vnode的
// 的實例,然後更新key再keys的位置(LRU置換策略),如果沒有命中就緩存起來,如果超出最大緩存數,就刪除cache中的第一項 4. keep-alive是一個抽象組件:自身不會渲染DOM元素,也不會出現再父組件鏈中 5.LRU算法:根據
// 數據的歷史訪問記錄來進行數據淘汰,其實就是訪問過的,以後訪問率會高 6. LRU實現,新數據插入鏈表頭部,每當緩存命中,則將數據移至鏈表頭部,當鏈表滿的時候,則將鏈表尾部數據丟棄
// vue-router的實現原理:單頁應用只有一個頁面,所有的頁面切換,其實是組件之間的顯示和隱藏,所有的頁面都只在一個html頁面上,
// vue-router是通過對window.location.hash和windown.history進行封裝,來實現hash或url變化映射組件的變化
// vue-router 前端路由的核心就是改變視圖的同時不會向後端發送請求,而是加載對應的而組件, 有兩種模式 hash和history。 hash模式在url後面帶有#,hash值會出現在#後面,但是不包含在http請求中,hash改變會
// 觸發hashChage事件,能控制瀏覽器的前進後退,兼容性好 缺點是: 包好#不美觀, 設置的值必須與原來的值不一樣纔會觸發hashChange, 每次url改變不屬於一次http請求,不利於seo優化
// history 基於pushState()和replaceState()來實現改變頁面路徑,histoty是瀏覽器提供的歷史記錄接口,可以通過back go forward讀取歷史記錄

// for of 無法遍歷對象,forEach和map都只能遍歷數組,不能終端,前者沒有返回值,後者有 // JS中 宏任務一般包含 scpirt setTimeout setInterval 微任務: promise preocess.nextTick , promise 是同步任務 then是異步任務 // 什麼是事件循環: js是單線程語言,同個時間執行一件事(同步),但它可以有一個異步隊列,遇到異步操作,(如axios這種阻塞時間久的),把它放到異步隊列中,並繼續往下執行,當同步任務執行 // 完成,就會去異步隊列中找剛剛存放的事件依次執行(異步任務包含宏任務和微任務,微任務優先於宏任務) // VUE3自定義v-model // 父組件中使用 <test v-model:title ="value" /> //子組件中定義 <div :title="title" @update:title="title = $event">{{title}}</div> emit('update:title',t.value) // vue2自定義v-model mode: { event: 'change', prop: 'check' } // rem相對於根元素 如果font-size = 16px,那 // 監聽屏幕大小 window.onresize = function() { // 獲取屏幕寬度 let w = document.documentElement.clientWidth || document.body.clientWidth // 根據設計圖設置大小 HTML.style.fontSize = 16 * (w / 750) + 'px' } // iphonex 適配當viewport-fit = contain 時,env() 是不起作用的 必須配合 viewport-fit-cover // env() 和 constant() 需要同時存在,且順序不能換 paading - bottom: containsPoint(safe - area -inset -bottom); paading - bottom: event(safe -area -inset - bottom)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章