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

歡迎訪問 生活随笔!

生活随笔

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

HTML

前端知识点总结——JS高级(持续更新中)

發布時間:2025/3/8 HTML 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前端知识点总结——JS高级(持续更新中) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前端知識點總結——JS高級(持續更新中)

1.字符串

什么是: 連續存儲多個字符的字符數組
相同: 1. 下標 2. .length 3. 遍歷

4. 選取: slice(starti[, endi])

不同: 類型不同 API不通用
API: 所有字符串API都無權修改原字符串,總是返回新字符串

  • 大小寫轉換:
    統一轉大寫: str=str.toUpperCase()
    統一轉小寫: str=str.toLowerCase()
    何時: 不區分大小寫時,都需要先轉為一致的大小寫,再比較。
  • 說明: 驗證碼本不該客戶端做,應該由服務器端完成

    2.獲取指定位置的字符:

    str.charAt(i) => str[i]
    獲取指定位置字符的unicode號
    str.charCodeAt(i)

    將unicode號轉為漢字: String.fromCharCode(unicode)

    3.獲取子字符串:

    str.slice(starti,endi+1)
    強調: 如果一個API,兩個參數都是下標,則后一個參數+1(含頭不含尾)
    str.substring(starti,endi+1) 用法和slice完全一樣
    強調: 不支持負數參數
    str.subStr(starti,n) 從starti開始,取n個
    強調: 第二個參數不是下標,所以,不用考慮含頭不含尾

    4.查找: 4種:

  • 查找一個固定的關鍵詞出現的位置:
    var i=str.indexOf("關鍵詞"[,fromi])
    在str中,fromi位置后,找下一個"關鍵詞"出現的位置
    如果找到,返回關鍵詞第一個字的下標位置
    如果沒找到,返回-1
    說明: fromi可省略,默認從0開始

    var i=str.lastIndexOf("關鍵詞");
    在str中,查找"關鍵詞"最后出現的位置

    問題: 只能查找一個固定的關鍵詞
    臥我草/操/艸/槽
    微 信 w x wei xin
    解決: 用正則查找:

  • 判斷是否包含關鍵詞:
    var i=str.search(/正則/)
    返回值: 如果找到,返回關鍵詞的位置

    如果沒找到,返回-1

    問題: 默認,所有正則都區分大小寫
    解決: 在第二個/后加i ignore 忽略
    問題: 只能獲得位置,無法獲得本次找到的敏感詞的內容

  • 獲得關鍵詞的內容:
    var arr=str.match(/正則/i);
    2種情況:

  • 不加g的情況: 只能返回第一個找到的關鍵詞內容和位置: [ 0: "關鍵詞內容", index: 位置 ]
  • 加g: 返回所有找到的敏感詞的內容,保存在數組中。g: global
  • 強調: 如果找不到,返回null

    警告: 凡是一個函數可能返回null!都要先判斷不是null,才能用!

    問題: 只能獲得關鍵詞內容,無法獲得位置

  • 即找每個關鍵詞內容,又找每個關鍵詞位置:
    reg.exec()
  • 5.替換:

    什么是: 將找到的關鍵詞替換為指定的內容
    如何: 2種:

  • 簡單替換: 將所有敏感詞無差別的替換為統一的新值
    str=str.replace(/正則/,"替換值")
  • 高級替換: 根據每個敏感詞的不同,分別替換不同的值
    str=str.replace(/正則/,function(kw){

    //kw: 會自動獲得本次找到的一個關鍵詞return 根據kw的不同,動態生成不同的替換值

    })

  • 衍生: 刪除關鍵詞:
    str=str.replace(/正則/,"")

    6.正則表達式: Regular Expression

    什么是: 描述一個字符串中字符出現規律的規則的表達式
    何時: 2種:

  • 查找關鍵詞:
  • 驗證:
  • 如何: 正則表達式語法:

  • 最簡單的正則其實是關鍵詞原文:
  • 7.字符集:

    什么是: 規定一位字符,備選字符列表的集合
    何時: 只要一位字符,有多種備選字時
    如何: [備選字符列表]
    強調: 一個[]只能匹配一位字符
    簡寫: 如果備選字符列表中部分字符連續

    可簡寫為: [x-x] 用-省略中間字符比如: [0-9] 一位數字[a-z] 一位小寫字符[A-Z] 一位大寫字母[A-Za-z] 一位字符[0-9A-Za-z] 一位字母或數字[\u4e00-\u9fa5] 一位漢字

    反選: 1 除了4和7都行

    8.預定義字符集: 4種:

    d 一位數字 [0-9]
    w 一位數字,字母或下劃線 [0-9A-Za-z_]
    強調: 只有100%匹配時,才使用w,如果不允許有_,則使用自定義字符集
    s 一位空字符,比如: 空格,Tab,...
    . 通配符
    問題: 字符集只能規定字符的內容,無法靈活規定字符的個數

    9.量詞:

    什么是: 專門規定一個字符集出現次數的規則
    何時: 只要規定字符集出現的次數,都用量詞
    如何: 字符集量詞
    強調: 量詞默認只修飾相鄰的前一個字符集
    包括: 2大類:

    1. 有明確數量邊界:{6,8} 最少6次,最多8次{6,} 最少6次,多了不限{6} 必須6次,不能多也不能少 2. 沒有明確數量邊界:? 可有可無,最多1次* 可有可無,多了不限+ 至少1次,多了不限

    10.選擇和分組:

  • 選擇: 或
    規則1|規則2
    何時: 只要在兩個規則中任選其一匹配
  • 分組: (規則1規則2...)
    何時: 如果希望一個量詞同時修飾多個規則時,都要先將多個規則分為一組,再用量詞修飾分組。

    比如: 車牌號: [\u4e00-\u9fa5][A-Z]?[0-9A-Z]{5} 比如: 手機號規則: \+86或0086 可有可無,最多1次 空字符 可有可無,多了不限1在3,4,5,7,8中選一個

    9位數字
    (+86|0086)?s*1[34578]d{9}

    比如: 身份證號:

    15位數字 2位數字 一位數字或X

    可有可無,最多一次 \d{15}(\d{2}[0-9X])? 比如: 電子郵件: 鄙視

    /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
    比如: url:
    (https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]

  • 11.匹配特殊位置: 3個:

  • 字符串開頭: ^
  • 字符串結尾: $
    比如: 開頭的空字符: ^s+

    結尾的空字符: \s+$開頭或結尾的空字符: ^\s+|\s+$

    3.單詞邊界: b 包括開頭,結尾,空字符,標點符號

    比如: 單詞首字母: \b[a-z] 匹配單詞: \bxxx\b
  • 12.String:

    替換: 2種: 如果關鍵詞是固定的:
    str=str.replace("關鍵詞","替換值");
    如果關鍵詞變化
    str=str.replace(/正則/ig,"替換值");
    切割: 2種: 如果分隔符是固定的:
    var substrs=str.split("分隔符")
    如果分隔符不是固定的
    var substrs=str.split(/正則/i)
    固定套路: 將字符串打散為字符數組

    var chars=str.split("")

    13.RegExp:

    什么是: 保存一條正則表達式,并提供用正則表達式執行驗證和查找的API
    何時: 只要用正則查找關鍵詞或驗證字符串格式時
    如何:
    創建: 2種:

  • 直接量: var reg=/正則/ig
    何時: 只要正則表達式的規則是固定不變的。
    問題: 正則表達式時固定不變的,不支持動態生成
  • new: var reg=new RegExp("正則","ig");
    何時: 只要需要動態生成正則表達式
  • API: 2個:

  • 驗證: var bool=reg.test(str)
    問題: 默認,只要找到匹配的內容,就返回true,不要求完整匹配!
    解決: 今后,凡是驗證必須前加^,后加$
  • 查找: 即找每個關鍵詞位置,又獲得每個關鍵詞內容
    var arr=reg.exec(str)
    在str中查找下一個關鍵詞的位置和內容
    返回值: arr:[ 0: 內容, index: 位置 ]
    如果找不到,返回null
    如果找所有: 只要用while反復調用reg.exec即可,exec可自動跳到下一個查找位置
  • 14.Math

    什么是: 保存數學計算的常量和API的對象
    何時: 進行算術計算
    如何:
    創建: 不用創建,所有API都用Math直接調用
    API:

  • 取整:
    上取整: Math.ceil(num)
    下取整:
    Math.floor(num)
    parseInt(str) 去掉字符串結尾非數字字符(單位)
    四舍五入取整:
    Math.round(num)
    優: 返回數字類型,可直接計算
    缺: 不能隨意指定小數位數
    n.toFixed(d)
    優: 可隨意指定小數位數
    缺: 返回字符串類型,不能直接做加法
    自定義round
  • 乘方和開平方:
    Math.pow(底數,冪)
    Math.sqrt(num)
  • 最大值和最小值
    Math.max(值1, 值2,...)
    Math.min(值1, 值2,...)
    問題: 不支持數組
    解決: Math.max(...arr)
  • 隨機數:
    Math.random() 0~1 隨機小數
    公式: 在min到max之間取一個隨機整數
    parseInt(Math.random()*(max-min+1)+min)
    簡寫: 在0~max之間取一個隨機整數
    parseInt(Math.random()*(max+1))
  • 三角函數:
    已知角度,求邊長,用三角函數: sin cos tan
    已知邊長,求角度,用反三角函數: asin acos atan
    僅以atan:
    var 弧度=Math.atan(對邊長/鄰邊長)

    360角度=2π弧度

    問題: atan無法區分角度的象限
    解決: Math.atan2(對邊長, 鄰邊長);

  • 15.Date:

    什么是: 保存一個時間,提供操作時間的API
    何時: 只要在程序中存儲時間或操作時間,都用date
    如何:
    創建: 4種:

  • 創建日期對象,并自動獲得客戶端當前系統時間
    var now=new Date();
  • 創建日期對象,保存自定義時間
    var now=new Date("yyyy/MM/dd hh:mm:ss");
  • 用毫秒數創建日期對象:
    var date=new Date(ms)
  • 復制一個日期對象:
    問題: 日期的計算都是直接修改原日期對象
    解決: 如果希望同時保留計算前后的開始和結束時間,都要先復制開始時間,再用副本計算結束時間
    var date2=new Date(date1)
  • 本質: 起始日期對象內部保存的是一個巨大的毫秒數:

    1970年1月1日至今的毫秒數

    文字存儲日期的問題:

    1. 有時區問題: 2. 不便于計算:

    毫秒數存儲日期:

    1. 不受時區的干擾: 2. 便于計算:

    總結: 將來在網絡中傳輸或在數據庫中存儲時間,都用毫秒數

    16.API:

  • 8個單位:
    FullYear Month Date Day
    Hours Minutes Seconds Milliseconds
  • 每個單位上都有一對兒get/set方法:
    getXXX() 負責獲得單位的值
    setXXX() 負責修改單位的值
    特例: Day 不能修改,沒有setDay()
  • 取值范圍:
    Month: 0~11 計算機中的月份總是比現實中小1
    Date: 1~31
    Day: 0~6
    Hours: 0~23
    Minutes/Seconds: 0~59
  • 日期計算:

  • 兩日期相減: 得到的是毫秒差
    何時: 計算時間段或計算倒計時
  • 對任意單位做加減: 3步:

  • 獲得單位的當前值
  • 做加減
  • 將計算后的結果set回去
    setXXX()可自動調整時間進制
  • 可簡化為: date.setXXX(date.getXXX()+n)
    問題: setXXX()直接修改原日期
    解決: 如果同時保存計算前后的開始和結束時間,應該先復制副本,再用副本計算。

    17.Date:

    日期格式化:
    date.toString() 默認當地時間的完整版格式
    date.toLocaleString() 轉為當地時間的簡化版格式
    date.toLocaleDateString() 僅保留日期部分
    date.toLocaleTimeString() 僅保留時間部分

    18.Error:

    什么是錯誤: 程序執行過程中,遇到的無法繼續執行的異常情況
    程序出錯,都會強行中斷退出。
    什么是錯誤處理: 即使程序出錯!也保證不會中斷退出
    何時: 如果希望程序,即使出錯,也不會強行中斷退出
    如何:
    try{
    可能出錯的正常代碼
    }catch(err){
    //err: 錯誤對象, 自動保存了錯誤的信息
    只有出錯才執行的錯誤處理代碼:
    提示錯誤信息, 記錄日志, 釋放資源
    }
    問題: 效率略低
    解決: 多數try catch,都能用if...else代替

    主動拋出錯誤:
    throw new Error("錯誤信息")
    鄙視: js中共有幾種錯誤類型: 6種:
    SyntaxError 語法錯誤
    ReferenceError 引用錯誤
    TypeError 類型錯誤
    RangeError 范圍錯誤 參數超范圍

    EvalError URIError

    19.Function:

    什么是函數: 保存一段代碼段的對象,再起一個名字。
    為什么: 代碼重用
    何時: 只要一段代碼可能被重復使用時!
    如何:
    創建: 3種:

  • 聲明: function 函數名(參數列表){

    函數體;return 返回值;}

    參數: 調用函數時,接收傳入函數的數據的變量
    何時: 如果函數自身必須某些數據才能正常執行時,就必須定義參數,從外部接收必須的數據
    返回值: 函數的執行結果
    何時: 如果調用者需要獲得函數的執行結果時
    調用: var 返回值=函數名(參數值列表);
    問題: 聲明提前: 在程序開始執行前,先將var聲明的變量和function聲明的函數,提前到當前作用域的頂部集中創建。賦值留在原地。
    解決:

  • 直接量: var 函數名=function (參數列表){
    特點: 不會被聲明提前
    揭示: 函數名其實只是一個變量

    函數其實是一個保存代碼段的對象函數名通過對象地址引用函數對象
  • new :
    var 函數名=
    new Function("參數1","參數2",...,"函數體")
  • 20.重載overload:

    什么是: 多個相同函數名,不同參數列表的函數,在調用時,可根據傳入的參數不同,自動執行不同的操作。
    為什么: 為了減少API的數量,減輕調用者的負擔
    何時: 只要一項任務,可能根據傳入參數的不同,執行不同的流程時。
    如何: js語法默認不支持重載!

    因為: js中不允許多個同名函數,同時存在。最后一個函數會覆蓋之前的。 變通實現: arguments什么是: 每個函數中,自動包含的,接收所有傳入函數的參數值的類數組對象類數組對象: 長得像數組的對象vs 數組: 相同: 1. 下標, 2. .length, 3. 遍歷不同: 類型不同, API不通用

    21.匿名函數:

    什么是: 定義函數時,不指定函數名
    為什么: 節約內存 或 劃分臨時作用域
    何時:

  • 只要一個函數,希望調用后,立刻自動釋放!
  • 劃分臨時作用域:
  • 如何:

  • 回調: 定義函數后,自己不調用,而是傳遞給另一個函數去調用
  • 自調: 定義函數后,立刻調用自己。
    何時: 今后所有js代碼必須都放在匿名函數自調中,避免全局污染。
  • 22.垃圾回收:

    什么是垃圾: 一個不再被任何變量使用的對象
    什么是垃圾回收: js引擎會自動回收不再被使用的對象的空間。
    為什么: 內存空間都是有限的!
    垃圾回收器: 專門負責回收垃圾對象的小程序——js引擎自帶
    如何:

  • 程序執行時,垃圾回收器伴隨主程序執行而執行。
  • 每創建一個對象,垃圾回收器就會記錄對象被幾個變量引用著.
  • 如果發現一個對象不再被任何變量應用,則自動回收該對象的存儲空間。
  • 好的習慣: 只要一個對象不再使用,就要賦值為null

    23.作用域和作用域鏈

    作用域(scope): 一個變量的可用范圍
    為什么: 避免內部的變量影響外部
    本質: 是一個存儲變量的對象
    包括: 2種:

  • 全局作用域: window
    保存全局變量: 隨處可用,可反復使用
  • 函數作用域: ?
    保存局部變量: 僅在函數內可用,且不可重用!
  • 24.函數生命周期:

  • 程序開始執行前
    在內存中創建執行環境棧(數組): 用于保存正在調用的函數任務。
    在執行環境站中添加第一條記錄: 調用瀏覽器主程序
    創建全局作用域對象window: 2個作用:

    1. 保存瀏覽器自己需要的數據和對象 2. 作為程序的全局作用域對象,保存全局變量
  • 定義函數時:
    在window中定義函數名變量
    創建函數對象保存函數定義
    函數名變量引用函數對象
    函數對象的scope屬性,又指回了函數創建時的作用域
  • 調用函數時
    在執行環境棧中添加了本次函數調用的記錄
    創建本次函數調用的函數作用域對象AO
    在AO中添加函數的局部變量
    設置AO的parent指向函數的scope
    執行環境棧中的函數調用記錄,引用AO
    變量的使用順序: 先用局部,再用全局
  • 函數調用后
    本次函數調用的記錄從執行環境棧中出棧
    導致AO被釋放, 導致所有局部變量都釋放
  • 25.作用域鏈:

    什么是: 由多級作用域對象,逐級引用形成的鏈式結構
    2個作用:

  • 保存所有變量
  • 控制著變量的使用順序!
  • 26.閉包closure:

    什么是: 即重用一個變量,又保護變量不被污染的一種機制
    為什么: 全局變量和局部變量都具有不可兼得的優缺點:
    全局變量: 優: 可重用, 缺: 易被污染
    局部變量: 優: 僅函數內可用,不會被污染

    缺: 不可重用!

    何時: 只要一個變量,可能被重用,又不想被篡改
    如何: 3步:

  • 用外層函數包裹要保護的變量和內層函數
  • 外層函數將內層函數返回到外部
  • 調用外層函數,獲得內層函數的對象,保存在外部的變量中——形成了閉包
  • 閉包形成的原因: 外層函數調用后,外層函數的函數作用域對象無法釋放
    主動使用閉包: 為一個函數綁定一個專屬的變量
    鄙視: 畫簡圖

  • 找受保護的變量,并確定其最終值
  • 找內層函數對象
    外層函數向外返回內層函數對象: 3種:

  • return function(){}
  • 全局變量=function(){}
  • return arr/obj{function(){...}}
  • 27.OOP

    什么是對象: 內存中存儲多個數據的獨立存儲空間都稱為一個對象。
    什么是面向對象: 程序中都是用對象結構來描述現實中一個具體事物。
    為什么: 為了便于大量數據的維護和查找
    何時: 幾乎所有js程序,都使用面向對象的方式開發
    如何: 三大特點: 封裝,繼承,多態
    封裝: 用對象來集中描述現實中一個具體事物的屬性和功能
    為什么: 便于維護和查找
    何時: 今后只要使用面向對象的方式開發,都要先封裝對象,再按需使用對象的屬性和功能。
    如何: 3種:

  • 用{}:
    var obj={
    屬性名:值,

    ... : ... ,

    //方法名:function(){...},
    方法名 (){...},
    }
    其中: 事物的屬性值會成為對象的屬性

    對象的屬性本質是保存在對象中的一個變量事物的功能會成為對象的方法!方法的本質是保存在對象中的一個函數

    如何訪問對象的成員:
    訪問對象的屬性: 對象.屬性名
    調用對象的方法: 對象.方法名()
    問題: 對象自己的方法中要使用對象自己的屬性
    錯誤: 直接用屬性名,報錯: 找不到變量

    為什么: 默認,不加.就使用的變量,只能在作用域鏈中查找,無法自動進入對象中

    解決一: 對象名.屬性名

    問題: 對象名僅是一個普通的變量名,可能發生變化。

    正確解決: this.屬性名
    this: 自動指正在調用當前方法的.前的對象

    為什么: 不受對象名變量的影響 何時: 只要對象自己的方法向訪問對象自己的屬性時,都必須加this.
  • js中對象的本質,其實就是一個關聯數組

  • 用new:
    var obj=new Object(); //創建空對象 等效于{}
    obj.屬性名=值;
    obj.方法名=function(){
    ... this.屬性名 ...
    }
  • 和關聯數組一樣,js中的對象也可隨時添加新屬性和方法。
    問題: 反復創建多個相同結構的對象時,重復代碼太多,導致不便于維護
    解決:

  • 用構造函數:
    構造函數: 描述一類對象統一結構的函數
    為什么: 為了重用結構代碼!
    何時: 只要反復創建相同結構的多個對象時,都用構造函數
    如何: 2步:

  • 定義構造函數
    function 類型名(屬性參數列表){
    this.屬性名=屬性參數;
    this. ... = 屬性參數;
    this.方法名=function(){

    this.xxx

    }
    }

  • 調用構造函數創建新對象
    var obj=new 類型名(屬性值列表)
    new: 1. 創建新的空對象

    2. 設置新對象繼承構造函數的原型對象3. 用新對象調用構造函數將構造函數中的this都指向新對象4. 返回新對象的地址
  • 問題: 構造函數只能重用代碼,無法節約內存!
    解決: 繼承:

    28.繼承:

    什么是: 父對象的成員,子對象無需創建,就可直接使用
    為什么: 代碼重用,節約內存
    何時: 只要多個子對象,擁有相同的成員時,都應只在父對象中定義一份,所有子對象共用即可!
    如何: js中繼承都是通過原型對象實現的

    什么是原型對象: 集中存儲同一類型的所有子對象,共用成員的父對象 何時: 只要繼承,必然原型對象 如何: 創建: 不用創建,買一贈一每創建一個構造函數,都附贈一個原型對象 繼承: 在創建子對象時,new的第2步自動設置子對象繼承構造函數的原型對象訪問成員: 優先訪問自有成員自己沒有,就去父對象(原型對象)中查找將成員添加到原型對象中: 構造函數.prototype.成員=值

    自有屬性和共有屬性:
    自有屬性: 保存在當前對象本地,僅歸當前對象獨有的屬性
    共有屬性: 保存在父對象中,所有子對象共有的屬性
    讀取屬性值: 子對象.屬性
    修改屬性值: 自有屬性,必須通過子對象自己修改

    共有屬性,只能用原型對象修改!

    內置對象的原型對象:
    鄙視: 內置對象: 11個:

    String Number Boolean ——包裝類型對象 Array Date RegExp Math Error Function Object Global (在瀏覽器中,被window代替)

    鄙視: 包裝類型的理解

    什么是: 保存一個原始類型的值,并提供操作原始類型值的API 為什么: 原始類型的值本身不具有任何功能 何時: 只要試圖對原始類型的值調用API時,都會自動使用包裝類型對象來幫助原始類型的值執行操作。 如何: 1. 內存中已經預置了三大包裝類型的對象:String Number Boolean2. 在試圖對原始類型的值調用API時,自動檢測原始類型的值的類型名var n=345.678;typeof n => number3. 根據類型名實例化對應的包裝類型對象,調用其APInew Number(n).toFixed(2) => 345.684. 執行后,包裝類型對象自動釋放new Number釋放!

    29.OOP

    面向對象三大特點: 封裝,繼承,多態
    繼承:
    原型對象:
    內置類型的原型對象:
    一種類型: 包含兩部分:

    1. 構造函數: 創建該類型的子對象 2. 原型對象: 保存所有子對象的共有成員

    解決瀏覽器兼容性問題: 舊瀏覽器無法使用新API

    1. 判斷當前瀏覽器對應類型的原型對象中是否包含該API 2. 如果不包含,則自定義該API,添加到對應類型的原型對象中

    30.原型鏈:

    什么是: 由多級父對象,逐級繼承形成的鏈式結構
    保存著: 所有對象的屬性
    控制著: 對象屬性的使用順序:

    先自有,再共有

    鄙視: 如何判斷一個對象是數組類型? 有幾種方法
    錯誤: typeof : 只能區分原始類型,函數,無法進一步區分引用類型對象的具體類型名
    正確: 4種:

  • 判斷原型對象:
    obj.__proto__==Array.prototype
    Array.prototype.isPrototypeOf(obj)
  • 判斷構造函數:
    obj.constructor==Array
    obj instanceof Array
  • 問題: 不嚴格, 不但檢查直接父對象,且檢查整個原型鏈

  • 判斷對象內部的class屬性
  • class屬性: 對象內部的專門記錄對象創建時的類型名的屬性
    問題1: class屬性是內部屬性,無法用.直接訪問
    解決: 唯一的辦法: Object.prototype.toString()
    問題2: 每種類型的原型對象都重寫了各自不同的toString()方法,子對象無法調用到Object.prototype.toString()
    解決: fun.call(obj) 讓obj強行調用任何一個fun

    Object.prototype.toString.call(obj)在執行的一瞬間: obj.toString()結果:"[object Class]"

    鄙視: 何時將方法定義在原型對象中,何時將方法定義在構造函數上
    實例方法和靜態方法:
    實例方法: 必須該類型的子對象才能調用的方法
    比如: arr.sort() arr.push()
    何時: 只要要求必須該類型的子對象才能調用
    如何: 所有放在原型對象中的方法都是實例方法
    靜態方法: 不需要創建該類型的子對象,任何對象都可使用的方法。
    比如: Array.isArray(fun)

    Array.isArray(date)Array.isArray(obj)

    何時: 不確定將來調用該函數的對象類型時
    如何: 添加到構造函數對象上的方法都是靜態方法。可通過構造函數.靜態方法方式直接調用!

    31.多態:

    什么是: 一個方法在不同情況下表現出不同的狀態
    包括:

  • 重載overload:
  • 重寫override:
    什么是: 如果子對象覺得從父對象繼承來的成員不好用,可在本地定義同名的自有成員,覆蓋父對象的成員
    為什么: 覺得從父對象繼承來的成員不好用
    何時: 只要覺得從父對象繼承來的成員不好用
    如何: 在本地定義同名的自有成員
  • 32.自定義繼承:

  • 只修改一個對象的父對象
    obj.__proto__=father
    Object.setPrototypeOf(obj,father)
  • 修改所有子對象的父對象:
    構造函數.prototype=father
    時機: 在創建子對象之前換!
  • 兩種類型間的繼承:
    何時: 發現多個類型之間擁有部分相同的屬性結構和方法定義時,都要抽象父類型出來
    如何: 2步:

  • 定義抽象父類型: 2步:

  • 定義構造函數保存公共的屬性結構
  • 定義原型對象保存公共的方法
  • 讓子類型繼承父類型: 2步:

  • 在子類型構造函數中借用父類型構造函數
    錯誤: 直接調用: Flyer(fname,speed)
    原因: Flyer不用.不用new調用,其中的this默認指window,Flyer中所有屬性泄露到全局
    正確: 用call將正確的this注入到Flyer中,代替錯誤的this
    如何: Flyer.call(正確的this, fname,speed)
  • 讓子類型原型對象繼承父類型原型對象
    Object.setPrototypeOf(子類型原型,父類型原型)
  • 33.ECMAScript6

  • 嚴格模式:
    什么是: 比普通js運行機制要求更嚴格的模式
    為什么: 普通的js運行機制有很多廣受詬病的缺陷
    何時: 今后所有項目必須運行在嚴格模式下

  • 如果新項目,整個js文件啟用嚴格模式
  • 舊項目,逐個函數啟用嚴格模式
  • 如何:

  • 在script或整個js文件頂部,添加"use strict";
  • 在函數內頂部,添加"use strict";
  • 規則: 4個:

  • 禁止給未聲明的變量賦值
  • 將靜默失敗升級為錯誤
  • 普通函數或匿名函數自調中的this默認不再指向window,而是undefined
  • 禁止使用arguments, arguments.callee,...
  • 補: arguments.callee 自動獲得當前正在調用的函數本身
    禁用,說明強烈不推薦使用遞歸!

    34.保護對象:

    保護對象的屬性:
    ES5將對象屬性分為:
    命名屬性: 可用.直接訪問到的屬性
    數據屬性: 直接存儲屬性值的屬性
    保護數據屬性: 4大特性:

    一個屬性包含四大特性:{value: 實際保存屬性值,writable: true/false, //只讀enumerable: true/false, //不可遍歷//不是徹底隱藏,用.依然可訪問!configurable:true/false //1. 禁止刪除//2. 禁止修改其它特性//一旦改為false,不可逆 } 獲取一個屬性的四大特性: var attrs=Object.getOwnPropertyDescriptor(obj,"屬性") 修改四大特性: Object.defineProperty(obj,"屬性",{四大特性:值 }) 簡寫: Object.defineProperties(obj,{屬性名:{特性:值,特性:值,},屬性名:{... : ...}})

    訪問器屬性: 不直接存儲屬性值,僅提供對另一個數據屬性的保護
    何時: 只要對一個屬性提供自定義規則的保護
    如何:

    添加: 只能用Object.defineProperty和defineProperties添加 四大特性: {get(){ return this.數據屬性 }set(val){ 如果驗證val通過this.數據屬性=val否則報錯}enumerable:configurable: }

    如何使用: 同普通的數據屬性用法一樣!

    在取值時,自動調用訪問器屬性內部的get在賦值時,自動調用訪問器屬性內部的set方法,同時將等號右邊的新值,交給val參數

    問題: enumerable只能防住for in,防不住.,依然可用.直接修改被保護的數據屬性
    解決:
    內部屬性: 不能用.直接訪問到的屬性
    比如: class proto

    保護對象的結構: 3種

  • 防擴展: 禁止給對象添加新屬性
    Object.preventExtensions(obj)
    原理: 內部屬性: extensible:true

    preventExtensions將extensible改為false
  • 密封: 在防擴展同時,禁止刪除現有屬性
    Object.seal(obj)
    原理: 1. 將extensible改為false,禁止擴展

    2. 自動將所有屬性的configurable都改為false
  • 凍結: 在密封的同時,禁止修改一切屬性值
    Object.freeze(obj)
    原理: 1. 兼具密封的所有功能

    2. 又將每個屬性的writable自動改為false!
  • Object.create()
    僅用父對象,就可創建子對象,
    同時還可為子對象擴展自有屬性
    var child=Object.create(father,{
    //Object.defineProperties
    屬性名:{

    特性:值, 特性:值,

    }
    })
    鄙視: 描述Object.create的執行原理

  • 創建空對象child
  • 自動設置child的__proto__為father
  • 為child擴展新的自有屬性
  • 35.call/apply/bind

    替換函數中不想要的this!
    call/apply: 立刻調用函數,并臨時替換中的this為指定對象
    何時: 只要調用函數時,函數中的this不是想要的就用call換成想要的
    如果傳入函數的參數,是以數組形式,整體傳入
    就用.apply(obj,arr)
    bind: 基于原函數,創建一個新函數,并永久綁定this為指定對象
    何時: 不會立刻調用的函數(回調函數)中的this,不是想要的,就可用bind創建一個新函數,并永久綁定this!

    36.數組API:

    判斷:

  • 判斷數組中所有元素是否都符合條件
    arr.every(function(elem,i,arr){

    //elem: 當前元素值 //i: 當前位置 //arr: 當前數組對象 return 判斷條件

    })

  • 判斷數組中是否包含符合條件的元素
    arr.some(function(elem,i,arr){

    return 判斷條件

    })

  • 遍歷:

  • forEach: 對原數組中每個元素執行相同的操作
    arr.forEach(function(elem,i,arr){
    arr[i]=新值
    })
  • map: 依次取出原數組中每個元素執行相同操作后,放入新數組。原數組不變
    arr.map(function(elem,i,arr){
    return 新值
    })
  • 過濾和匯總:

  • 過濾: 復制出原數組中符合條件的元素,放入新數組返回
    var subs=arr.filter(function(elem,i,arr){
    return 判斷條件
    })
  • 匯總: 將原數組中所有值統計出一個最終結論
    var result=arr.reduce(function(prev,elem,i,arr){
    //prev: 截止到目前,之前的臨時匯總值
    return prev+elem;
    })
  • 37.let: 代替var

    為什么
    問題1: 聲明提前, 破壞程序原有執行順序
    解決: let禁止在聲明之前,提前使用該變量
    問題2: js沒有塊級作用域, 塊內的變量,會污染到塊外
    解決: let會將當前所在if/for/while...(){}變成塊級作用域

    后果: 塊內的let出的變量不會影響外部!

    原理: 其實let就是匿名函數自調!
    let與for循環,可形成閉包的效果
    強調: 原來塊內外都可使用的變量,出了塊,就不能用了!

    38.參數增強:

    默認值: function fun(參數1, 參數2,...,參數n=默認值)
    強調: 帶默認值的參數必須定義在列表末尾
    原理: 參數n=參數n||默認值;
    rest: 代替了arguments
    何時: 當函數,不確定參數個數時——重載
    為什么: arguments的缺點:

  • 類數組對象,不是數組
  • 只能后去全部,不能有選擇的分段獲取
  • 如何: 定義函數時: function fun(參數1,參數2,..., ...數組名)
    數組名, 是一個純正的數組,且可有選擇的分段獲取
    原理: var arr=[].slice.call(arguments[,starti]);//將類數組對象轉為數組
    spread: 代替apply
    為什么: apply雖然可打散數組類型參數為單個值,但是必須和替換this的操作捆綁使用
    何時: 只要僅需要打散數組類型參數為單個值時
    如何: 調用時: fun(參數值1,參數值2,...數組)

  • 箭頭函數: 代替回調函數中的function

  • 何時: 只要回調函數,都不再使用function,而是使用箭頭函數
    如何:

  • 去function改=>
  • 如果只有一個參數,可省略()
  • 如果函數體只有一句話,則{}可省略

    更簡化: 如果僅有的一句話還是return,可省略return
  • 特點: 內外共用同一個this ——代替bind
    問題: 如果反而希望內外this不通用時,就不能用箭頭函數

    40.模板字符串: 代替+號拼接字符串

    ESLint規定,不允許使用+拼接字符串
    如何:

  • 定義模板: 左右模板內容都必須放在``中
  • 在模板中嵌入變量或表達式,動態生成內容:
    模板內,可用${...}嵌入任何合法的js變量或語句
  • 41.解構: 簡化批量賦值

    什么是: 將一個對象/數組中的成員和元素,分別提取出來,單獨使用。
    為什么: 避免反復使用對象名/數組名
    何時: 只要希望將一個大的對象或數組中的每個成員單獨取出使用時
    如何: 3種:

  • 數組解構: 下標對下標
  • 對象解構: 屬性對屬性
  • 參數解構: 屬性對屬性
    定義函數時:
    問題: 普通函數的參數列表的順序和個數是固定的
    解決: 使用對象語法定義參數列表
    優點: 將來傳入的參數個數,順序與對象列表無關
    調用函數: 也用對象語法傳入參數
    賦值過程中,采用對象結構的方式,為參數變量賦值
  • 42.for...of 在特定情況下,代替for循環

    什么是: 依次遍歷數組/類數組對象中每個元素的值
    vs for...in: 依次遍歷關聯數組/對象中每個成員的屬性名
    何時: 如果希望從頭到尾遍歷整個數組或類數組對象
    如何:

    for(var elem of arr){elem}

    局限: 無法獲得當前位置; 無法控制遍歷的進度/順序; 無法有選擇的遍歷部分

    43.class: 代替傳統的封裝,繼承,多態的語法

    封裝:

    class Student {constructor(sname,sage){... ...}intr (){//Student.prototype.intr} fun (){}}

    繼承:

    class Flyer {constructor(fname,speed){... ...}fly (){... ...}}class Plane extends Flyer{constructor(fname,speed,score){//super指向父類型構造函數,且自動替換thissuper(fname,speed)... ...}getScore (){... ...}}

    靜態方法:

    class User{constructor(uname,upwd){this.uname=uname;this.upwd=upwd;}save(){//保存在User.prototype中的實例方法console.log("保存當前對象");}static findOne(){//靜態方法,定義在構造函數上return new User();}}var user=new User(...);user.save();//調用實例方法User.findOne();//調用靜態方法

    44.Promise: 解決: 回調地獄

    什么是callback hell: 由于使用參數傳遞回調函數,導致步驟多時,參數的嵌套層級很深。
    何時: 只要異步調用,可能發生延遲時,都要用Promise代替傳統參數callback
    如何: 定義時

    function 第一件事(){return new Promise(fn=>{第一件事的內容fn()})}function 第二件事(){return new Promise(fn=>{第二件事的內容fn()})}function 第三件事(){第三件事的內容}

    調用時:

    第一件事()//return Promise(fn).then(第二件事)//return Promise(fn).then(第三件事)

    鄙視題:

  • 將類數組對象復制為數組:
    var arr2=Array.prototype.slice.call(arguments)
    將類數組對象復制為數組,并選取指定位置的剩余元素
    var arr2= Array.prototype.slice.call(arguments,starti)

    相當于arguments.slice(starti)

    其實更簡單的: var arr2= [].slice.call(arguments,starti)

  • promise中的錯誤處理:
    其實: new Promise(可接收2件事)

    .then( ) .catch( )

    new Promise((正常函數,出錯函數)=>{

    如果順利執行:調用正常() 否則調用出錯()

    })

  • 等待多個任務完成
    前提: 每個任務都必須都返回Promise
    如何: Promise.all([

    task1(), task2(),...]).then(()=>{所有任務完成后才執行的任務})

  • 47 ?
  • 總結

    以上是生活随笔為你收集整理的前端知识点总结——JS高级(持续更新中)的全部內容,希望文章能夠幫你解決所遇到的問題。

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