日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JS高级课堂笔记

發布時間:2023/12/16 javascript 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JS高级课堂笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JS高級課堂筆記

    • 數據的特點
    • 問題:`var a = xxx;`,a 內存中到底保存的是什么?
    • 關于引用變量的賦值問題
    • 問題:在 js 調用函數時傳遞變量參數時,是值傳遞還是引用傳遞?
    • 問題:js引擎如何管理內存?
    • 為什么要用對象?
    • 對象的組成:
    • 什么是函數?
    • 為什么要使用函數?
    • 如何調用(執行)函數?
    • 代碼風格:是否加分號
    • 什么叫隔離變量?
    • 作用域和執行上下文的區別
    • 函數執行完后,函數內部聲明的局部變量是否還存在?
    • 在函數外部能直接訪問函數內部的局部變量嗎?
    • 內存溢出與內存泄露
    • 閉包使用場景:
    • 節流的使用場景:
    • 防抖的使用場景:
    • try{}catch(error){} 所對應的error
    • 對象拓展 Object.is()
    • 創建數組的四種方式
    • for 循環用于遍歷數組
    • 解構賦值
    • 怎樣優化網頁性能?
    • 自己實現性能測試(只供參考,不能作為參考標準)
    • 一個 6~16位的字符串,必須同時包含有大小寫字母和數字。
    • 1-10為必須包含數字、字母、下劃線。必須以下劃線開頭。
    • 如何改變 this 指向
    • Promise 的缺點是什么
    • localStorage 的使用場景
    • cookie的使用場景
    • 請求體參數有兩種編碼形式:content-type
    • xhr 和 fetch的區別
    • axios發送請求
    • slice, substr 和 substring 的區別
    • 請求攔截器和響應攔截器
    • 總結 this 指向(熊鍵)
    • 談一談閉包(熊鍵)
    • 談一談跨域(熊健)
    • 談談 js 異步代碼執行機制(熊鍵)
    • 什么是埋點?
    • includes與indexOf()的區別
    • 高效學習三部曲(適用于任何行業):找準知識體系,刻意練習,及時反饋。
    • 圖片底部空白問題
    • 元素的顯示與隱藏:
    • 瀏覽器輸入 URL 按下 enter 發生了什么
    • 比較
    • 對象里面的屬性是否可以為數字?
    • 對象的屬性名不能是一個對象
    • Map 結構
    • new 做了什么?
    • == 比較
    • 變量計算-類型轉換
    • form 表單怎么阻止重復提交?
    • 懶加載大量數據的時候加載不出來的情況怎么優化?
    • js 的垃圾回收機制。
    • 說說什么情況會造成內存泄露?
    • TAPD跟禪道:工作中的 bug 處理。
    • 關于axios
    • JSON對象的方法:
    • yarn 基本指令
    • 其他
      • 1. 原型鏈:查找變量的過程。由多級父對象,逐級繼承,形成的鏈式結果。
      • 2. alert 彈出來的結果都會進行內部 toString 轉換,輸出為字符串。
      • 3. 枚舉、迭代、遍歷。
      • 4. 無論客戶關閉了瀏覽器還是電腦,只要還在 `maxAge`秒之前,登錄網站時該 Cookie 仍然有效。
      • 5. 代理(proxy):就是通過一個對象來操作另一個對象。
      • 6. 所有對象都是實例對象。都是 new 某個東西產生的。
      • 7. react 中使用 ``如果你指定了 button 的 type 屬性,要么不指定,要么指定 submit,不要指定為`type = ‘button’`。
      • 8. property 和 attribute
      • 9. 瀏覽器內核:支撐瀏覽器運行的最核心的程序。
      • 10. 注意:三元運算符中不能寫 return。
      • 11. 所有的字符串的方法都是返回一個新的字符串。
      • 12. this += n 也就是 this = this + n; 這樣會報錯的,this 不能像變量一樣賦值的。
      • 13. 如 `n = Number(n) && (isNaN(n) ? 0 : n);` n = Number(n) 賦值這個操作,永遠都為 true。

數據的特點

  • 可傳遞。var a = 3; var b = a;
  • 可運算。var a = 3; var b = a + 2;
  • 問題:var a = xxx;,a 內存中到底保存的是什么?

  • xxx是基本數據,保存的就是這個數據。
  • xxx是對象,保存的是對象的地址值。
  • xxx是一個變量,保存的xxx的內存內容(可能是基本數據,也可能是地址值)。
  • 關于引用變量的賦值問題

    • 兩個或多個引用變量指向同一個對象,通過一個變量修改對象內部數據,其他所有變量看到的是修改之后的數據。
    • 兩個或多個引用變量指向同一個對象,讓其中一個引用變量指向另一個對象,另一個引用變量依然指向前一個對象。
    var obj1 = {name: 'Tom'}; var obj2 = obj1; obj1.name = 'Jack'; console.log(obj2.name); // 'Jack' var obj1 = {name: 'Tom'}; var obj2 = obj1; obj2.age = 12; console.log(obj1.age); // 12 function fn(obj) {obj.name = 'A'; } fn(obj1); console.log(obj2.name); // 'A' var a = {age: 12}; var b = a; a = {name: 'Bob', age: 13}; console.log(b.age, a.name, a.age); // 12 'Bob' 13 var a = {age: 12}; var b = a; a = {name: 'Bob', age: 13}; b.age = 14; console.log(b.age, a.name, a.age); // 14 'Bob' 13 function fn2 (obj) {obj = {age: 15}; // 注意:這里是obj 等于一個新對象,而不是obj.age,這個一個對象會成為垃圾對象。 } fn2(a); console.log(a.age); // 13

    問題:在 js 調用函數時傳遞變量參數時,是值傳遞還是引用傳遞?

    理解一:都是值(基本值/地址值)傳遞。

    理解二:可能是值傳遞,也可能是引用傳遞(地址值)。

    var a = 3; function fn(a) {a = a + 1; }; fn(a); console.log(a); // 3

    問題:js引擎如何管理內存?

  • 內存生命周期:

    • 分配小內存空間,得到它的使用權。
    • 存儲數據,可以反復進行操作。
    • 釋放當前的小內存空間。
  • 釋放內存:

    • 局部變量:函數執行完自動釋放。
    • 對象:稱為垃圾對象→垃圾回收機制回收。
  • 什么是對象?

  • 多個數據的封裝體。
  • 用來保存多個數據的容器。
  • 一個對象代表現實世界中的一個事物。
  • 為什么要用對象?

    統一管理多個數據。

    對象的組成:

  • 屬性:屬性名(本質上都是字符串)和屬性值(任意類型)。
  • 方法:一個特別的屬性(屬性值是函數)。
  • 什么是函數?

  • 實現特定功能的 n 條語句的封裝體。
  • 只有函數是可以執行的,其他類型的數據不能執行。
  • 為什么要使用函數?

  • 提高代碼復用。
  • 便于閱讀交流。
  • 如何調用(執行)函數?

  • test():直接調用。
  • obj.test():通過對象調用。
  • new test():new 調用。
  • test.call/apply(obj):臨時 讓 test 成為 obj 的方法進行調用。
  • var obj = {}; function test2 () {this.xxx = 'baidu'; }; test2.call(obj); console.log(o);

    代碼風格:是否加分號

    是否加分號是編碼風格問題,沒有應不應該,只有自己喜歡不喜歡。

    在下面2中情況下不加分號會有問題:

  • 小括號開頭的前一條語句。

    var a = 3 ;(function () {}) // 不加分號報錯:var a = 3(function () {})
  • 中方括號開頭的前一條語句。

    var b = 4 ;[1, 3].forEach(function () {}) // 報錯的理解:var b = 4[1, 3].forEach(function () {})

    解決辦法:在行首加分號

  • 讀取對象的屬性值時:會自動到原型鏈中查找。

    設置對象的屬性值時:不會查找原型鏈,如果當前對象中沒有此屬性,直接添加此屬性并設置其值。

    方法一般定義在原型中,屬性一般通過構造函數定義在對象本身上。

    function Fn () {} Fn.prototype.a = 'xxx'; var fn1 = new Fn(); console.log(fn1.a, fn1);var fn2 = new Fn(); fn2.a = 'yyy'; console.log(fn1.a, fn2.a, fn2);
  • 原型鏈測試題1:

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-M61GBCQd-1663432794797)(js高級課堂筆記 .assets/無標題.png)]

    function A () {}A.prototype.n = 1;var b = new A();A.prototype = {n: 2,m: 3};var c = new A();console.log(b.n, b.m, c.n, c.m)// 1 undefined 2 3

    原型鏈測試題2:

    var F = function () {Object.prototype.a = function () {console.log('a()')}Function.prototype.b = function(){console.log('b()')}}var f = new F()f.a()f.b()F.a()F.b()
  • 什么叫隔離變量?

    隔離變量:不同作用域下同名變量不會被沖突。

    作用域和執行上下文的區別

    作用域是靜態的,只要函數定義好了就一直存在,且不會再改變。

    執行上下文是動態的,調用函數時創建,函數調用結束時會自動釋放。

    函數執行完后,函數內部聲明的局部變量是否還存在?

    一般是不存在,存在于閉包中的變量才可能存在。

    在函數外部能直接訪問函數內部的局部變量嗎?

    不能,但我們可以通過閉包讓外部操作它。

    內存溢出與內存泄露

    內存溢出:

  • 一種程序運行出現的錯誤。
  • 當程序運行需要的內存超過了剩余的內存時,就會拋出內存溢出的錯誤。
  • 內存泄露:

  • 占用的內存沒有及時釋放。
  • 內存泄露積累多了就容易導致內存溢出。
  • 常見的內存泄露:
    • 意外的全局變量。
    • 沒有及時清理的計時器或回調函數。
    • 閉包
  • 閉包使用場景:

  • 刪除某一條數據,通過 ID 或 index 去刪除的時候,會使用到閉包。
  • 發送 Ajax 請求成功或失敗的回調。
  • setTimeout 的延時回調。
  • 節流的使用場景:

  • 滾動加載更多。
  • 搜索框搜索的聯想功能。
  • 高頻點擊。
  • 表單重復提交。
  • 防抖的使用場景:

  • 搜索框搜索輸入,并在輸入完以后自動搜索。
  • 手機號,郵箱驗證輸入檢測。
  • 窗口大小 resize 變化后,再重新渲染。
  • try{}catch(error){} 所對應的error

    Error.name 的六種值對應的信息:

  • EvalError:eval() 的使用與定義不一致。
  • RangeError:數值越界。
  • ReferenceError:非法或不能識別的引用數值(如:變量未聲明就使用; 函數未聲明就調用)。
  • SyntaxError:發生語法解析錯誤。
  • TypeError:操作數類型錯誤(如:數組方法操作對象)。
  • URIError:URI處理函數使用不當。
  • 對象拓展 Object.is()

    全等判斷有兩個問題:

  • 0 和 -0 在進行全等判斷的時候,得到的是 true。
  • NaN 和 NaN 在進行全等判斷的時候,得到的是 false。
  • console.log(0 === -0); // true console.log(NaN === NaN); // false

    對象拓展 is 方法:

  • 0 和 -0 在進行全等判斷的時候,得到的是 false。
  • NaN 和 NaN 在進行全等判斷的時候,得到的是 true。
  • console.log(Object.is(0, -0)); // false console.log(Object.is(NaN, NaN)); // true

    除此之外,is 方法 和 === 是一樣的。

    創建數組的四種方式

  • 字面量 []
  • 構造函數 new Array()
  • 工廠方法 Array();
  • Array.of()
  • for 循環用于遍歷數組

    for in 循環用于遍歷對象的key

    for of 循環遍歷實現了迭代器接口的對象(不能直接遍歷對象)

    迭代器接口對象一旦遍歷完成,就無法再遍歷了。

    解構賦值

    解構賦值,解構出來的數據會創建全局變量,因此工作中,常常配合模塊化開發去使用(這時相當于局部變量了)。

    數組依賴的是索引,對象依賴的是屬性名。

    解構語法不會影響原來的數組。

    怎樣優化網頁性能?

  • 盡量減少 HTTP 請求次數
  • 減少 DNS 查找次數
  • 資源合并與壓縮
  • CSS Sprites
  • 小圖標使用字體圖標或者base64
  • 將外部腳本置底
  • 緩存
  • 自己實現性能測試(只供參考,不能作為參考標準)

  • 任何的代碼性能測試都是和測試的環境有關系的,例如CUP、內存、GPU等電腦當前性能不會有相同的情況。

  • 不同瀏覽器也會導致性能上的不同。

  • 測試A所用的時間 // console.time 可以測試出一段程序執行的時間 console.time('A'); // 括號里不寫東西,控制臺上什么也不會出現 for (let i = 0; i < 10000; i++) {} console.timeEnd('A'); // 打印開始的A到結束的A所用的時間
  • console.profile() 在火狐瀏覽器中安裝FireBug,可以更精準的獲取到程序每一個步驟所消耗的時間。

  • 一個 6~16位的字符串,必須同時包含有大小寫字母和數字。

    編寫一條正則,用來驗證此規則:一個 6~16位的字符串,必須同時包含有大小寫字母和數字。(一般用于密碼)

    // 問號(?): 0次或1次let reg = /^(?![a-zA-Z]+$)(?![a-z0-9]+$)(?![A-Z0-9]+$)[a-zA-Z0-9]{6,10}$/;console.log(reg.test('aaabbb')); // falseconsole.log(reg.test('111aaa')); // falseconsole.log(reg.test('111AAA')); // falseconsole.log(reg.test('111aaaBBB')); // true

    1-10為必須包含數字、字母、下劃線。必須以下劃線開頭。

    let reg = ^/(?=_)\w{1,10}$/; console.log(reg.test('_aaabbb2_')); // true console.log(reg.test('111aaa')); // false console.log(reg.test('_3')); // true

    如何改變 this 指向

    • 使用 ES6 的箭頭函數。

      箭頭函數沒有 this,所以也不能用 call()、apply()、bind() 方法改變 this 的指向。

      需要通過查找作用域鏈來確定 this 的值,如果箭頭函數被非箭頭函數包含,this 綁定的就是最近一層非箭頭函數的 this。

    • 在函數內部使用 _this = this。

      先將調用這個函數的對象保存在變量 _this 中,然后在函數中都使用這個 _this

    • 使用 call、apply、bind。

    • new 實例化一個對象。

      用 new 調用函數,改變指向 new 的實例對象。

    Promise 的缺點是什么

  • promise 一旦新建就會立即執行,無法中途取消。
  • 當處于 pending 狀態時,無法得知當前處于哪一個狀態,是剛剛開始還是剛剛結束。
  • 如果不設置回調函數,promise 內部的錯誤就無法反映到外部。
  • promise 封裝 ajax 時,由于 promise 是異步任務,發送請求的三步會被延后到整個腳本同步代碼執行完,并且將響應回調函數延遲到現有隊列的最后,如果大量使用會大大降低了請求效率。
  • localStorage 的使用場景

  • 緩存一般信息,如搜索頁的出發城市,達到城市,非實時定位的信息。
  • 緩存城市列表數據,這個數據往往比較大。
  • 每條緩存信息需要可跟蹤,比如服務器通知城市數據更新,這個時候在最近一次訪問的時候要自動設置過期。
  • localStorage 常用于長期登錄+判斷用戶是否已經登錄。
  • cookie的使用場景

    cookie 一般要配合 session一起使用,session 的使用場景:

  • 商城中的購物車。
  • 保存用戶登錄信息。
  • 將某些數據放入 session 中,供同一用戶的不同頁面使用。
  • 方式在用戶非法登錄。
  • 請求體參數有兩種編碼形式:content-type

  • urlencoded

    概念:

    • urlencoded 格式,又叫 form 格式、x-www-form-urlencoded 格式。
    • 它是一種表單格式

    組成格式:

    • 鍵值對組成
    • 鍵和值之間用 = :name=poloyy
    • 多個鍵值對之間用 & :name=poloyy&age=19

    實際例子:

    瀏覽器百度搜索:baidu.com/s?ie=UTF-8&wd=baidu

  • JSON:這個 JSON 太厲害了,看詳解。

    {"name" :"polo","age":35,"smoke":false }

    詳解鏈接

  • xhr 和 fetch的區別

    xhr 和 fetch 都是 window 身上的方法,Ajax 請求只在瀏覽器端發送,服務器端不行(服務器端,沒頁面,也沒有 window)。服務器端可以發 HTTP 請求。而 axios 可以滿足瀏覽器端和服務器端都可以發送 Ajax 請求。

    fetch發送網絡請求

    axios發送請求

    axios 完整版:

    btn1.onclick = () = {axios({method: 'GET',url: 'http://localhost:3000/get_persons',}).then(response => console.log(response.data),error => console.log(error)) }

    axios 精簡版:

    btn1.onclick = () = {axios.get('http://localhost:3000/get_persons').then(response => console.log(response.data),error => console.log(error)) }

    slice, substr 和 substring 的區別

    首先,他們都接收兩個參數,slice和substring接收的是起始位置和結束位置(不包括結束位置),而substr接收的則是起始位置和所要返回的字符串長度。

    解析地址

    請求攔截器和響應攔截器

    請求攔截器:在請求還沒有發出去之前:

  • 把請求攔截住。
  • 根據具體業務邏輯,決定是否放行。
  • 定義:在真正發請求前執行的一個回調函數。

    作用:

  • 對請求的配置做一些處理:data、header,界面 loading 提示。

    界面 loading 提示:在發請求的時候,我可以在請求攔截器里面加載一個頁面,一直加載中,然后等著數據回來的時候,要經過響應攔截器,在響應攔截器中把 loading 取消掉。這樣就可以展示一個比較好的 loading 效果。這樣做有個比較大的優勢就是,我只要寫了一個請求攔截器和一個響應攔截器,在我這個項目里面,只要我敢發請求,以后都走這個請求攔截器和這個響應攔截器,所有請求都加上了 loading 或者 進度條 的效果。

  • 對請求進行檢查,根據具體的條件決定是否真正發送請求。

  • 多個請求攔截器(axios.interceptors.request.use()):后指定的攔截器先工作,先指定的攔截器后工作。實際工作中,一般只會配置一個請求攔截器。

    多個響應攔截器(axios.interceptors.response.use()):先指定的攔截器先工作,后指定的攔截器后工作。

    定義:得到響應之后執行的一個回調函數。

    作用:

  • 若請求成功,對成功的數據進行處理。
  • 若請求失敗,對失敗進行進一步操作。
  • 總結 this 指向(熊鍵)

  • 什么是 this?

    • 一個關鍵字,是一個引用變量。
    • 函數中可以出現 this (全局的 this 指向 window)。
    • this 指向其所在函數的調用者,如果沒有調用者則指向 window。
    • this 的指向是在調用函數的時候確定的。
  • this 指向(其實就是看函數的調用方式)。

  • this 默認綁定 (函數默認調用)。

  • 定時器的 this 指向 window。

  • 箭頭函數的 this:箭頭函數沒有自己的 this,箭頭函數內部的 this 并不是調用時候指向的對象,而是定義函數時所在函數的 this 指向。

  • this 指向調用函數的上下文 (函數是上下文調用的)。

  • 注意隱式丟失現象(通過一個上下文對象拿到了一個函數,但是沒有調用,而是賦值給了其他人)。

  • this 指向實例化對象 (函數實例化調用)。

  • 強制綁定:this 指向 call、apply、bind 修改的對象(函數是call、apply、bind調用的)。

  • 談一談閉包(熊鍵)

    什么是閉包:

  • 函數嵌套函數,閉包就是內部嵌套的函數。

  • 閉包就是包含被引用變量的 closure 對象,在嵌套的內部函數中。

  • 產生閉包的情況:

  • 函數嵌套。

  • 內部函數引用外部函數的變量。

  • 調動外部函數。

  • 閉包的作用:

  • 延長了局部變量的生命周期。

  • 可以在外部操作局部變量。

  • 閉包的缺點:

  • 函數的局部變量占用內存時間過長,容易造成內存泄露。

  • 解決:

  • 減少使用閉包。
  • 及時釋放閉包。
  • 談一談跨域(熊健)

    同源:協議名、域名、端口號一致。

    跨域:給不同源的地址發送 Ajax 請求。

    解決跨域問題:

  • jsonp 原理: 就是利用 script 標簽發送請求不受同源策略的限制,去給服務器發送請求,發送時要將一個定義好的函數名通過 callback=函數名的形式,上傳給服務器。服務器會響應函數的調用。具體要響應給瀏覽器的數據,就是函數調用時的實參。瀏覽器拿到函數調用的字符串之后,會將這個字符串,放到對應的 script 里面去執行,執行時會自動將引號去掉。直接變成了一段 js 代碼。而這段 js 代碼就是函數調用。所以這時會去全局查找對應的函數。找到了之后就執行這個函數,響應的數據,就直接賦值給形參了。在這個函數體中,就可以操作這個數據了。

    jsonp 的注意點:

  • jsonp 只能發送 get 請求。

  • jsonp 沒有兼容性問題。

  • 要想實現跨域,需要后臺配合。

    后端配合:用 jquery 隨機生成字符串,后臺將數據作為參數包裹在這個隨機字符串函數里作為參數傳遞到前臺。

  • cors(跨域資源共享): IE10 以上的瀏覽器才能使用。在真正發送 ajax 請求之前,瀏覽器會檢查是否同源,如果不同源,會自動先給指定的服務器預請求一下,詢問是否支持 cors,如果服務器響應支持,瀏覽器才會讓我們寫的 ajax 請求發送出去,響應的時候就不再攔截了,如果服務器不支持 cors。瀏覽器就不會將我們的 ajax 發送出去。

    cors 的注意點:

  • IE10+ 才支持(有兼容性問題)。

  • 可以使用 get/post 請求。

  • 依然需要后臺配合。

    后端配合:跨域資源共享(CORS, Cross-Origin Resource Sharing),本質是設置響應頭,使得瀏覽器允許跨域請求。

  • 談談 js 異步代碼執行機制(熊鍵)

  • 同步代碼和異步代碼如何執行?
  • JS 引擎從上到下依次執行所有代碼。
  • 遇到同步代碼,依次執行。
  • 遇到異步代碼,異步函數是會被同步調用,只是其中的異步任務和回調函數會交給瀏覽器相關模塊負責處理。
  • 此時 JS 引擎會繼續執行后面代碼。
  • 比如:定時器函數會被同步調用,里面計時任務和回調函數會交給瀏覽器定時器管理模塊去處理,

    當瀏覽器定時器管理模塊記錄時間到點了,會將回調函數添加回調隊列中,等待執行。

    等 JS 引擎執行完全局所有代碼,才會開啟事件輪詢,輪詢回調隊列,執行其中異步回調函數,默認按照順序依次執行,先進先出。

  • 異步代碼具體誰先執行,誰后執行?
  • 宏任務(執行優先級低):setTimeout、setInterval、DOM 事件回調、Ajax 請求、setImmediate(NODEJS)
  • 微任務(執行優先級高):promise.then/catch/finally、queueMicrotask、requestAnimationFrame
  • 將整個 script 當做一個宏任務執行。

    執行完一個宏任務,先檢查是否有微任務要執行。

    需要所有微任務都執行完,再檢查是否有宏任務要執行。

    執行完一個宏任務,先檢查是否有微任務要執行。

    什么是埋點?

    埋點:是網站分析的一種常用的數據采集方法。如:統計客戶點擊某個按鈕的次數。

    includes與indexOf()的區別

    • indexOf()返回的是數值,而includes()返回的是布爾值
    • indexOf() 不能判斷NaN,返回為-1 ,includes()則可以判斷

    高效學習三部曲(適用于任何行業):找準知識體系,刻意練習,及時反饋。

    圖片底部空白問題

    產生的原因:圖片默認的vertical-align:baseline(基線)。

    解決:

  • 最簡單粗暴也是最有效的方法:img{display:block;}。
  • 給圖片添加 vertical-align: middle | top | bottom 等。(推薦使用)
  • 博客鏈接

    元素的顯示與隱藏:

  • display : none / block; 不占位置。

  • visibility : hidden / visible ; 占位置。

  • overflow : hidden ; 溢出隱藏。

  • 瀏覽器輸入 URL 按下 enter 發生了什么

  • 輸入 URL 并按下 enter。
  • DNS 解析 URL 對應的 IP。
  • 瀏覽器查找當前 URL 是否存在緩存,并比較緩存是否過期。
  • 根據 IP 建立 TCP連接(三次握手)。
  • HTTP 發送請求。
  • 服務器處理請求,瀏覽器接收 HTTP 響應。
  • 渲染頁面,構建 DOM 樹。
  • 關閉 TCP 連接(四次揮手)。
  • 比較

  • 比較
  • [10] == 10; // true [10] === 10; // false // 全等不支持類型轉換

    數據類型比較:

    == 數據類型不一樣

  • 對象 == 字符串 對象.toString()變為字符串。(對象如果變成數字是先 對象.toString() 然后 Number(放剛轉成的字符串))
  • null == undefined 相等。但是和其他值比較就不再相等了。
  • NaN == NaN 不相等。
  • 剩下的都是轉換為數字。如:"1"==true// true
  • 對象里面的屬性是否可以為數字?

    對象里面的屬性是可以為數字的,用中括號來取就可以了:

    var obj = {100: 99}; console.log(obj[100]) // 99

    對象的屬性名不能是一個對象

    對象的屬性名不能是一個對象(遇到對象屬性名,會默認轉換為字符串)

    obj = {} arr = [12, 23] obj[arr] = 'xiaozhu' console.log(obj) // { '12,23': 'xiaozhu' }

    普通對象.toStirng 調取的是Object.prototype 上的方法(這個方法是用來檢測數據類型的):

    obj = {} console.log(obj.toString()) // "[object Object]"

    Map 結構

    不過 es6 中的 map 支持屬性名是任意類型,包括對象,數組等。

    • JavaScript 的對象(Object),本質上是鍵值對的集合(Hash 結構),但是傳統上只能用字符串當作鍵。這給它的使用帶來了很大的限制。
    • 為了解決這個問題,ES6 提供了 Map 數據結構。它類似于對象,也是鍵值對的集合,但是“鍵”的范圍不限于字符串,各種類型的值(包括對象)都可以當作鍵。也就是說,Object 結構提供了“字符串—值”的對應,Map 結構提供了“值—值”的對應,是一種更完善的 Hash 結構實現。如果你需要“鍵值對”的數據結構,Map 比 Object 更合適。
    // 為什么會有Map? 因為對象屬性名稱必須是字符串,如果是其他類型則不行 let p1 = { name: "lily" }; let obj1 = {id: 1,[p1]: "good" } console.log(obj1)// Map也是新增的數據結構 類似于對象 let mp1 = new Map([["a", 1],["b", 2], ]) console.log(mp1)let p2 = { name: "lily" }; let mp2 = new Map([["a", 1],[p2, 2], ]) console.log(mp2)

    new 做了什么?

    構造函數中的 new,是 js 中內置的。

    new 做了什么?

    ? 1. 創建了一個對象

    ? 2. 調用構造函數,并把構造函數的 this 指向了這個對象,這個對象就是當前實例

    ? 3. 對象的隱式原型指向了當前函數的顯式原型(構成原型鏈)

    ? 4. 判斷構造函數的返回值,如果是基本類型,則正常返回實例化對象,如果是對象類型,則返回當前的對象 。

    function _new(Fn, ...arg) {let obj = {};obj.__proto__ = Fn.prototype;Fn.call(obj, ...arg);return obj; } let sanmao = _new(Dog, '三毛'); 注意: let obj = {}; obj.__proto__ = Fn.prototype; 可以改寫為: let obj = Object.create(Fn.prototype);

    == 比較

    == 進行比較的時候,如果左右兩邊數據類型不一樣,則先轉換為相同的數據類型,然后再進行比較,雙等(==)最終得到的是一個布爾值

  • {} == {} 兩個對象進行比較,比較的是堆內存的地址

  • null == undefined 相等的 / null === undefined 不相等

  • NaN == NaN 不相等 NaN 和誰都不相等

  • [12] == “12” 對象和字符串比較,是把對象 toString() 轉換為字符串后,再進行比較

  • 剩余所有情況在進行比較的時候,都是轉換為數字(前提是數據類型不一樣):

    • 對象轉數字:先轉換為字符串,然后在轉換為數字。
    • 字符串轉數字:只要出現一個非數字字符,結果就是 NaN。
    • 布爾轉數字:true 為 1,false 為 0。
    • null 轉數字:0。
    • undefined 轉數字:NaN。
    [] == false var a = Number([].toString()) == false // [].toString()是空字符串, 空數組轉成數字為 0。 console.log(a); // true[12] == true var a = Number([12].toString()) == true console.log(a); // false
  • 變量計算-類型轉換

    下面三種情況容易發生類型轉換:

  • 字符串拼接。

    如:const b = 100 + "10"; const c = true + "10";

  • ==

    如:100 == "100"; // true

  • if 語句和邏輯運算

    truly 變量:!!a === true 的變量 falsely 變量:!!a === false 的變量 以下是 falsely 變量。除此之外都是 truly 變量 !!0 === false !!NaN === false !!'' === false !!null === false !!undefined == false !!false === false // truly 變量 const a = true; if (a) {// ... } const b = 100 if (b) {// ... } // falsely 變量 const c = '' if (c) {// ... } const d = null if (d) {// ... } let e if (e) {// ... } // 邏輯判斷 console.log(10 && 0); // 0 console.log('' || 'abc'); // 'abc'
  • form 表單怎么阻止重復提交?

    **會引起表單重復提交的情況:**f5 刷新頁面,點擊瀏覽器后退,重復點擊提交按鈕。

    前臺:

  • 提交后按鈕設置為灰色,或者添加蒙版。
  • PRG 模式:表單提交后,redirect 到一個倒計時頁面,或者信息提示頁面,等有成功信息返回后,再跳轉回之前頁面。
  • js 中設置標記為判斷:
  • <script>var isCommitted = false; // 表單是否已經提交標識,默認為 falsefunction doSubmit() {if(isCommitted == false) {isCommitted = true; // 提交表單后,將表單是否已經提交標識設置為 true return true; // 返回 true 讓表單正常提交}else {return false; // 返回 false 那么表單將不提交}} </script>

    后臺:

  • session 方式,當表單頁面被請求時,生成一個特殊的字符標志串,存在 session 中,同時放在表單的隱藏域里。接受處理表單數據時,檢查標識字符串是否存在,如果存在,且表單中和 session 中相等,那么提交表單,并立即從 session 中刪除它。再次請求過來,如果發現表單提交里沒有有效的標志串,這說明表單已經被提交過了,屬于重復提交。
  • spring mvc 防止重復提交。
  • **數據庫:**數據庫中做唯一性約束。

    懶加載大量數據的時候加載不出來的情況怎么優化?

  • 圖片資源的壓縮。
  • 監聽滾動條事件,當滾動條到底時,增加顯示數據個數。
  • 可以使用虛擬列表,Object.freeze 凍結對象,Object.preventExtentsion 阻止對象擴展來阻止 vue 給每個對象加上 get, set,但是缺點是不能響應了。
  • icon 資源使用雪碧圖。
  • 開啟 gzip 壓縮(“命令行執行:npm i compression-webpack-plugin -D”)。
  • js 的垃圾回收機制。

    js 的垃圾回收機制就是為了防止內存泄漏的,內存泄漏的含義就是當已經不需要某塊內存時這塊內存還存在著,垃圾回收機制就是間歇的不定期的尋找到不再使用的變量,并釋放掉它們所指向的內存。所以這里又涉及到變量的生命周期,當一個變量的生命周期結束之后它所指向的內存就應該被釋放。

    JS 有兩種變量,全局變量和在函數中產生的局部變量。局部變量的生命周期在函數執行過后就結束了,此時便可將它引用的內存釋放(即垃圾回收),但全局變量生命周期會持續到瀏覽器關閉頁面。所以當我們過多的使用全局變量的時候也會導致內存泄漏的問題。

    說說什么情況會造成內存泄露?

    js 中:

  • 全局變量:JavaScript可以處理沒有聲明的變量:一個未聲明的變量的引用在全局對象中創建了一個新變量。在瀏覽器的環境中,全局對象是 window。
  • 閉包:匿名函數可以訪問父級作用域的變量。閉包會造成對象引用的生命周期脫離當前函數的上下文,如果閉包使用不當,可以導致環形引用(circular reference),類似于死鎖,只能避免,無法發生之后解決,即使有垃圾回收也還是會內存泄露。
  • 被遺忘的定時器:使用完setInterval/setTimeout之后通常忘記清理。
  • dom 清空或刪除時,事件未清除導致的內存泄露。
  • vue 中:

    如果在 created/mounted 中做了以下事情,記得在 beforeDestroy 中關閉:

  • 綁定了 DOM 對象中的事件。
  • 第三方庫初始化。
  • 如果組件中使用了定時器。
  • 組件中綁定了自定義事件。
  • 組件中使用了消息訂閱與發布。PubSub.unsubscribe(pubId)
  • TAPD跟禪道:工作中的 bug 處理。

    TAPD跟禪道

    tapd是騰訊公司的一個產品研發平臺,全名叫做騰訊敏捷產品研發平臺。最初只是在內部的人員才有資格接觸到,并且這個平臺已經存在有12年之久,正式對公眾開放是在2017年。

    禪道是第一款國產的開源項目管理軟件,她的核心管理思想基于敏捷方法scrum,內置了產品管理和項目管理,同時又根據國內研發現狀補充了測試管理、計劃管理、發布管理、文檔管理、事務管理等功能,在一個軟件中就可以將軟件研發中的需求、任務、bug、用例、計劃、發布等要素有序的跟蹤管理起來,完整地覆蓋了項目管理的核心流程。

    關于axios

  • 什么是 axios?

    官方介紹:Axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。

  • 使用 Fetch 發送請求:

    Fetch API 提供了一個 JavaScript 接口,用于訪問和操縱 HTTP 管道的一些具體部分,例如請求和響應。

    **注意:**Fetch 是 js 原生的,es6 以后出來的,自帶 promise,不需要下載第三方包,直接用即可。

    **缺點:**有兼容性問題,IE 全部不兼容。目前沒有廣泛使用。

  • Axios 取消請求:

  • 如果要取消請求的話,我們可以通過調用 XMLHttpRequest 對象上的 abort 方法來取消請求:

    let xhr = new XMLHttpRequest(); xhr.open("GET", "https://developer.mozilla.org/", true); xhr.send(); setTimeout(() => xhr.abort(), 300);
  • 而對于 Axios 來說,我們可以通過 Axios 內部提供的 CancelToken 來取消請求:

    const CancelToken = axios.CancelToken; const source = CancelToken.source();axios.post('/user/12345', {name: 'semlinker' }, {cancelToken: source.token })source.cancel('Operation canceled by the user.'); // 取消請求,參數是可選的
  • 此外,你也可以通過調用 CancelToken 的構造函數來創建 CancelToken,具體如下所示:

    const CancelToken = axios.CancelToken; let cancel;axios.get('/user/12345', {cancelToken: new CancelToken(function executor(c) {cancel = c;}) });cancel(); // 取消請求
  • Axios 如何取消請求?

    當請求方式、請求 URL 地址和請求參數都一樣時,我們就可以認為請求是一樣的。因此在每次發起請求時,我們就可以根據當前請求的請求方式、請求 URL 地址和請求參數來生成一個唯一的 key,同時為每個請求創建一個專屬的 CancelToken,然后把 key 和 cancel 函數以鍵值對的形式保存到 Map 對象中,使用 Map 的好處是可以快速的判斷是否有重復的請求:

    import qs from 'qs'const pendingRequest = new Map(); // GET -> params;POST -> data const requestKey = [method, url, qs.stringify(params), qs.stringify(data)].join('&'); const cancelToken = new CancelToken(function executor(cancel) {if(!pendingRequest.has(requestKey)){pendingRequest.set(requestKey, cancel);} })

    當出現重復請求的時候,我們就可以使用 cancel 函數來取消前面已經發出的請求,在取消請求之后,我們還需要把取消的請求從 pendingRequest 中移除。現在我們已經知道如何取消請求和如何判斷重復請求,下面我們來介紹如何取消重復請求。

  • JSON對象的方法:

  • JSON.stringify(obj/arr);

    js 對象(數組) 轉換為 json 對象(數組)(字符串類型)

  • JSON.parse(json);

    json 對象(數組)(字符串類型) 轉換為 js 對象(數組)

  • yarn 基本指令

    yarn init:初始化一個項目。

    yarn add + 包名:安裝一個依賴包。

    yarn update + 包名:升級依賴包。

    yarn update + 包名@version:升級指定版本的依賴包。

    yarn remove + 包名:移除依賴包。

    yarn install:安裝全部依賴包。

    其他

    1. 原型鏈:查找變量的過程。由多級父對象,逐級繼承,形成的鏈式結果。

    2. alert 彈出來的結果都會進行內部 toString 轉換,輸出為字符串。

    3. 枚舉、迭代、遍歷。

    4. 無論客戶關閉了瀏覽器還是電腦,只要還在 maxAge秒之前,登錄網站時該 Cookie 仍然有效。

    5. 代理(proxy):就是通過一個對象來操作另一個對象。

    6. 所有對象都是實例對象。都是 new 某個東西產生的。

    7. react 中使用 <button></button>如果你指定了 button 的 type 屬性,要么不指定,要么指定 submit,不要指定為type = ‘button’。

    8. property 和 attribute

    property:操作屬性為布爾值的屬性。

    attribute:操作屬性為非布爾值的屬性。

    9. 瀏覽器內核:支撐瀏覽器運行的最核心的程序。

    10. 注意:三元運算符中不能寫 return。

    11. 所有的字符串的方法都是返回一個新的字符串。

    12. this += n 也就是 this = this + n; 這樣會報錯的,this 不能像變量一樣賦值的。

    13. 如 n = Number(n) && (isNaN(n) ? 0 : n); n = Number(n) 賦值這個操作,永遠都為 true。

    總結

    以上是生活随笔為你收集整理的JS高级课堂笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。