目錄
## 一、操作表單
### 1、快速獲取表單元素
form.name值
```html
<form action="#">
請輸入姓名: <input type="text" name="userName" id=""><br>
請輸入密碼: <input type="password" name="pass" id=""><br>
性別: <input type="radio" name="nan" id="" group="sex">男
<input type="radio" name="nv" id="" group="sex">女<br>
愛好:
<input type="checkbox" name="basketball" id="" group="hobby"> 打籃球
<input type="checkbox" name="itworker" id="" group="hobby"> 寫代碼
<input type="checkbox" name="study" id="" group="hobby"> 學習
<input type="checkbox" name="LOL" id="" group="hobby"> 英雄聯盟
</form>
```
```javascript
// 快速獲取表單元素的方法: form.name值
var form = document.getElementsByTagName('form')[0];
console.log(form);
console.log(form.userName);
console.log(form.pass);
console.log(form.nan);
console.log(form.LOL);
```
### 2、表單事件
1. 提交: onsubmit
1. 在表單提交的時候會觸發這個事件
2. 如果這個事件返回true表示可以提交, 如果返回false表示阻止提交
3. 事件加給form元素
2. 重置: onreset
1. 在表單提交的時候會觸發這個事件
2. 如果這個事件返回true表示重置, 如果返回false表示阻止重置
3. 事件加給form元素
3. 聚焦: onfocus
4. 失焦: onblur
3.4添加給表單元素, 3在表單的文本選中的時候觸發這個事件, 4在表單的文本失去焦點的時候觸發這個事件
```javascript
form.onsubmit = function(){
if(form.userName.value == '' || form.pass.value == ''){
alert('請輸入賬號和密碼');
return false;
} else {
return true;
}
}
form.onreset = function(){
// console.log('重置了');
if(confirm('是否重置')){
return true;
} else {
return false;
}
}
form.pass.onfocus = function(){
// 判斷當前輸入框是否可輸入
console.log(1);
}
form.pass.onblur = function(){
// 密碼校驗、文本輸入是否正確
console.log(2);
}
```
### 3、表單方法
1. submit(): 加給form元素, 將指定的form元素提交
2. reset(): 加給form元素, 將指定form元素重置
3. focus(): 表單元素, 將指定的表單元素獲取焦點
4. blur(): 表單元素, 將指定的表單元素失去焦點
5. select(): 表單元素, 讓form中的表單元素被選中
```javascript
var div = document.getElementsByTagName('div')[0];
div.onclick = function(){
// 提交
// form.submit();
// 重置
// form.reset();
// 獲取焦點, 一次只能聚焦一個
form.pass.focus();
// form.userName.focus();
}
setTimeout(function(){
// form.pass.blur();
// 表單元素被選中, 一次只能選中一個
// form.pass.select();
form.nan.select();
}, 5000);
```
## 二、系統對話框
### 1、alert(彈出的內容): 警告框
### 2、帶有確認按鈕的對話框
- confirm(要彈出的內容), 具有返回值, 點擊確定返回true, 點擊取消返回false
### 3、帶有輸入框的對話框
- prompt(提示內容, 默認值), 具有返回值, 點擊確定, 返回的是輸入框中的內容, 點擊取消返回null
### 4、打印預覽: print();
### 5、查找: find(要查找的字符);
```javascript
// window: 窗口, window和document的關係:窗口包含文檔
// window.alert(1);
var a1 = 1;
// console.log(window);
// 系統對話框
// 1. alert(彈出的內容): 警告框
// 2. 帶有確認按鈕的對話框: confirm(要彈出的內容), 具有返回值, 點擊確定返回true, 點擊取消返回false
// var sm = confirm('這是一個新頁面, 你知道了嗎?');
// console.log(sm);
// 3. 帶有輸入框的對話框: prompt(提示內容, 默認值), 具有返回值, 點擊確定, 返回的是輸入框中的內容, 點擊取消返回null
// var s = prompt('當前你想跳轉到第幾頁', '');
// console.log(s);
// 4. 打印預覽: print();
var btn = document.getElementsByTagName('button')[0];
btn.onclick = function(){
// print();
// find(1);
find('a');
}
// 5. 查找: find(要查找的字符);
```
## 三、瀏覽器相關
### 1、open與close
1. open: 打開新窗口; open(url, 打開窗口的方式, 特殊字符串, 是否取代之前的網頁的瀏覽記錄); 返回新窗口的window
_self: 自身打開 _blank: 打開新的頁面
```javascript
var newWindow = open('a.html', '_blank', 'width=800px,height=800px;');
```
2. close: 關閉瀏覽器 window.close(); 關閉當前瀏覽器可以省略window
```html
<!-- 行間, window不能省略 -->
<div οnclick="window.close();">關閉</div>
```
```javascript
newWindow.close();
close();
```
### 2、location
location: 最有用的BOM對象之一, 存儲有關當前窗口加載的文檔的信息, 還有一些導航功能, 既是window的對象屬性, 也是document的對象屬性
```javascript
console.log(location);
console.log(location.hash); // 地址中的hash值, #content(#後面的內容), 如果沒有, 返回空字符
console.log(location.host); // 服務器的名稱+端口
console.log(location.hostname); // 服務器名稱
console.log(location.port); // 端口
console.log(location.protocol); // 協議
console.log(location.href); // 完整地址
console.log(location.toString()); // 返回完整地址
console.log(location.search); // 獲取到?後面的查詢字符串(以?開頭的字符串)
// 改變地址,跳轉頁面
location.href = 'https://www.baidu.com';
```
### 3、navigator
appCodeName 瀏覽器的名稱。通常都是Mozilla,即使在非Mozilla瀏覽器中也是如此
appMinorVersion 次版本信息
appName 完整的瀏覽器名稱
appVersion 瀏覽器的版本。一般不與實際的瀏覽器版本對應
buildID 瀏覽器編譯版本
cookieEnabled 表示cookie是否啓用
cpuClass 客戶端計算機中使用的CPU類型(x86、68K、Alpha、PPC或Other)
javaEnabled() 表示當前瀏覽器中是否啓用了Java
language 瀏覽器的主語言
mimeTypes 在瀏覽器中註冊的MIME類型數組
onLine 表示瀏覽器是否連接到了因特網
opsProfile 似乎早就不用了。查不到相關文檔
oscpu 客戶端計算機的操作系統或使用的CPU
platform 瀏覽器所在的系統平臺
plugins 瀏覽器中安裝的插件信息的數組
preference() 設置用戶的首選項
product 產品名稱(如 Gecko)
productSub 關於產品的次要信息(如Gecko的版本)
systemLanguage 操作系統的語言
taintEnabled() 已經廢棄, 表示是否允許變量被修改(taint)。爲了與Netscape Navigator 3向後兼容而保留下來
userAgent 瀏覽器的用戶代理字符串
userLanguage 操作系統的默認語言
userProfile 藉以訪問用戶個人信息的對象
vendor 瀏覽器的品牌
vendorSub 有關供應商的次要信息
### 4、history
1. 向前進: history.forword(); 向前跳轉一個頁面
2. 向後退: history.back(); 向後退一個頁面
3. 跳轉到: history.go(參數); 參數爲數字, 跳轉到第幾個頁面, 正數--> 前 負數--->後 0--->刷新
```javascript
history.forward();
history.go(1);
history.go(0);
history.back();
```
### 5、client
元素可視寬高
clientHeight/clientWidth: height/width + 上下/ 左右padding
clientTop: 上邊框
clientLeft: 左邊框
```javascript
var div = document.getElementsByTagName('div')[0];
console.log(div.clientHeight); // 200 + 20 + 5
console.log(div.clientWidth); // 200 + 10 + 1
console.log(div.clientTop);
console.log(div.clientLeft);
// 屏幕的可視寬高:
console.log(document.documentElement.clientHeight);
console.log(document.documentElement.clientWidth);
// body的可視寬高
console.log(document.body.clientHeight);
console.log(document.body.clientWidth);
```
### 5、client
元素可視寬高
clientWidth/clientHeight: padding + content
clientTop: 上邊框
clientLeft: 左邊框
### 6、offset
元素的佔位(實際)寬高
元素.offsetWidth/元素.offsetHeight: padding + content + border
元素.offsetTop: 當前元素的頂部到定位父元素頂部的距離, 如果沒有定位父元素, 到body頂部的距離;
元素.offsetLeft: 當前元素的左邊到定位父元素左邊的距離, 如果沒有定位父元素, 到body左邊的距離;
```javascript
console.log(div.offsetHeight); // 20 + 5 + 200 + 20 + 20
console.log(div.offsetWidth); // 251
console.log(div.offsetTop);
console.log(div.offsetLeft);
```
### 7、scroll
頁面/元素被捲去的高度
元素.scrollWidth/元素.scrollHeight: 元素實際內容的寬高
元素.scrollTop: 頁面/元素被捲去的高度
元素.scrollLeft: 頁面/元素被捲去的寬度
onscroll: 窗口滾動條滾動時所觸發的事件
頁面滾動的距離:
document.documentElement.scrollTop || document.body.scrollTop
document.documentElement.scrollLeft || document.body.scrollLeft
```javascript
window.onscroll = function(){
// console.log(document.documentElement.scrollTop);
// console.log(document.body.scrollTop);
var top = document.documentElement.scrollTop || document.body.scrollTop;
var left = document.documentElement.scrollLeft || document.body.scrollLeft;
console.log(top, left);
}
```
### 8、resize
當窗口大小發生改變的時候,會觸發這個函數
```javascript
window.onresize = function(){
console.log(1);
}
```
## 四、事件
### 1、事件處理函數
1. 事件處理函數: 當事件發生時所調用的函數
2. div.onlick = function(){} onlick後面的就是事件處理函數
3. div.onclick = a; a就是事件處理函數
```javascript
var div = document.getElementsByTagName('div')[0];
// div.onclick = function () {
// alert(1);
// }
function a(){
alert(2);
}
div.onclick = a;
```
2. 事件對象
1. 事件對象: 當事件發生的時候, 瀏覽器會將事件相關的信息(事件類型, 觸發源, 鼠標的位置, 距離各個屏幕、元素的位置等等)存儲在事件對象中, event
2. ie\chrome\高版本ff: window.event
3. 低版本ff: 事件處理函數的第一個參數傳遞
4. 兼容: var evs = window.event || ev;
5. 常用屬性
```javascript
var evs = window.event || ev;
console.log(evs);
console.log(evs.type); // 事件類型
console.log(evs.target); // 事件觸發源, ie8+
console.log(evs.srcElement); // 事件觸發源
console.log(evs.target || evs.srcElement);
console.log(evs.clientX, '------', evs.clientY); // 鼠標相對於屏幕的位置
console.log(evs.pageX, '-----', evs.pageY); // 鼠標相對於body的距離
console.log(evs.ctrlKey, evs.altKey, evs.shiftKey); // 判斷相對應的鍵是否被按下, 返回true和false
```
3. 事件綁定
1. 標籤.事件 這種方式所添加的事件, 如果給同一個元素添加同一個事件, 那麼後面的會覆蓋前面的;
2. 事件綁定:
1. 標準: 標籤.addEventListener(事件類型(不加on), 事件處理函數(函數名), 是否捕獲(默認false));
```javascript
function a(){
console.log(1);
}
function b(){
console.log(2);
}
div.addEventListener('click', a, false);
div.addEventListener('click', b, false);
```
2. ie: 標籤.attachEvent(on+事件類型, 事件處理函數);
```javascript
// ie
console.log(div.attachEvent); // 標準: undefined
div.attachEvent('onclick', a);
div.attachEvent('onclick', b);
```
3. 區別:
1. 事件類型: 標準不加on,ie要加on
2. 標準中有捕獲, ie中沒有
3. 標準中執行順序是正序執行, ie中是倒敘執行
4. this的指向不同: 標準中指向觸發源, ie中指向window
3. 事件解綁
1. 標籤.事件 取消事件: 標籤.事件 = null;
2. 事件解綁
+ 標準: 標籤.removeEventListener(事件類型(不加on), 事件處理函數(函數名), 是否捕獲(默認false));
+ ie: 標籤.detachEvent(on+事件類型, 事件處理函數);
```javascript
if(div.removeEventListener){
// 標準
div.removeEventListener('click', a, false);
} else {
// ie
div.detachEvent('onclick', a);
}
```
### 2、事件流
1. 事件流
事件流: 當事件發生的時候, 從父節點到子節點之間固定的執行順序
事件捕獲階段:當事件發生的時候, 將事件從window向子元素依次傳遞
確定目標階段: 確定事件目標
冒泡處理階段: 事件目標開始處理事件, 處理完成之後將事件從子元素依次傳遞到父元素, 到window結束
2. 阻止冒泡
標準: evs.stopPropagation();
ie: evs.cancelBubble = true;
兼容:
evs.stopPropagation ? evs.stopPropagation() : evs.cancelBubble = true;
一個加()一個不加(), 兼容就用帶()來判斷
```javascript
var divs = document.getElementsByTagName('div');
function a(ev){
var evs = event || ev;
console.log(evs.stopPropagation); // ie undefined
console.log(this);
// evs.stopPropagation();
// evs.cancelBubble = true;
evs.stopPropagation ? evs.stopPropagation() : evs.cancelBubble = true;
}
/*
阻止冒泡:
標準: evs.stopPropagation();
ie: evs.cancelBubble = true;
兼容:
evs.stopPropagation ? evs.stopPropagation() : evs.cancelBubble = true;
一個加()一個不加(), 兼容就用帶()來判斷
*/
divs[0].onclick = a; //不是捕獲就是冒泡
divs[1].onclick = a;
divs[2].onclick = a;
```
3. 阻止默認事件
標籤.事件 return false;
綁定:
標準: evs.preventDefault();
ie: evs.returnValue = false;
兼容:
evs.preventDefault ? evs.preventDefault() : evs.returnValue = false;
```javascript
ujiuye.bind(document, 'contextmenu', function(ev){
console.log(1);
var evs = event || ev;
// return false;
// evs.preventDefault();
// evs.returnValue = false;
evs.preventDefault ? evs.preventDefault() : evs.returnValue = false;
});
```
### 3、鍵盤事件
按下:onkeydown
擡起: onkeyup
長按: onkeypress
1. onkeypress與onkeydown:
1. down: 特殊鍵會觸發函數, press: 非特殊鍵(0-9, a-z)
2. down: 始終返回大寫字母的ASCII值, press: 區分大小寫
3. down: 按住特殊鍵會一直輸出, shift + 1 ---> 16 + 49 shift + 1
press: 按住特殊鍵不會一直輸出, shift+1----> 33 !
```javascript
document.onkeydown = function(ev){
var evs = event || ev;
// // console.log(1);
// console.log(evs); // KeyboardEvent
// console.log(evs.key); // 具體的按鍵, ie--->undefined
// console.log(evs.keyCode); // 按鍵的ASCII值
}
document.onkeyup = function(){
// console.log(2);
}
document.onkeypress = function(){
var evs = event || ev;
// console.log(1);
// console.log(evs); // KeyboardEvent
// console.log(evs.key); // 具體的按鍵, ie--->undefined
console.log(evs.keyCode); // 按鍵的ASCII值
}
```
### 4、滾輪事件
chrome\ie: onmousewheel
```javascript
document.onmousewheel = function(ev){
var evs = event || ev;
// console.log(evs);
console.log(evs.wheelDelta); // 上: 120 | 正數 下: -120 | 負數
}
```
ff: 必須使用事件綁定的方式來監聽, 標籤.addEventListener('DOMMouseScroll', 事件處理函數);
```javascript
if (document.addEventListener) {
// ff/chrome
document.addEventListener('DOMMouseScroll', function (ev) {
var evs = event || ev;
// console.log(evs);
console.log(evs.detail); // 上: -3 | 負數 下: +3 | 正數
});
}
```
### 5、事件代理
事件代理: 事件委託, 將子元素本來要做的事情交給父元素, 找到對應子元素後, 由子元素進行後續事件操作
```java
var ul = document.getElementsByTagName('ul')[0];
ul.onclick = function(ev){
var evs = event || ev;
console.log(evs);
var target = evs.target || evs.srcElement;
console.log(target);
if(target.nodeName == 'LI'){
// alert(this.innerText); // this事件處理函數中, 點誰就誰
console.log(target.innerText);
}
}
```
優勢: 元素可以發生在未來
```javascript
// var li = document.createElement('li');
// li.innerText = '12345';
// ul.appendChild(li);
ul.innerHTML += '<li>12345</li>';
```
## 五、cookie
### 1、概念
1. cookie: 是瀏覽器在訪問服務器之後, 服務器傳給瀏覽器的一段數據.瀏覽器需要保存這段數據, 在每次請求的時候, 都必須帶上這段數據, 一般是不會輕易刪除。
cookie: 指小量信息, 只能存儲4kb, 由web服務器創建, 存儲在用戶計算機中.
2. 優點:
+ 由web服務器創建, 存儲在本地的少量數據, 只有4kb
+ 谷歌和歐朋不支持本地存儲
+ 沒有過期時間, 一般默認瀏覽結束就銷燬cookie
3. 缺點
+ 存儲容量有限, 只有4kb
+ 由明文傳遞, 容易被竊取和盜用
+ cookie每次請求的時候都會自動添加到請求頭Request Header, 增加容量
### 2、存儲
1. 存儲: document.cookie = 'key=value';
2. 注意:一次只能存儲一個cookie, 如果key相同, 後面的value會覆蓋前面的
```javascript
document.cookie = 'userName=123456';
document.cookie = 'pass=123456';
document.cookie = 'userName=ujiuye';
```
### 3、獲取: document.cookie
```javascript
document.cookie = 'age=12';
// 獲取: document.cookie
var cookie = document.cookie;
// 每兩組之間分割符: '; '
console.log(cookie); // pass=123456; userName=ujiuye; age=12
```
### 4、刪除cookie: 讓一個cookie的過期時間變成過去時間
如何設置cookie的過期時間: document.cookie = 'key=value;expires=時間'
```javascript
var date = new Date();
date.setSeconds(date.getSeconds() + 10);
console.log(date.toGMTString());
document.cookie = 'height=180;expires=' + date.toGMTString();
// setInterval(function(){
// console.log(document.cookie);
// }, 1000);
```
## 六、正則
### 1、概念:
正則: 是對字符串操作的邏輯公式, 就是用事先定義好的一些特殊字符, 及特殊字符的組合, 組成一個規則字符串, 對字符串添加一種過濾邏輯。
簡單來說: 規定文本檢索的內容, 通常用來替換、檢索文本。
### 2、創建
1. 構造函數創建: new RegExp('要匹配的字符或者規則', '修飾符')
```javascript
var reg = new RegExp('o', 'ig');
console.log(reg);
```
2. 字面量創建: /要匹配的字符或規則/修飾符;
```javascript
var reg1 = /o/ig;
console.log(reg1);
```
### 3、修飾符:
1. g: global, 全局匹配
2. i: ignore case, 忽略大小寫
4. 字符串方法
1. 字符串.replace(要匹配字符/正則, 替換字符);
```javascript
var str = '123456123456123123123';
var s = str.replace('1', 'a');
console.log(s);
var reg = /1/;
var reg1 = /1/g;
console.log(str.replace(reg, 'a')); // a23456123456123123123
console.log(str.replace(reg1, 'a')); // a23456a23456a23a23a23
var str = '1234aaa561AAA234561aaa23123123';
var reg = /a/g;
var reg1 = /a/ig;
console.log(str.replace(reg, '。')); // 1234。。。561AAA234561。。。23123123
console.log(str.replace(reg1, '。')); // 1234。。。561。。。234561。。。23123123
```
2. 字符串.split('分割符/正則');
```javascript
var str = 'zabczdefg12345zzz123z123z';
var reg = /z/ig;
console.log(str.split(reg)); // ["", "abc", "defg12345", "", "", "123", "123", ""]
```
3. 字符串.match(字符/正則); 挑選符合條件的字符組成數組返回
```javascript
var str = '1q2w3e4r5t6y7u8i9o0p';
var reg = /\d/ig; // \d數字
console.log(str.match(reg)); // ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
```
4. 字符串.search(正則)
```javascript
var str = 'q2w3e4r5t6y7u8i9o0p';
var reg = /\d/ig;
console.log(str.indexOf('1')); // 明確的字符
console.log(str.search(reg));
```
### 4、正則驗證方法:
正則驗證方法: 一次匹配一項,每次驗證如果沒有加g, 每次都從0開始, 如果加了g, 每次從上一次查詢到的地方開始
1. test: 返回布爾值, true--匹配成功, false---匹配失敗 正則.test(字符串);
```javascript
var str = '1q2w3e';
var reg = /\d/ig;
console.log(reg.lastIndex); // 返回本次檢驗開始的位置下標 0
console.log(reg.test(str));
console.log(reg.lastIndex); // 返回本次檢驗開始的位置下標 1
console.log(reg.test(str));
console.log(reg.lastIndex); // 返回本次檢驗開始的位置下標 3
console.log(reg.test(str));
console.log(reg.lastIndex); // 返回本次檢驗開始的位置下標 5
console.log(reg.test(str)); // false
console.log(reg.lastIndex); // 0
console.log(reg.test(str));
```
2. exec: 具體的檢索, 返回能匹配上的數組, null--匹配不上
正則.exec(字符串);
```javascript
console.log(reg.lastIndex); // 0
console.log(reg.exec(str)); // ["1", index: 0, input: "1q2w3e", groups: undefined]
console.log(reg.lastIndex); // 1
console.log(reg.exec(str)); // ["2", index: 2, input: "1q2w3e", groups: undefined]
console.log(reg.lastIndex); // 3
console.log(reg.exec(str));
console.log(reg.lastIndex); // 5
console.log(reg.exec(str)); // null
console.log(reg.lastIndex); // 0
console.log(reg.exec(str));
```
### 5、元字符
1. .(點): 匹配除換行以外的所有字符
```javascript
var str = '\n123';
var reg = /./ig;
console.log(reg.exec(str));
```
2. []: 要匹配的字符, 寫在[]中的,任何一個都是要匹配的字符, 只要有一個匹配得上就會返回回來
```javascript
var str = "'123a'";
var reg = /[ab']/ig;
console.log(reg.exec(str));
```
[^] 不要匹配的字符集]
```javascript
var reg = /[^'a]/ig;
console.log(reg.exec(str));
```
3. \d: 匹配數字 \D: 匹配非數字
```javascript
var str = 'web123';
var reg = /\d/ig;
var reg1 = /\D/ig;
console.log(reg.exec(str));
console.log(reg1.exec(str));
```
4. \s: 匹配空格 \S: 匹配非空格
```javascript
var str = 'web 123';
var reg = /\s/ig;
var reg1 = /\S/ig;
console.log(reg.exec(str));
console.log(reg1.exec(str));
```
5. \w: 匹配數字、字母、_ \W: 匹配非數字、字母、_
```javascript
var str = '_1web.123';
var reg = /\w/ig;
var reg1 = /\W/ig;
console.log(reg.exec(str));
console.log(reg1.exec(str));
```
6. \b: 匹配單詞邊界 \B: 匹配非單詞邊界
```javascript
var str = 'he is a boyisA';
var reg = /\bis\b/ig;
var reg1 = /\Bis/ig;
console.log(reg.exec(str));
console.log(reg1.exec(str));
```
7. ^: 以什麼爲開頭 $: 以什麼爲結尾
```javascript
var str = 'web123';
var reg = /^[a-zA-Z]/ig; // 以字母a-zA-Z開頭
var reg1 = /\d$/ig;
console.log(reg.exec(str));
console.log(reg1.exec(str));
```
### 7、多個字符
1. a?: 匹配一個或者是0個
2. a*: 匹配0個或者連續多個a, 儘可能多的去匹配‘
3. a+: 匹配至少一個, 並且儘可能多的匹配
4. a{n,m}: 至少匹配n次,至多匹配m次
a{n,}: 至少匹配n次, 至多不限制
a{n}: 只匹配n次
```javascript
// a?: 匹配一個或者是0個
var str = 'web12332232a3232';
var reg = /\d?/ig; // 匹配0個或者一個數字
console.log(reg.exec(str));
// a*: 匹配0個或者連續多個a, 儘可能多的去匹配
var reg = /\w*\d*/ig;
console.log(reg.exec(str));
// a+: 匹配至少一個, 並且儘可能多的匹配
var str = 'web12332232a3232';
var reg = /[a-z]+\d+/ig;
console.log(reg.exec(str));
// a{n,m}: 至少匹配n次,至多匹配m次
var str = 'webweb123123';
var reg = /[a-z]{1,3}\d{3,6}/ig;
console.log(reg.exec(str));
// a{n,}: 至少匹配n次, 至多不限制
var reg = /[a-z]{1,}\d{3,6}/ig;
console.log(reg.exec(str));
// a{n}: 只匹配n次
var reg = /[a-z]{1}\d{3,6}/ig;
console.log(reg.exec(str));
```
5. 特殊字符
1. |: 或
2. (): 分組
```javascript
var str = 'webweb123';
var reg = /web(\d+)(2|3)/ig; // 判斷web後面跟的是1或者是2的web返回回來
console.log(reg.exec(str));
console.log(RegExp.$1); // 第一個括號
console.log(RegExp.$2); // 第二個括號
```
3. |: 或
4. (): 分組
5. (?:): 正向的非獲取匹配
6. (?=): 正向肯定預查
7. (?!): 正向否定預查
8. (?<=): 反向肯定預查
9. (?<!): 反向否定預查
```javascript
// 非獲取匹配: (?:)(?=)(?!=)(?<=)(?<!)
// (?:): 正向的非獲取匹配
var str = 'webbweb123weba';
var reg = /web(?:1|3|b)/ig;
console.log(reg.exec(str));
// (?=): 正向肯定預查
var str = 'webbweb123weba';
var reg = /web(?=\d+)/ig; // 獲取後面跟數字的web
console.log(reg.exec(str));
// (?!=): 正向否定預查
var str = 'webbweb123weba';
var reg = /web(?!\d+)/ig; // 獲取後面不跟數字的web
console.log(reg.exec(str));
// (?<=): 反向肯定預查
var str = '1webbweb123weba';
var reg = /(?<=\d+)web/ig; // 獲取前面跟數字的web
console.log(reg.exec(str));
// (?<!): 反向否定預查
var str = '1webbweb123weba';
var reg = /(?<!\d+)web/ig; // 獲取前面不跟數字的web
console.log(reg.exec(str));
```
## 七、面向對象
1. 兩種編程模式
面向過程: 注重過程
面向對象: 注重結果
2. 對象的特徵: 封裝 多態 繼承
3. 對象的組成:
屬性:靜態的, 對象的描述-----變量
方法:動態的, 對象的行爲-----函數
### 1、js中的對象
原生對象: String Number Boolean Object Array Function Date RegExp Error
內置對象: Math\Global(全局,window.document)
宿主對象: DOM BOM
全局對象: window
### 2、創建方式
1. 字面量創建:var 變量名 = { 屬性名: 屬性值}
```javascript
var obj = {
'name': '彭于晏',
'height': 180,
'tip': function(){
console.log('會掙錢');
}
};
// 獲取屬性
console.log(obj.name);
// 調用方法
obj.tip();
// 適用於單個對象的創建
```
2. 實例創建
```javascript
var obj1 = new Object();
obj1.name = '彭于晏';
obj1.tip = function(){
console.log('會掙錢');
}
console.log(obj1);
console.log(obj1.name);
obj1.tip();
// 代碼冗餘
```
3. 工廠模式創建
```javascript
function cObj(name,sex) {
var obj1 = new Object();
obj1.name = name;
obj1.sex = sex;
obj1.tip = function () {
console.log('會掙錢');
}
return obj1;
}
var obj = cObj('彭于晏', '男');
var obj1 = cObj('彭于晏2號', '男');
console.log(obj, obj1);
obj.tip();
obj1.tip();
var arr = [123,123];
console.log(typeof obj);
console.log(typeof arr);
// instanceof: 要檢驗的數據 instanceof 是否由Object創建
console.log(obj instanceof Object); // true
console.log(obj instanceof cObj); // false
// 問題: 識別不清
```
4. 構造函數創建
構造函數的特點:
\1. 函數名首字母大寫(不是必須, 爲了和普通函數區別, 是約定)
\2. 構造函數調用前面必須要有new, 不加和普通函數一樣
\3. 屬性和方法直接加在this上
new的時候會發生的事情:
\1. 創建一個空對象
\2. 將空對象的__proto__指向構造函數的原型對象的prototype
\3. this指向空對象, 添加屬性和方法, 隱式返回
原型: __proto__, 原型是當對象創建的時候就自帶的屬性, 用來存儲最頂層共享的屬性和方法
```javascript
// 1. 構造函數創建
function CreateObj(name, sex) {
// var obj1 = new Object();
this.name = name;
this.sex = sex;
this.tip = function () {
console.log('會掙錢');
}
// return this;
}
// 2. 實例化對象
var obj = new CreateObj('彭于晏', '男');
var obj1 = new CreateObj('彭于晏2號', '男');
console.log(obj, obj1);
console.log(obj.tip == obj1.tip); // false
// 問題: 內存浪費
```
5. 原型創建
1. 原型
+ 原型對象: prototype: 原生對象身上用來存儲共享的屬性和方法的對象就是原型對象
+ 原型屬性: __proto__, 原型是當對象創建的時候就自帶的屬性, 用來存儲最頂層共享的屬性和方法
+ 修改原型對象方法, 共享效果
```javascript
// 1. 原型對象: prototype: 原生對象身上用來存儲共享的屬性和方法的對象就是原型對象
console.log(Array.prototype);
// console.log(Date.prototype);
// 2. 原型屬性: __proto__, 原型是當對象創建的時候就自帶的屬性, 用來存儲最頂層共享的屬性和方法
var arr = new Array(1,2,3);
console.log(arr.__proto__);
console.log(arr.__proto__ == Array.prototype); // true
// 修改原型對象方法, 共享效果
arr.push(1);
console.log(arr);
Array.prototype.push = function(){
console.log(1);
}
arr.push(9);
console.log(arr);
```
2. 原型創建對象
```javascript
// 1. 原型創建
function CreateObj(name, sex) {
CreateObj.prototype.name = "彭于晏";
CreateObj.prototype.sex = "男";
CreateObj.prototype.tip = function(){
console.log('掙錢');
}
}
var obj = new CreateObj('彭昱暢', '男');
var obj1 = new CreateObj('彭昱暢2號', '男');
console.log(obj, obj1);
console.log(obj.tip == obj1.tip); // true
// 不能傳參
```
6. 混合創建
```javascript
// 混合創建: 構造函數(可變的) + 原型創建(不變的, 共享)
// 混合創建
function CreateObj(name, sex) {
this.name = name;
this.sex = sex;
CreateObj.prototype.tip = function () {
console.log('掙錢');
}
}
var obj = new CreateObj('彭于晏', '男');
var obj1 = new CreateObj('彭昱暢', '男');
console.log(obj, obj1);
obj.tip();
obj1.tip();
console.log(obj.tip == obj1.tip); // true
console.log(obj.tips); // true
```
## 八、面向對象繼承
1. 原型鏈: js中屬性和方法的查找方式, 先找對象自身, 再找原型屬性__proto__(原型對象), 父級的原型屬性, 找到null上, 找不到返回報錯undefined
2. 命名空間:
```javascript
var nav = '導航';
// 當項目足夠大的時候, 分組作業、使用很多第三方庫, 命名不夠用
var home = {}; // 用來存儲所有首頁的變量
home.nav = {}; // 用來存儲導航(首頁)d的變量
home.nav.title = '這是導航';
```
3. this的指向
this: 存在於全頁面, 在不同位置有不同的含義
全局---window
普通函數---window
事件函數---觸發源
構造函數---創建的新對象
4. 改變this指向
1. call: 函數.call(this的指向, 實參1, 實參2, ....);
2. apply: 函數.apply(this的指向, [實參1, 實參2, ...]);
3. 注意: 直接在函數調用的時候改變this指向 區別: 傳參方式不同
4. bind: 函數1.bind(this的指向), 返回一個與函數1一致的函數, 需要調用返回值
```javascript
function fn(a,b){
console.log(this, a, b);
}
fn(10, 20); // window 10 20
// this--->document
fn.call(document, 2, 3);
fn.apply(1, [2, 3]);
var obj = {
'name': 1,
'sayName': function(){
console.log(this);
console.log(this.name);
}
}
var obj1 = {
'name': 2
}
// obj.sayName.call(obj1); // 2
var m = obj.sayName.bind(obj1);
m();
```
5. 原型鏈繼承
```javascript
// 父類構造函數
function Father(name, age){
this.name = name;
this.age = age;
this.arr = [1,2,3];
}
Father.prototype.tip = function(){
console.log('父愛如山');
}
// 子類構造函數
function Son(name, age){}
Son.prototype.tip = function(){
console.log('任性');
}
// 繼承操作: 子類構造函數的原型對象 = 父類構造函數的實例化對象(new 函數名)
Son.prototype = new Father('123', 32);
var obj = new Son('456', 12);
var obj1 = new Son('456', 12);
console.log(obj);
console.log(obj.name, obj.age, obj.arr);
console.log(obj1.name, obj1.age, obj1.arr);
obj1.arr.push(5);
console.log(obj.arr, obj1.arr); // [1, 2, 3, 5] [1, 2, 3, 5]
// 問題: 1. 不能傳參 2. 如果引用數據類型, 一改全改
```
6. 對象冒充繼承
```javascript
// 父類構造函數
function Father(name, age){ // a
this.name = name;
this.age = age;
this.arr = [1,2,3];
}
Father.prototype.tip = function(){
console.log('父愛如山');
}
// 子類構造函數
function Son(name, age){ // b
// 對象冒充
Father.call(this, name, age);
}
Son.prototype.tip = function(){
console.log('任性');
}
var obj = new Son('小明', 32);
var obj1 = new Son('小明2好', 22);
console.log(obj, obj1);
// 問題: 不能繼承父類構造函數原型對象上的屬性和方法
```
7. 混合繼承
```javascript
// 父類構造函數
function Father(name, age){ // a
this.name = name;
this.age = age;
this.arr = [1,2,3];
}
Father.prototype.tip = function(){
console.log('父愛如山');
}
// 子類構造函數
function Son(name, age){ // b
// 對象冒充
Father.call(this, name, age);
}
Son.prototype.tip = function(){
console.log('任性');
}
// 繼承操作: 子類構造函數的原型對象 = 父類構造函數的實例化對象(new 函數名)
Son.prototype = new Father();
var obj = new Son('小明', 32);
var obj1 = new Son('小明2好', 22);
console.log(obj, obj1);
```