正則表達式&函數
1 正則表達式RegExp
1.1 概述
Regular Expression:由普通字符和特殊字符組成以描述特定字符規則的表達式;常用於在文本中搜索,匹配,替換特定形式的文本
1.2 定義
除開所有大小寫字母和數字,部分字符有特殊語法含義,必須使用\進行轉義:. \ / * ? + [ ( ) ] { } ^ $ |
-
字符集:正則表達式匹配範圍內的字符
語法 含義 [abc] 匹配指定集合內的任一個字符 [^abc] 匹配不在集合內的任意字符 [0-9] 一個數字 [a-z] 一個小寫字母 [A-Z] 一個大寫字母 [A-Za-z] 一個字母 [A-Za-z0-9] 一位數字或字母 [\u4e00-\u9fa5] 一個漢字 -
預定義字符集:對常用字符集簡化寫法
語法 含義 \d 匹配一個數字 \D 匹配非數字 \w 匹配數字/字母/下劃線 \W 匹配非數字/字母/下劃線 \s 匹配空字符 \S 匹配非空字符 . 除回車換行的任何字符 -
量詞:規定字符出現次數
重複字符 含義 {x} 必須x位 {x,y} x到y位 {x,} x位以上 * 可有可無,數量不限 ? 可有可無,最多一個 + 可有可無,至少一個 -
選擇分組
使用()指定分組,使用|進行條件選擇;
|只匹配左右所有字符,不會考慮單個字符 -
匹配位置
重複字符 含義 ^ 字符串開頭 $ 字符串結尾 b 單詞邊界 B 單詞非邊界 ?=x 之後緊接x的字符串 ?!x 之後沒有緊接x的字符串
1.3 RegExp對象
專門保存正則表達式的對象,提供正則表達式執行驗證和查找的API.
- 直接量創建:var reg=/正則/ig;
- 用程序動態生成:var reg=new RegExp(“正則表達式”,“ig”)參數列表中式字符串,所以可以能夠js動態生成;
常用API:reg.test(str)檢查字符串str的格式,只要部分規則符合就返回true;可以通過前加^後加$從頭到尾完整匹配;
reg.exec(str)在str中查找下一個符合reg要求的關鍵詞的內容和位置,使用循環反覆調用直至返回null
1.4 模式匹配
1.4.1 查找關鍵詞
- 查找一個固定的敏感詞出現的位置:
回顧: str.indexOf()
var i=str.indexOf(“敏感詞”,starti)
在str中,從starti位置開始,查找下一個“敏感詞”的位置
省略第二個參數starti,默認從0位置開始查找
返回值: 如果找到,返回敏感詞第一個字的位置
如果找不到,返回-1
問題: 只能查找一種固定的敏感詞 - 模糊查找符合正則表達式要求的敏感詞:
var i=str.search(/正則/);
在str中查找第一個符合正則要求的敏感詞的位置
返回值: 如果找到,返回敏感詞第一個字的位置
如果找不到,返回-1
問題1: 正則默認都是區分大小寫的
解決: 在第二個/後加後綴i, ignore
問題2: 只能返回位置i,無法返回敏感詞的內容 - 查詢敏感詞的內容: 2種情況:
- 只查看第一個敏感詞的內容和位置:
var arr=str.match(/正則/i);
在str中查找第一個符合正則要求的敏感詞的內容和位置
返回值: 如果找到: arr:[ 0:“敏感詞”, index: 位置i ]
補充: js中其實一切都是關聯數組
如果找不到: 返回null
強調: 如果一個函數有可能返回null,都要先驗證不是null,再使用。
問題: 正則表達式默認只找到第一個就退出
解決: 在第二個/後加後綴g, global(全部) - 查找所有敏感詞的內容:
var arr=str.match(/正則/ig)
在str中查找所有符合正則要求的敏感詞的內容
返回值: 如果找到: arr: [ 敏感詞1, 敏感詞2,… ]
如果沒找到,返回null
問題: 只能獲得內容,無法獲得位置
- 只查看第一個敏感詞的內容和位置:
- 查找每個敏感詞的內容和位置: reg.exec()
1.4.2 替換
- 簡單替換: 將所有敏感詞都替換爲統一的新值:
str=str.replace(/正則/ig,“新值”)
查找str中符合正則要求的所有敏感詞,替換爲統一的新值
強調: 所有字符串API是無權直接修改原字符串,總是返回新字符串作爲處理結果,所以必須用變量接住返回的新字符串。 - 高級替換: 可根據每次找到的敏感詞不同,動態生成替換的新值
str=str.replace(/正則/ig,function(kword){
return 新值
});
查找str中每個符合正則要求的敏感詞,每找到一個敏感詞,就自動調用一次回調函數。每次調用時,都自動傳入本次的敏感詞作爲參數kword,再將返回的新值,替換回字符串中。
衍生操作: 刪除找到的敏感詞,其實就是替換爲""
1.4.3 切割
將一個字符串按指定的分隔符切割爲多段子字符串:
- 簡單切割: 切割符是固定的:
回顧: var arr=str.split(“切割符”) - 複雜切割: 切割符不是固定的
var arr=str.split(/正則/)
2 函數Function
2.1 Function對象
函數在JavaScript中以對象形式存在,函數名的本質是變量,指向Function對象的引用。有三種創建方式:
-
直接量聲明
function 函數名(形參列表){ 函數體; return 返回值; }
問題: 會被聲明提前
解決: 改聲明方式爲賦值方式 -
賦值
var 函數名=function (形參列表){ 函數體; return 返回值; }
優點: 因爲是賦值方式,不會被聲明提前
揭示了js中函數的本質:- 函數其實也是一個保存一段代碼的對象;
- 函數名其實只是一個普通的變量而已。函數名變量通過函數對象的地址引用着函數對象。所以使用函數名變量等效於使用函數對象本身。
-
用new Function構造函數創建函數對象:
var 函數名=new Function(“形參1”,“形參2”,…,“函數體”)
效率遠不如直接使用function關鍵字定義函數(字符串需要再次解析),但方法體是字符串,可以在運行時動態創建修改執行
垃圾回收:引擎會自動檢測不再使用的對象,並自動釋放內容空間,因爲內存容量極其有限;垃圾回收器是專門檢測並回收垃圾對象的小程序,伴隨主程序執行而並行執行,當對象不再被任何變量引用就自動釋放,不再使用的對象,要將其賦值爲null
2.2 閉包
2.2.1 匿名函數
如果一個函數只使用一次,不會重用時,都要用匿名函數
非匿名函數在定義時就已創建函數對象和作用域鏈對象,所以未被調用也佔用內存空間。
匿名函數:定義時未指定函數名的函數,僅在調用時臨時創建函數對象和作用域鏈對象,並在調用完後立刻釋放。
- 回調函數:自己定義給其它函數調用;
- 匿名函數自調:定義函數後立刻執行;幾乎所有js代碼都裝在匿名函數自調中,避免使用全局變量造成全局污染;
(function(參數列表){ 函數體; return 返回值 })(參數值列表) 第一個圓括號相當於返回函數地址
匿名函數比非匿名函數更節省內存空間
2.2.2 作用域和作用域鏈
作用域scope:程序中定義變量的使用範圍,避免函數內外的變量間相互干擾。可分爲全局作用域和函數作用域,優先使用局部變量,函數對象使用scope屬性指向自己所在的作用域。
作用域鏈scope chain:由多級作用域逐級引用形成的鏈式結構(專門保存函數可用變量存儲位置的對象);每個函數對象都對應一個作用域鏈對象
2.2.3 閉包
閉包:重用變量,保護變量不被篡改的機制。全局變量可重用,但隨處可用且易被篡改;局部變量不可重用。
閉包的三個步驟:
- 用外層函數包裹受保護的變量和內層函數;
- 外層函數將內層函數對象返回到外部:三種方式(1.return;2.給全局變量賦值;3.內層函數包裹在數組/對象中返回);
- 調用外層函數獲得內層函數的對象;
形成原因:外層函數的函數作用域對象無法釋放,所以內層函數比普通函數佔用更多內存空間(外層函數的作用域AO);
尋找閉包:找受保護的變量(外層函數的局部變量);找外層函數返回的內層函數(一次外層函數調用返回的內層函數共用同一個閉包中受保護的變量)
不再使用閉包應立刻釋放閉包結構
結合匿名函數調用閉包的外層函數:
var zan = (function(){
var n=0;
return function () {
n++;
document.write(`共${n}贊`);
}
})();