主頁 > 前端設計 > 【JS】萬字整理JavaScript相關基礎技術面試題總結 - 前端面試必備 - 基礎知識總結 - 秋招沖鴨

【JS】萬字整理JavaScript相關基礎技術面試題總結 - 前端面試必備 - 基礎知識總結 - 秋招沖鴨

2021-08-12 07:41:59 前端設計

在這里插入圖片描述

文章目錄

    • 1. 變數宣告與型別
      • 1.1 var let const 區別
      • 1.2 資料型別
      • 1.3 值型別與參考型別的區別
      • 1.4 typeof 能判斷哪些型別
      • 1.5 判斷資料型別的方式
      • 1.6 `===` 與 `==`
      • 1.7 truly變數與falsely變數
      • 1.8 強制型別轉換和隱式型別轉換
      • 1.9 陳述句與運算式
    • 2. 陣列字串相關
      • 2.1 手寫深拷貝
      • 2.2 手寫深度比較
      • 2.3 陣列的API有哪些是純函式
      • 2.4 `split()`和`join()`的區別
      • 2.5 陣列`slice`與`splice`區別
      • 2.6 手寫字串 trim
    • 3. 函式相關
      • 3.1 函式宣告與函式運算式
      • 3.2 什么是JSON
      • 3.3 將URL引數決議成JS物件
    • 4. 原型與原型鏈
      • 4.1 解釋一下原型與原型鏈
      • 4.2 class的原型本質
      • 4.3 new Object() 與 Object.create()的區別
      • 4.4 用class語法寫一個簡單的jQuery
    • 5. 作用域與閉包
      • 5.1 作用域
      • 5.2 this不同場景下如何取值
      • 5.3 手寫bind
      • 5.4 閉包
      • 5.5 閉包的應用場景
    • 6. ES6新特性
    • 7. 異步相關
      • 7.1 同步與異步的區別
      • 7.2 前端使用異步的場景
      • 7.3 Promise的三種狀態
      • 7.4 promise的then和catch
      • 7.5 手寫promise加載圖片
      • 7.6 async/await與Promise
      • 7.7 位元組面試看代碼題
      • 7.8 for-of 的應用場景 【異步】
    • 8. Event Loop
      • 8.1 宏任務macroTask與微任務microTask
      • 8.2 Event Loop機制
      • 8.3 event loop練習
    • 9. DOM
      • 9.1 獲取節點操作
      • 9.2 標簽屬性 attribute
      • 9.3 物件屬性 property
      • 9.4 DOM結構操作
      • 9.5 優化DOM性能
        • 9.5.1 對DOM查詢進行快取
        • 9.5.2 將頻繁操作改為一次性操作
    • 10. BOM
      • 10.1 檢查瀏覽器型別
      • 10.2 拆解URL各個部分
    • 11. 事件
      • 11.1 事件系結、冒泡、代理
      • 11.2 寫一個通用的事件系結函式
      • 11.3 描述事件冒泡程序
      • 11.4 無限下拉的圖片串列,如何監聽每個圖片的點擊
    • 12. AJAX
      • 12.1 手寫一個簡單的ajax
      • 12.2 跨域解決方案
    • 13. 瀏覽器存盤
    • 14. 頁面加載
      • 14.1 資源的形式
      • 14.2 從輸入url到渲染出頁面的整個程序
      • 14.3 window.onload與DOMContentLoaded的區別
    • 15. 性能優化
      • 15.1 前端常見性能優化方案
      • 15.2 快取
      • 15.3 SSR服務渲染
      • 15.4 圖片懶加載
      • 15.5 節流與防抖
    • 16. 前端安全
      • 16.1 XSS 跨站請求攻擊
      • 16.2 XSRF 跨站請求偽造
    • 17. 演算法刷題

之前也總結過一些前端面試題,推薦可以一起看看

【網路】計算機網路常見面試題 - 前端面試必備 - 吐血整理

【CSS】面試題總結 - 基礎知識總結 - 復習專用 - 前端面試必備 - 吐血整理

【Vue】面試題總結 - 基礎知識總結 - 復習專用 - 組件相關 - Vue家族 - 原始碼相關

這次是關于JavaScript的面試題有題目也有答案,想深入了解,可以看我之前的一些筆記博文(狠詳細),當然,每題有相關博文的我都會放鏈接~

持續更新中…

1. 變數宣告與型別

1.1 var let const 區別

  1. var是ES5語法,let、const是ES6的語法
  2. var有變數提升
  3. var、let是變數,可修改;const是常量,不可修改
  4. let、const 塊級作用域;var函式作用域

在這里插入圖片描述
【ES6】變數宣告-var-let-const-區別與聯系-總結

1.2 資料型別

值型別(7個):Undefined、Null、Number、String、Boolean、Symbol(ES6)、BigInt(ES10)
參考型別:Object:Array、Function

【JS】JavaScript-ES5資料型別-基本資料型別-參考資料型別-型別之間的轉換-資料型別的判斷

1.3 值型別與參考型別的區別

值型別 存在堆疊記憶體中,變數拿到的就是它的值
參考型別 存在記憶體中,變數拿到的只是它的一個參考,是它的地址

【JS】JavaScript-物件-Object-內建物件-宿主物件-自定義物件-操作物件-基本資料型別與參考資料型別區別

1.4 typeof 能判斷哪些型別

  1. undefined、string、number、boolean、symbol、bigint【除了null的基本型別】
  2. function 【函式】
  3. object (typeof null === ‘object’) 【所有參考型別只能到object這里】

1.5 判斷資料型別的方式

  1. typeof 【除了null的基本型別 + function】
  2. instanceof 【參考型別】【從子類到父類直到object】【順著原型鏈】
  3. toString() 【任意型別】
  4. Array.isArray() 【陣列】

1.6 =====

=== 嚴格的比較是否相等

== 會進行型別轉換,再進行比較

以下都是成立的

100 == '100'
0 == ''
0 == false
fase == ''
null == undefined

有一個情況可以用下 ==

if(a == null) {}
// 等價于
if(a === null || a === undefined)()

1.7 truly變數與falsely變數

truly變數:!!a === true 的變數
falsely變數:!!b === false 的變數

以下是falsey變數,除了這六種情況,其余都是truely變數

!!0 === false
!!NaN === false
!!'' === false
!!null === false
!!undefined === false
!!false === false

1.8 強制型別轉換和隱式型別轉換

強制:parseIntparseFloattoString
隱式:if、邏輯運算、==+拼接字串

一定要看這個,狠詳細
【JS】JavaScript-ES5資料型別-基本資料型別-參考資料型別-型別之間的轉換-資料型別的判斷

1.9 陳述句與運算式

運算式:一個運算式會產生一個值,可以放在任何一個需要值的地方

a
a+b
demo(1)
x===y? 'a': 'b'

陳述句

if(){}
for(){}

2. 陣列字串相關

2.1 手寫深拷貝

function deepClone(obj){
	if (typeof obj !== 'object' || obj === null){
		return obj
	}
	let result = Array.isArray(obj) ? []: {}
	for (let key in obj) {
		if(obj.hasOwnProperty(key)) {
			result[key] = deepClone(obj[key])
		}
	}
	return result
}

【JS】自定義JS工具函式庫-自定義物件方法-new-instanceof-mergeObject-實作陣列與物件的深拷貝與淺拷貝-封裝字串相關函式

2.2 手寫深度比較

// 判斷是否是物件或陣列
function isObject(obj) {
  return typeof obj === object && obj !== null;
}

// 深度比較
function isEqual(obj1, obj2) {
  if (!isObject(obj1) || !isObject(obj2)) {
    // 值型別,直接判斷【一般不會傳函式,不考慮函式】
    return obj1 === obj2;
  }
  if (obj1 === obj2) {
    return true;
  }
  // 兩個都是物件或陣列,而且不相等
  // 1. 先判斷鍵的個數是否相等,不相等一定回傳false
  const obj1Keys = Object.keys(obj1);
  const obj2Keys = Objext.keys(obj2);
  if (obj1Keys.length !== obj2Keys.length) {
    return false;
  }
  // 2. 以obj1為基準,和obj2依次遞回比較
  for (let key in obj1) {
    // 遞回比較
    const res = isEqual(obj1[key], obj2[key]);
    if (!res) {
      return false;
    }
  }
  // 3. 全相等
  return true;
}

2.3 陣列的API有哪些是純函式

純函式:①不改變原陣列(沒有副作用) ②回傳一個新陣列
concat、map、filter、slice

非純函式:push、pop、shift、unshift、forEach、some、every、reduce

【JS】你不得不知道的JavaScript陣列相關知識【全面總結】復習專用

2.4 split()join()的區別

split() 是字串的方法
join() 是陣列的方法

'1-2-3'.split('-') // [1,2,3]
[1,2,3].join('-') // 1-2-3

2.5 陣列slicesplice區別

slice 切片
splice 剪接

【JS】JavaScript陣列-操作方法-concat-陣列強制打平-slice-splice方法使用

2.6 手寫字串 trim

String.prototype.trim = function() {
	return this.replace(/^\s+/, '').replace(/\s+$/, '')
}

3. 函式相關

3.1 函式宣告與函式運算式

函式宣告式

function fn(a, b) {
  return a + b;
}

函式運算式

let fun = function(a, b){
  return a + b;
}

3.2 什么是JSON

  • JSON是一種資料格式,本質是一段字串
  • JSON格式與JS物件結構一致,對JS語言更友好
  • window.JSON是一個全域物件,常用的兩個方法 JSON.stringifyJSON.parse

3.3 將URL引數決議成JS物件

傳統方法,分析search

function queryToObj() {
	const res = {}
	const search = location.search.substr(1)
	search.split('&').forEach(paramStr => {
		const arr = paramStr.split('=')
		const key = arr[0]
		const val = arr[1]
		res[key] = val
	})
	return res
}

使用URLSearchParams

function queryToObj() {
	const res = {}
	const pList = new URLSearchParams(location.search)
	pList.forEach((val, key) => {
		res[key] = val
	})
	return res
}

4. 原型與原型鏈

4.1 解釋一下原型與原型鏈

每個函式物件都有顯式原型 prototype
每個實體物件都有隱式原型 __proto__
實體物件的__proto__指向函式物件的prototype

在這里插入圖片描述
(之前博文中的圖)

原型鏈:實體物件在獲取物件上的屬性和方法時,先在自身找,找不到就去隱式原型上面找

在這里插入圖片描述
(之前博文中的圖)

4.2 class的原型本質

class是ES6語法規范,由ECMA委員會發布【建構式、繼承】
ECMA只規定語法規則,不規定如何實作

下面博文具體介紹了class語法,以及具體的原生實作【建構式、繼承】

【ES6】JavaScript面向物件-面向物件與面向程序的對比-類class-繼承extends-建構式-super

【JS】JavaScript創建物件 - 工廠模式 - 建構式模式 - 原型模式 - 原型鏈 - 組合模式

【JS】JavaScript繼承 - 原型鏈 - 盜用建構式 - 組合繼承 -原型式繼承 - 寄生式繼承 - 寄生式組合繼承

4.3 new Object() 與 Object.create()的區別

  • {} 等同于 new Object(),原型為Object.prototype
  • Object.create(null) 沒有原型
  • Object.create({...}) 可以指定原型

4.4 用class語法寫一個簡單的jQuery

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

  get(index) {
    return this[index];
  }

  each(fn) {
    for (let i = 0; i < this.length; i++) {
      const elem = this[i];
      fn(elem);
    }
  }
  
  on(type, fn) {
    return this.each((elem) => {
      elem.addEventListener(type, fn, false);
    });
  }
}

// 插件
jQuery.prototype.dialog = function(info){
	console.log(info);
}

// 拓展性
class myjQuery extends jQuery{
	constructor(selector){
		super(selector)
	}
	// 擴展自己的方法
	addClass(className){}
	addStyle(data){}
}

5. 作用域與閉包

這篇博文寫的很詳細,推薦閱讀
【JS】你不知道的JavaScript 筆記(一)—— 作用域與閉包 - 編譯原理 - LHS - RHS - 回圈與閉包 - 模塊 - 詞法作用域 - 動態作用域

【JS】函式定義與呼叫方式-函式this指向問題-call-apply-bind方法使用與自定義

【JS】你不知道的JavaScript筆記(二)- this - 四種系結規則 - 系結優先級 - 系結例外 - 箭頭函式

5.1 作用域

一個變數合法的使用范圍,JS中采用的是詞法作用域(靜態作用域)
【變數的查找,取決于在哪里定義,而不是在哪里執行】

全域作用域 - 函式作用域 - 塊級作用域

自由變數:一個變數在當前作用域沒有定義,但是被使用了,這時就向上級作用域一層一層依次查找,直到找到為止,最后在全域作用域都沒找到就報錯 ReferenceError:xxx is not defiend

5.2 this不同場景下如何取值

this查找采用的是動態作用域
【this的指向,取決于在哪里執行,而不是在哪里定義】

例題

const User = {
	count: 1,
	getCount: function() {
		return this.count
	}
}
console.log(User.getCount()) // 1
const func = User.getCount
console.log( func() ) // undefined

【JS】你不知道的JavaScript筆記(二)- this - 四種系結規則 - 系結優先級 - 系結例外 - 箭頭函式

5.3 手寫bind

【JS】函式定義與呼叫方式-函式this指向問題-call-apply-bind方法使用與自定義

Function.prototype.myBind = function() {
	// 將引數拆解為陣列
	const args = Array.prototype.slice.call(arguments)  
	// 獲取this
	const t = args.shift()
	// fn1.bind(...)中的 fn1
	const self = this
	return function() {
		return self.apply(t, args)
	}
}

使用

function fn1(a, b, c) {
	console.log('this', this)
	console.log(a, b, c)
	return 'this is fn1'
}
const fn2 = fn1.myBind({x: 100}, 10, 20, 30)
const result = fn2() 
console.log(result)

在這里插入圖片描述

5.4 閉包

當函式可以記住并訪問所在的詞法作用域,即使函式是在當前詞法作用域之外執行,這時就產生了閉包

① 函式作為引數被傳遞 ② 函式作為回傳值被回傳

【JS】你不知道的JavaScript 筆記(一)—— 作用域與閉包 - 編譯原理 - LHS - RHS - 回圈與閉包 - 模塊 - 詞法作用域 - 動態作用域

5.5 閉包的應用場景

隱藏資料,只提供API

function createCache() {
	const data = {}  // 閉包中的資料被隱藏,不被外界訪問
	return {
		set: function(key, value) {
			data[key] = value
		},
		get: function(key){
			return data[key]
		}
	}
}

const cache = createCache()
c.set('a', 100)
console.log(c.get('a'))

6. ES6新特性

【ES6】變數宣告-var-let-const-區別與聯系-總結

【ES6】Symbol基本使用及常用內置符號

【ES6】JavaScript函式-箭頭函式-this指向-簡寫

【ES6】JavaScript-變數的解構賦值-陣列解構-物件解構-物件的屬性-物件的方法

【ES6】JavaScript物件-增強的物件語法-屬性值簡寫-可計算屬性-簡寫方法名

【ES6】JavaScript函式-引數的默認值-與解構賦值的結合使用-對arguments的影響-默認引數作用域與暫時性死區

【ES6】JavaScript陣列-陣列的創建-建構式-字面量-Array.from()-Array.of()靜態方法

【ES6】JavaScript陣列-迭代器方法-keys()-values()-entries()-迭代方法-every()-some()-filter()-map()-forEach()

【ES6】JavaScript面向物件-面向物件與面向程序的對比-類class-繼承extends-建構式-super

【ES6】迭代器與生成器

【Promise】入門-同步回呼-異步回呼-JS中的例外error處理-Promis的理解和使用-基本使用-鏈式呼叫-七個關鍵問題

【ES8】異步代碼終極解決方案 async 和 await

【ES6模塊化】import - export - 按需引入 - 專案中使用babel - ES6模塊化引入npm包

7. 異步相關

因為單執行緒,所以異步【同步會阻塞代碼執行】

JS單執行緒, 和DOM渲染共用一個執行緒【因為JS可以修改DOM結構】
瀏覽器和node.js已經支持JavaScript啟動行程,如 Web Worker

7.1 同步與異步的區別

【JavaScript】同步與異步-異步與并行-異步運行機制-為什么要異步編程-異步與回呼-回呼地獄-JavaScript中的異步操作

7.2 前端使用異步的場景

網路請求,如ajax
定時任務

7.3 Promise的三種狀態

  1. pending 等待中 不會觸發thencatch
  2. resolved 成功了 會觸發后續的then回呼函式
  3. rejected 失敗了 會觸發后續的catch回呼函式

then正常回傳 resolved,里面有報錯則回傳 rejected
catch正常回傳 resolved,里面有報錯則回傳 rejected

【Promise】入門-同步回呼-異步回呼-JS中的例外error處理-Promis的理解和使用-基本使用-鏈式呼叫-七個關鍵問題

7.4 promise的then和catch

Promise.resolve().then(()=>{
	console.log(1) // 執行
}).catch(()=>{
	console.log(2) // 不執行
}).then(()=>{
	console.log(3) // 執行
})
Promise.resolve().then(()=>{
	console.log(1) // 執行
	throw new Error('err1')
}).catch(()=>{
	console.log(2) // 執行
}).then(()=>{
	console.log(3) // 執行
})
Promise.resolve().then(()=>{
	console.log(1) // 執行
	throw new Error('err1')
}).catch(()=>{
	console.log(2) // 執行
}).catch(()=>{
	console.log(3) // 不執行
})

7.5 手寫promise加載圖片

function loadImg(src){
	return new Promise((resolve, reject)=>{
		const img = document.createElement('img')
		img.onload = () =>{
			resolve(img)
		}
		img.onerror = () => {
			reject(new Error(`圖片加載失敗 ${src}`))
		}
		img.src = src
	})
}

// 使用
const url = ''
loadImg(url).then(img => {
	console.log(img.width)
	return img
}).then(img => {
	console.log(img.height)
}.catch(err => console.error(err))

// 使用加載多張圖片
url1 = ''
url2 = ''
loadImg(url1).then(img1 => {
	console.log(img1.width)
	return img1
}).then(img1 => {
	console.log(img1.height)
	return loadImg(url2)	
}).then(img2 => {
	console.log(img2.width)
	return img2
}).then(img2 => {
	console.log(img2.height)
}).catch(err => console.error(err))

7.6 async/await與Promise

  1. 執行async函式,回傳的是Promise物件
  2. await相當于Promise的then
  3. try/catch可以捕獲例外,代替了Promise的catch

【ES8】異步代碼終極解決方案 async 和 await

7.7 位元組面試看代碼題

async function async1() { // 函式定義
  console.log("async1 start"); // 2
  await async2(); // 函式執行
  // await后面的內容,可以看作是回呼里的內容,即異步執行
  console.log("async1 end"); // 6
}

async function async2() { // 函式定義
  console.log("async2"); // 3
}

console.log("script start"); // 1
async1(); // 函式執行

new Promise((resolve)=>{
	console.log('promise1'); // 4
	resolve();
}).then(()=>{
	console.log('promise2'); // 7
})

console.log("script end"); // 5 同步代碼執行完畢

7.8 for-of 的應用場景 【異步】

for、forEach、for-in 是常規的【同步】遍歷
for-of常用于【異步】的遍歷

function muti(num) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(num * num);
    }, 1000);
  });
}

const nums = [1, 2, 3];

nums.forEach(async (i) => {
  const res = await muti(i);
  console.log(res); // 會同時列印出三個結果
});

(async function () {
  for (let i of nums) {
    const res = await muti(i);
    console.log(res); // 會每隔一秒列印出一個結果
  }
})();

8. Event Loop

8.1 宏任務macroTask與微任務microTask

  • 宏任務:setTimeout、setInterval、Ajax、DOM事件【W3C規范】
  • 微任務:Promise、async/await【ES規范】

微任務執行時機比宏任務早


  • 微任務在DOM渲染觸發 【Promise】
  • 宏任務在DOM渲染觸發 【setTimeout】

8.2 Event Loop機制

  • 回呼堆疊 Call Stack
  • 事件回圈 event loop
  • 回呼佇列 Callback Queue
  • 微任務佇列 micro task queue
    在這里插入圖片描述
  1. 同步代碼,一行一行放在回呼堆疊中執行,執行完了就出堆疊
  2. 遇到異步,記錄下來,等待時機;時機到了,就移動到回呼佇列中
  3. 當回呼堆疊為空,(微任務[微任務佇列])【嘗試DOM渲染】 事件回圈開始作業:輪詢查找(宏任務)回呼佇列,有則移動到回呼堆疊中執行
  4. 繼續輪詢loop

【同步任務——微任務——DOM渲染——宏任務】——同步任務——微任務——DOM渲染——宏任務…


實際上真正的 event loop 是這樣的

  1. 一開始整個腳本作為一個宏任務執行
  2. 執行程序中同步代碼直接執行,宏任務進入宏任務佇列,微任務進入微任務佇列
  3. 當前宏任務執行完出隊,檢查微任務串列,有則依次執行,直到全部執行完
  4. 執行瀏覽器UI執行緒的渲染作業
  5. 檢查是否有Web Worker任務,有則執行
  6. 執行完本輪的宏任務,回到2,依此回圈,直到宏任務和微任務佇列都為空

所以程序是

【宏任務(代碼整體)——同步任務——微任務——DOM渲染】——宏任務——同步任務——微任務——DOM渲染…

8.3 event loop練習

console.log('1'); // ①同步任務 

setTimeout(function() { // ① 宏任務
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})

process.nextTick(function() { // ① 微任務
    console.log('6');
})

new Promise(function(resolve) {
    console.log('7'); // ① 同步任務 
    resolve();
}).then(function() { // ① 微任務
    console.log('8')
})

setTimeout(function() { // ① 宏任務
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
    
    console.log('13');
    
    process.nextTick(function() {
        console.log('14'); // 微任務 process.nextTick 比 promse.then優先級要高
    })
})

1 7 6 8 2 4 3 5 9 11 13 10 14 12

9. DOM

9.1 獲取節點操作

document.getElementById('yk') // 元素
document.getElementsByTagName('div') // 集合

document.getElementsByClassName('container') // 集合
document.querySelectorAll('p') // 集合

9.2 標簽屬性 attribute

修改的是標簽屬性【行內樣式】
修改html屬性,會改變html結構

const pList = document.querySelectorAll('p')
const p = pList[0]

p.getAttribute('data-name')
p.setAttribute('data-name','ykjun')
p.getAttribute('style')
p.setAttribute('style', 'font-size: 10px')

9.3 物件屬性 property

用JS的屬性操作DOM元素
修改物件屬性,不會 體現到html結構中

const pList = document.querySelectorAll('p')
const p = pList[0]
console.log(p.style.width) // 獲取樣式
p.style.width = '100px' // 修改樣式

console.log(p.className) // 獲取class
p.className = 'p1' // 修改class

console.log(p.nodeName) // 獲取nodeName節點名稱
console.log(p.nodeType) // 獲取nodeType節點型別

9.4 DOM結構操作

const div1 = document.getElementById('div1')
const div2 = document.getElementById('div2')

// 新建節點
const newP = document.createElement('p')
newP.innerHTML = 'this is new p'

// 插入節點
div1.appendChild(newP)

// 移動節點
const p1 = document.getElementsByTagName('p')[0]
div2.appendChild(p1)

// 獲取父元素
console.log(p1.parentNode)

// 獲取子元素串列
const div1ChildNodes = div1.childNodes
console.log('div1ChildNodes', div1ChildNodes)

const div1ChildNodesP = Array.from(div1ChildNodes).filter(child => {
	if(child.nodeType === 1) {
		return true;
	}
	return false;
}
console.log('div1ChildNodesP', div1ChildNodesP)

// 洗掉節點
div1.removeChild(div1ChildNodesP[0])

9.5 優化DOM性能

9.5.1 對DOM查詢進行快取

不使用快取DOM查詢結果

for(let i = 0; i < document.getELementsByTagName('p').length; i++){
	//	每次回圈都會計算length,頻繁進行DOM查詢
}

快取DOM查詢結果

const pList = document.getELementsByTagName('p')
const length = pList.length
for(let i = 0; i < length; i++){
	// 快取length, 只進行一次DOM查詢
}

9.5.2 將頻繁操作改為一次性操作

const listNode = document.getElementById('list')
// 創建一個檔案片段,此時還沒有插入到DOM樹中
const frag = document.createDocumentFragment()
// 執行插入操作
for(let i = 0; i < 10; i++){
	const li = document.createElement('li')
	li.innerHTML = "Iist Item " + i
	frag.appendChild(li)
}
// 都完成后,再插入DOM樹中
listNode.appendChild(frag)

10. BOM

  • navigator
  • screen
  • location
  • history

【BOM】JavaScript-定時器-執行機制-location-navigator-history

10.1 檢查瀏覽器型別

const ua = navigator.userAgent
const isChorme = ua.indexOf('Chrome')
console.log(isChorme)

10.2 拆解URL各個部分

location
在這里插入圖片描述

11. 事件

【DOM】JavaScript-事件高級-注冊事件-事件流-事件物件-事件冒泡-委派-滑鼠鍵盤事件

11.1 事件系結、冒泡、代理

const btn = document.getElementById('btn1')
btn.addEventListener('click', event => {
	console.log('clicked')
})

11.2 寫一個通用的事件系結函式

function bindEvent(elem, type, fn){
	elem.addEventListener(type, fn)
}

const btn1 = document.getELementById('btn1')
bindEvent(btn1,  'click', event => {
	console.log(event.target) // 獲取觸發的元素
	event.preventDefault() // 阻止默認行為
	alert('clicked')
})

升級版【支持代理】

function bindEvent(elem, type, selector, fn){
	if(fn == null){
		fn = selector
		selector = null
	}
	elem.addEventListener(type, event => {
		if(selector){
			// 代理系結 
			if (target.matches(selector)){
				fn.call(target, event)
			}
		}else {
			// 普通系結
			fn.call(target, event)
		}
	})
}


// 普通系結
const btn1 = document.getELementById('btn1')
bindEvent(btn1, 'click', function(event) {
	console.log(event.target) // 獲取觸發的元素
	event.preventDefault() // 阻止默認行為
	alert(this.innerHTML)
})

// 代理系結 [在a父節點div上系結事件]
const div3 = document.getElementById('div3')
bindEvent(div3, 'click', 'a', function(event) {
	event.preventDefault()
	alert(this.innerHTML)
})

11.3 描述事件冒泡程序

  • 基于DOM樹形結構
  • 事件會順著觸發元素往上冒泡
  • 應用場景:事件代理

11.4 無限下拉的圖片串列,如何監聽每個圖片的點擊

  • 事件代理
  • event.target獲取觸發元素
  • matches來判斷是否是觸發元素

12. AJAX

【Ajax】HTTP相關問題-GET-POST-XHR使用-jQuery中的ajax-跨域-同源-jsonp-cors

【axios】使用json-server 搭建REST API - 使用axios - 自定義axios - 取消請求 - 攔截器

12.1 手寫一個簡單的ajax

function ajax(url) {
	const p = 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(null)
	})
	return p
}

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

12.2 跨域解決方案

瀏覽器中加載圖片、css、js可以無視同源策略

  • <img /> 可用于統計打點,可使用第三方服務
  • <link /> <script> 可以使用CDN
  • <script> 可以實作JSONP

所有跨域,都必須經過server端允許和配合
未經server允許就實作跨域,說明瀏覽器有漏洞

  • JSONP
  • CORS
  • 代理

【Ajax】HTTP相關問題-GET-POST-XHR使用-jQuery中的ajax-跨域-同源-jsonp-cors

13. 瀏覽器存盤

【瀏覽器】瀏覽器存盤&快取 - Cookie - localStorage - sessionStorage - IndexDB - Cache Storage - Application Cache

cookie

  • 本身用于瀏覽器和服務器通訊
  • 存盤大小最大4KB
  • http請求時需要發送到服務端,增加請求資料量
  • 是能用document.cookie='...'來修改,太過簡陋

localStorage 和 sessionStorage

  • HTML5專門為存盤設計,最大可存5M
  • API簡單易用 setItem getItem
  • 不會隨著HTTP請求被發出去

14. 頁面加載

14.1 資源的形式

  • HTML代碼
  • 媒體檔案,如圖片、視頻
  • JavaScript代碼 css代碼

14.2 從輸入url到渲染出頁面的整個程序

① 獲取資源
DNS域名決議:域名——> IP地址
TCP三次握手建立連接
瀏覽器根據IP地址向服務器發起HTTP請求
服務器處理HTTP請求,并資源回傳給瀏覽器

② 渲染頁面
瀏覽器根據HTML代碼生成DOM Tree
根據CSS代碼生成 CSSOM
將DOM Tree 和 CSSOM 整合成 渲染樹 Render Tree
根據Render Tree 渲染頁面
遇到 scrpit 標簽 則暫停渲染,優先加載并執行JS代碼,完成再繼續
直至把Render Tree 渲染完成

14.3 window.onload與DOMContentLoaded的區別

window.onload 資源全部加載完成才能執行,包括圖片
DOMContentLoaded DOM渲染完成即可,圖片可能尚未下載

const img1 = document.getElementById('img1')
img1.onload = function() {
	console.log('img loaded') // 2 
}
window.addEventListener('load', function() {
	console.log('window loaded') // 3
})
document.addEventListener('DOMContentLoaded', function() {
	console.log('dom content loaded') // 1
})

15. 性能優化

15.1 前端常見性能優化方案

  1. 思路
  • 多使用記憶體、快取或其他方法
  • 減少CPU計算量,減少網路加載耗時
  • 空間換時間
  1. 加載優化
  • 減少資源體積:壓縮代碼
  • 減少訪問次數:合并代碼,SSR服務端渲染、快取
  • 使用更快的網路:CDN
  1. 渲染優化
  • CSS放在head,JS放在body最下面
  • 盡早開始執行JS,用DOMContentLoaded觸發
  • 懶加載
  • 對DOM查詢進行快取
  • 頻繁DOM操作,合并到一起插入DOM結構
  • 節流與防抖

15.2 快取

靜態資源加hash后綴,根據檔案內容計算hash
檔案內容不變,則hash不變,則url不變
url和檔案不變,就會自動觸發HTTP快取機制,回傳304

網路方面的快取分為三塊:DNS快取、HTTP快取、CDN快取, HTTP 快取也稱為瀏覽器快取

(建議收藏)為什么第二次打開頁面快?五步吃透前端快取,讓頁面飛起

15.3 SSR服務渲染

將網頁和資料一起加載,一起渲染
非SSR(前后端分離):先加載網頁,再加載資料(ajax),再渲染資料

15.4 圖片懶加載

先給一個小的預覽圖,判斷到用戶訪問到當前位置,再加載高清

<img id="img1" src="preview.png" data-realsrc="real.png" />
<script>
	let img1 = document.getElementById('img1')
	img1.src = img1.getAttribute('data-realsrc')
<script>

15.5 節流與防抖

【JS】函式節流與函式防抖-自定義JS工具類

16. 前端安全

16.1 XSS 跨站請求攻擊

前端安全系列(一):如何防止XSS攻擊?

16.2 XSRF 跨站請求偽造

前端安全系列之二:如何防止CSRF攻擊?

17. 演算法刷題

【演算法】經典排序演算法總結-JavaScript描述-圖解-復雜度分析

【LeetCode】經典題分類(數學 - 陣列 - 字串)精選 - JavaScript - ES6 - 技巧總結

【LeetCode】經典題分類(鏈表 )精選 - JavaScript - ES6 - 技巧總結

【LeetCode】經典題分類(樹&圖 )精選 - JavaScript - ES6 - 技巧總結

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/293188.html

標籤:其他

上一篇:JavaScript利用charAt()統計出現次數最多的字符和次數

下一篇:TypeScript技術(三)基礎型別學習!!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more