JS基礎知識學習總結

JS 學習總結

1. typeof能判斷的類型?(JS變量類型)

答:undefined、number、string、boolean、symbol、object、function

2. 何時使用===,何時使用==(強制類型轉換)

答:任何時候都用===,除非是判斷==null

3. window.onload和DOMContentLoaded的區別(頁面加載過程)

答:window.onload是在頁面元素全部加載結束後觸發,二DOMContentLoaded是在頁面的骨架渲染出來,而圖片等資源尚未渲染時觸發,用戶等待時間短

4. JS創建10個<a>標籤,點擊彈出對應的序號(JS作用域)

答:

for(let i = 0; i < 10; i++){
  const a = document.createElement('a');
  a.href="javascript:;";
  a.addEventListener('click', function () {
    alert(i)
  })
  a.innerHTML = `標籤${i}`;
  document.body.appendChild(a)
}

5. 手寫節流throttle和防抖debounce(性能、體驗優化)

  • 防抖debounce
  function debounce (fn ,delay = 500) {
    let timer = null
    return function () {
      if (timer) {
        clearTimeout(timer)
      }
      timer = setTimeout( () => {
        fn.apply(this, arguments)
      }, delay)
    }
  }

  const input = document.getElementById('input')input.addEventListener('keyup', debounce(function(){
    console.log(this.value)
  }, 1000))
  
  • 節流throttle
  function throttle(fn, delay = 100) {
    let timer = null
    return function () {
      if (timer) {
        return
      }
      timer = setTimeout(() => {
        fn.apply(this, arguments)
        timer = null
      }, delay);
    }
  }
  
  const div = document.getElementById('div')
  div.addEventListener('drag', throttle(function(e){
    console.log(e.offsetX, e.offsetY)
  }, 200))

6. Promise解決什麼問題?(JS異步)

答:回調地獄

7. 值類型和引用類型的區別(值類型和引用類型)

答:值類型是存放在棧中。引用類型是放在堆中,棧中存放的是該變量在堆中的內存地址。

8. 手寫深拷貝 (值類型和引用類型)

/**
 * 深拷貝
 * @param {Object} obj 要拷貝的對象
 */
function deepClone(obj) {
  if (typeof obj !== 'object' || obj === null) return obj
  let newObj
  if (obj instanceof Array) {
    newObj = []
  } else {
    newObj = {}
  }
  for (let key in obj) {
    if (obj.hasOwnProperty(key))
      newObj[key] = deepClone(obj[key])
  }
  return newObj
}

9. 如何準確判斷一個變量是不是數組?(原型鏈)

答:a instanceof Array

10. 手寫一個簡易的jQuery, 考慮插件和擴展性 (class)

答:

class jQuery {
  constructor(selector) {
    this.selector = selector
    const res = document.querySelectorAll(selector)
    for(let i = 0; i < res.length; i++) {
      this[i] = res[i]
    }
    this.length = res.length
  }

  get (index) {
    return this[index]
  }

  each (fn) {
    for(let i = 0; i < this.length; i++) {
      fn(this[i])
    }
  }

  on (type, fn) {
    return this.each(function (ele) {
      ele.addEventListener(type, fn, false)
    })
  }
}

const p = new jQuery('p')
console.log(p.get(0))

// 插件
jQuery.prototype.dialog = function (info) {
  alert(info)
}

// 造輪子
class myJQuery extends jQuery {
  constructor(selector) {
    super(selector)
  }

  // 擴展自己的方法
  addClass(className) {
  }

  style(data) {
  }
}

11. class的原型本質,怎麼理解?(原型和原型鏈)

答:所有的實例都有隱式原型__proto__,所有的class都有顯示原型prototype,實例的隱式原型__proto__強等於class的顯示原型 prototype,而class的顯示原型prototype的隱式原型__proto__等於父類的顯示原型prototype

12. this的不同應用場景,如何取值?(作用域)

  • 作爲普通函數this指向window
  • 使用call、apply、bind,傳入什麼this就指向什麼
  • 作爲對象方法被調用,指向調用它的對象
  • 在class方法被調用,指向調用它的對象
  • 箭頭函數,不改變this指向,this是上級作用域的this

13. 手寫bind函數(this)

答:

const obj = {
  name: 'yibo'
}

function fn(a, b) {
  console.log(this)
  console.log(a + b)
  return a + b
}

function myBind(obj) {
  const context = this
  const newArguments = Array.prototype.slice.call(arguments)
  newArguments.shift()
  return function () {
    return context.apply(obj, newArguments)
  }
}

const res = fn(1, 2)
console.log(res)

Function.prototype.myBind = myBind
const myFn = fn.myBind(obj, 5, 8)
const res2 = myFn()
console.log(res2)

14. 實際開發中閉包的應用場景,舉例說明

答:

// 閉包隱藏數據,只提供API
function createCache () {
  // 閉包中的數據,被隱藏,不被外接訪問
  const data = {}
  return {
    set: function (key, val) {
      data[key] = val
    },
    get: function (key) {
      return data[key]
    }
  }
}

const c = createCache()

c.set('a', 100)
console.log(c.get('a'))

15. 同步和異步的區別是什麼?(JS異步和單線程)

答:同步會阻塞代碼執行,異步不會阻塞代碼執行

16. 手寫用Promise加載一張圖片(Promise)

答:

    const url = 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg'
    
    function loadImg(src) {
      return new Promise((resolve, reject) => {
        console.log('start')
        const img = document.createElement('img')
        img.onload = () => {
          console.log('loaded')
          resolve(img)
        }
        img.onerror = () => {
          resolve(new Error(`圖片加載失敗${src}`))
        }
        img.src = src
        console.log('end')
      })
    }
    
    loadImg(url)
    .then(img => {
      document.body.appendChild(img)
      return img
    })
    .then(img => {
      console.log(img.height)
    })
    .catch(err => console.log(err))

17. 前端使用異步的場景有哪些?

答:網絡請求、圖片加載、定時任務

18. DOM是哪種數據結構?

答:樹形結構

19. DOM操作的常用API

增刪改查:getElementsByTagName、getAttribute、setAttribute、createElement、appendChild、removeChild

20. attribute和property的區別

property: 修改對象屬性,不會體現到HTML結構中

attribute:修改HTML屬性,會改變HTML結構

兩者都可能引起DOM重新渲染

21. 一次性插入多個DOM節點,考慮性能

答:

const list = document.getElementById('list')
// 創建一個文檔片段
const fragment = document.createDocumentFragment()
for(let i = 0; i < 10; i++){
const li = document.createElement('li')
li.innerHTML = i
// 插入到文檔片段,文檔片段是在內存中
fragment.appendChild(li)
}
// 將文檔片段一次性插入
list.appendChild(fragment)

22. 如何識別瀏覽器的類型

答:UA,navigator.userAgent

23. 分析拆解URL各個部分

答:${protocol}${host}${pathname}${search}${hash} === ${href}

24. 編寫一個通用的事件監聽函數

答:

function bindEvent(ele, type, selector, fn) {
  if(!fn) {
  fn = selector
  selector = null
}
ele.addEventListener(type, function(event){
  const target = event.target
  if(selector){
    if(target.matches(selector)){
      fn.call(target, event)
    }
  }
  else {
    fn.call(target, event)
  }
})
}

25. 描述事件冒泡的流程

答:基於DOM屬性結構,事件會順着觸發元素往上冒泡,應用場景:代理

26. 無限下拉的圖片列表,如何監聽每個圖片的點擊?

答:事件代理,用e.target獲取觸發元素,用matches來判斷是否是觸發元素

27. 手寫一個簡易的ajax

答:

function ajax(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open('GET', url, true)
    xhr.onreadystatechange = function () {
      if(xhr.readyState === 4) {
        if(xhr.status === 200) {
        	resolve(JSON.parse(xhr.responseText))
        }else if(xhr.status === 404){
        	reject(new Error('404 not found'))
        }
      }
    }
    xhr.send()
  })
}

const url = '/data/test.json'
ajax(url)
.then(res=>console.log(res))
.catch(err=>console.log(err))

28. 描述cookie、localStorage、sessionStorage 的區別

答:容量、API易用性、是否跟隨http請求發送出去
cookie
本身用於瀏覽器和server通訊
被”借用“到本地存儲來
可用window.cookie=’‘來修改
缺點
存儲大小:最大4kb
http請求時需要發送到服務端,增加請求數據量
只能用document.cookie=’'來修改,太過簡陋
localStorage、sessionStorage
HTML5專門爲存儲而設計,最大可存5M
API簡單易用,setItem、getItem
不會隨http請求發送到服務器端
localStorage數據會永久存儲,除非代碼或手動刪除
sessionStorage數據只存在於當前會話,瀏覽器關閉則清空
一般用localStorage更多一些

29. 從輸入url到渲染出頁面的整個過程

答:下載資源:各種資源類型,下載過程。渲染頁面:結合HTML、CSS、JavaScript、圖片等

30. window.onload和DOMContent的區別

答:

window.addEventListener('load', funciton () {
// 頁面的全部資源加載完纔會執行,包括圖片、視頻等
})
document.addEventListener('DOMContentLoaded', function () {
// DOM 渲染完即可執行,此時圖片、視頻可能還沒加載完
})

31. 爲何建議把CSS放在head中?

答:讓DOM在生成之前就和CSS整合,然後一次性渲染完。

32. 爲何建議把JS放在body之後?

答:頁面渲染過程比較長,被js阻礙

33. 常見的web前端攻擊方式有哪些?

答:XSS跨站請求攻擊:替換特殊字符 <、 >、

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