JavaScript常見輸出
window.alert()? 彈出框警告
document.write()? 將內(nèi)容寫到HTML文檔中
innerHTML 寫入到HTML元素中
console.log() 控制臺輸出
1 函數(shù)中的arguments使用
每個函數(shù)內(nèi)部都有一個 arguments ,系統(tǒng)內(nèi)置的。
arguments是用來儲存實際傳入的參數(shù)
//求傳入任意數(shù)字的和?varsum=0;//求和的數(shù)functionsumFunction(){for(i=0;i<arguments.length;i++){//arguments.length代表當(dāng)前輸入已存儲參數(shù)的個數(shù)。sum+=arguments[i];}returnsum;}alert(sumFunction(1,2,3,4,5,6));
2 函數(shù)的作用域
任何程序運行時候都要占用空間,函數(shù)調(diào)用的時候也要去占用空間
垃圾回收機制:調(diào)用完函數(shù)之后,系統(tǒng)會分配對應(yīng)的空間給這個函數(shù)使用(空間大小一般由函數(shù)里聲明的變量和形參決定),當(dāng)函數(shù)使用完畢以后,這個內(nèi)存會被釋放,還給系統(tǒng)。
在函數(shù)內(nèi)部聲明的變量和形參是屬于當(dāng)前函數(shù)的內(nèi)存空間。
內(nèi)存管理機制:在函數(shù)中聲明的變量和形參,會隨著函數(shù)的調(diào)用被創(chuàng)建,隨著函數(shù)的調(diào)用結(jié)束而銷毀。在函數(shù)中聲明的變量和形參,有效范圍是當(dāng)前函數(shù)(當(dāng)前函數(shù)的大括號內(nèi)),作用域,局部作用域。
vara=10,b=20;// 聲明在全局的變量叫全局變量functionshow(a){varb=100;// 在函數(shù)內(nèi)部聲明,局部變量a+=5;alert(a+","+b);}
3 函數(shù)遞歸
滿足以下三個特點就是遞歸:
函數(shù)自己調(diào)用自己
一般情況有參數(shù)
一般情況下有return
注:遞歸可以解決循環(huán)能做的所有事情,有一些循環(huán)不容易解決的事情,遞歸也能解決。
//計算1~n的和?//正常函數(shù)寫法functionsum(n){varres=0;for(i=1;i<=n;i++){res+=i;}returnres;}alert(sum(100));//遞歸寫法/* 方法:1.首先去找臨界值,即無需計算,獲得的值。
? ? ? ? ? ? ? ? ? ? 2.找這一次和上一次的關(guān)系。
? ? ? ? ? ? ? ? ? ? 3.假設(shè)當(dāng)前函數(shù)已經(jīng)可以使用,調(diào)用自身算上一次。
? ? ? ? ? ? ? ? ? ? sum(100)== sum(99)+ 100;
? ? ? ? ? ? ? ? ? ? sum(n)== sum (n-1)+n;
? ? ? ? ? ? ? ? */functionsum(n){if(n==1){return1;}returnsum(n-1)+n;}alert(sum(100));
4 函數(shù)閉包
滿足以下特點的叫做閉包
函數(shù)嵌套函數(shù)
內(nèi)部函數(shù)使用外部的形參和變量
被引用的形參和變量就不會被 【垃圾回收機制所回收,使內(nèi)部函數(shù)的變量常駐內(nèi)存中】
window.onload=function(){//閉包實現(xiàn)按鈕遍歷完后,點擊按鈕輸出對應(yīng)的鍵值。varoBtn=document.getElementsByTagName("button");for(vari=0;i<oBtn.length;i++){oBtn[i].onclick=(function(index){returnfunction(){alert(index);}})(i);//這里的i相當(dāng)于傳入函數(shù)的參數(shù) 所以就是index就是等于i }/* 上面的是簡寫成立即執(zhí)行函數(shù)的閉包
? ? ? ? ? ? ? ? for(var i = 0;i < oBtn.length;i++){
? ? ? ? ? ? ? ? ? ? oBtn[i].onclick = btnClick(i);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //btnClick(0) index = 0
? ? ? ? ? ? ? ? function btnClick(index){
? ? ? ? ? ? ? ? ? ? return function(){
? ? ? ? ? ? ? ? ? ? ? ? alert(index);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? } */
5 數(shù)組方法
方法格式返回值說明
Math.random()var sum = Math.random() * 10數(shù)字隨機數(shù):? 隨機生成0 ~ 1之間的小數(shù)
push()數(shù)組.push(參數(shù)1,參數(shù)2,...)插完元素以后的數(shù)組的長度給數(shù)組的末尾添加元素
pop()數(shù)組.pop()? 不用傳參取下一個元素從數(shù)組末尾取下一個元素
shift()數(shù)組.shift()? 不用傳參取下的元素從數(shù)組頭部取下一個元素
unshift()數(shù)組.unshift(參數(shù)1,參數(shù)2,...)插完元素以后的數(shù)組的長度給數(shù)組的頭部插入元素
concat()數(shù)組.concat(數(shù)組,數(shù)據(jù),...)合并成的新數(shù)組,原數(shù)組不會改變拷貝原數(shù)組,生成新數(shù)組
slice()數(shù)組.slice(start, end)生成新數(shù)組原數(shù)組不會發(fā)生改變可以基于當(dāng)前數(shù)組獲取指定區(qū)域元素 [start, end] 提取出元素生成新數(shù)組
splice()數(shù)組.slice(開始截取的下標(biāo), 截取的長度,插入數(shù)據(jù)1,插入數(shù)據(jù)2...)截取下來的元素組成的數(shù)組對元素進(jìn)行增刪改
join()數(shù)組.join(字符串)拼接好的字符串將數(shù)組中的元素,用傳入的拼接符,拼接成一個字符串
reverse()數(shù)組.reverse()逆序后的數(shù)組,此方法會修改原數(shù)組數(shù)組逆序
sort()數(shù)組.sort()排序后的數(shù)組,此方法會修改原數(shù)組默認(rèn)從小到大排序,按照字符串排序
6 ECMA5新增數(shù)組方法
方法格式參數(shù)返回值說明
indexOf()數(shù)組.indexOf(item,start)item 任意數(shù)據(jù),start 小標(biāo),可以不傳,默認(rèn)為0-1 沒有查到,>= 0 查到元素的下標(biāo)在數(shù)組 中查找item元素下標(biāo)
forEach()數(shù)組.forEach(item,index){函數(shù)}item遍歷到的當(dāng)前數(shù)組的內(nèi)容,index遍歷到的當(dāng)前數(shù)組元素下標(biāo)item與index數(shù)組遍歷
map()數(shù)組.map(item, index, arr){函數(shù)}不會改變原數(shù)組,而是將里面函數(shù)執(zhí)行一次返回新數(shù)組遍歷當(dāng)前數(shù)組,然后調(diào)用參數(shù)中的方法
filter()數(shù)組.filter((item, index,array) => {函數(shù)})運行定義的函數(shù)后,返回符合的數(shù)組數(shù)組過濾
som()數(shù)組.some((item,index,arr) => {函數(shù)})有返回true,沒有返回false,只要找到符合條件的元素,后面的循環(huán)就停止了在數(shù)組中查找是否有符合內(nèi)容的元素
every()數(shù)組.every((item,index,arr) => {函數(shù)})有返回true,沒有返回false,只要找不到符合條件的元素,后面的循環(huán)就停止了在數(shù)組中查找是否有符合內(nèi)容的元素
reduce()歸并arr.reduce(prev, next, index, arr)prev第一次是 下標(biāo)為0的元素,第二次開始 上次遍歷retturn的值,next 從下標(biāo)1開始,當(dāng)前遍歷到的元素,arr數(shù)組本身
// reduce()歸并vararr=[34,65,33,87,24,56]varres=arr.reduce((prev,next,index,arr)=>{console.log(prev+","+next);returnprev+next})alert(res)
7 字符串方法
方法格式參數(shù)返回值說明
indexOf() 字符查找字符串.indexOf(text, start)text需要查找的字符串,start從哪里開始查找的下標(biāo)-1說明沒有找到查找text在字符串中的位置
lastIndexOf()字符串.lastIndexOf(text)text需要查找的字符串-1說明沒有找到查找text在字符串最后一次出現(xiàn)的位置
search()字符串.search(text)text需要查找的字符串或者 正則表達(dá)式-1說明沒有找到查找text在字符中第一次出現(xiàn)的位置
match()字符串.search(text)text需要查找的字符串或者 正則表達(dá)式null說明沒有找到匹配返回字符串中的所有符合text規(guī)則的字符數(shù)組
substring()字符串.substring(start, end)start, end 開始位置與結(jié)束位置新的字符串將字符串中 [start, end] 提取,生成一個新的字符串
substr()字符串.substr(start, length)start開始位置,length要生成新字符串的長度新的字符串提取字符串
slicce()字符串.slicce(start, end)start, end 開始位置與結(jié)束位置,不包括第end位新的字符串提取start到end 的字符串
replace() 過濾替換supStr.replace(oldStr,newStr)oldStr舊字符串,newStr新字符串新的字符串用newStr將supStr中的oldStr替換掉,生成新的字符串
new RegExp('\','g')txtData.replace(newRegExp('\','g'), '/')替換字符串中所有匹配上的字符或則使用replaceAll()但是兼容性不高
split() 字符串分割字符串.split(分隔符,length)分隔符為字符串里面的字符,lenth控制返回數(shù)組元素格式,一般不用數(shù)組對數(shù)組會用分隔符進(jìn)行分割,將分割后的子串,放到數(shù)組中
字符串大小寫轉(zhuǎn)換toLowerCase() 轉(zhuǎn)換成大寫toUpperCase() 轉(zhuǎn)換成小寫改變原字符串字符大小寫轉(zhuǎn)換
concat字符串拼接字符串.concat(字符串1,字符串2,...)字符新的字符串拼接字符串
fromCharCode()將ASCII編碼轉(zhuǎn)換成對應(yīng)的字符。
8 正則表達(dá)式
/*
? ? ? ? ? ? ? ? 敏感詞過濾
? ? ? ? ? ? */vararr=[/靠/ig,/tmd/ig,/nm/ig,/cao/ig];functionbtnClick(){varoTxt=document.getElementById("txt1");varoMsg=document.getElementById("msg");varoValue=oTxt.value;for(i=0;i<arr.length;i++){oValue=oValue.replace(arr[i],"*");}oMsg.innerHTML=oValue;oTxt.value='';}
9 對象方法
delete 關(guān)鍵字 刪除對象屬性或者方法
varobj={name:'zhangsan',age:23}deleteobj.ageconsole.log(sunStr);// {name:'zhangsan'}
Math 數(shù)學(xué)運算函數(shù)
方法說明
Math.random()返回0 ~ 1之間的隨機小數(shù)(可能是 0,不可能是 1)
Math.max(num1, num2)返回較大的數(shù)
Math.min(num1, num2)返回較小的數(shù)
Math.abs(num)絕對值
Math.ceil(19.3)向上取整(20)
Math.floor(11.8)向下取整(11)
Math.pow(x, y)x的y次方
Math.sqrt(num)開平方
日期對象
// 獲取當(dāng)前時間vartimeDate=newDate()conlose.log(tiemDate)// 傳入時間初始化vartimeDate=newDate("2000-01-01")vartimeDate=newDate("2000/01/01")// 傳入?yún)?shù)順序 年 月 日 時 分 秒 毫秒 vartimeDate=newDate(2000,0,1,8,30,50)// 可以直接傳入某一時間距離1970年1月1日至今的毫秒數(shù)vartimeDate=newDate()conlose.log(tiemDate)
方法說明
set/getDate()從Date對象中返回一個月中的某一天
getDay()從Date對象返回一周中的某一天(0 ~ 6)
set/getMonth()從Date對象中返回月份(0 ~ 11)
set/ getFullYear()從Date對象中返回年份
set/getHours()返回Date對象中的小時(0 ~ 23)
set/getMinutes()返回Date對象中的分鐘(0 ~ 59)
set/getSeconds()返回Date對象中的秒數(shù)(0 ~ 59)
set/getMilliseconds()返回Date對象的毫秒
set/getTime()返回1970年1月1日至今的毫秒數(shù)
getTimezoneOffset()返回本地時間與格林標(biāo)準(zhǔn)時間的分鐘差
對象遍歷方法
對象遍歷? 只能通過for ..in 方法
varperson={username:"zhangsan",age:18,sex:"男"}for(variinperson){document.write("對象遍歷:"+i+","+person[i])}
10 setInterval定時器
格式:
vartimer=setInterval(函數(shù),毫秒數(shù))clearInterval(timer)// 取消定時器
功能:每隔對應(yīng)毫秒數(shù),執(zhí)行一次傳入的函數(shù)
11 Bom對象
系統(tǒng)對話框
方法參數(shù)返回值說明
alert()無無彈出警告窗
confirm()無確認(rèn)返回true,取消 false帶取消和確定的提示框
prompt()1.面板顯示內(nèi)容 2.輸入框里面默認(rèn)參數(shù)(可以不傳)確認(rèn)返回輸入框內(nèi)容,取消返回null帶輸入框的提示框
varres=prompt("請輸入內(nèi)容",100);conlose.log(res)
open() 打開新窗口
參數(shù)1參數(shù)2參數(shù)3
跳轉(zhuǎn)的url? 打開一個新窗口,加載url字符串,給打開的窗口起一個名字一串特殊含義的字符串
functionbtnClick(){open("http://www.baidu.com","xxx")}
History 歷史記錄
window.history 掌管的是,當(dāng)前窗口(注意不是瀏覽器)歷史記錄(只要加載的url不一樣就會產(chǎn)生歷史記錄)
history .length? 輸出當(dāng)前窗口歷史記錄條數(shù)
history .back? 返回上一條歷史記錄
history .forward() 前進(jìn)到下一條歷史記錄
history .go()? 參數(shù)? 0 刷新當(dāng)前頁面? ? 正整數(shù)? 前進(jìn)n條記錄? 負(fù)整數(shù)? 后退n條記錄
location頁面跳轉(zhuǎn)
方法說明
location.assign(url)在當(dāng)前窗口跳轉(zhuǎn)到url
location.replace(url)在當(dāng)前窗口替換成新的url,不會產(chǎn)生歷史記錄
location.reload(url)刷新當(dāng)前窗口
location.reload(true)不經(jīng)過瀏覽器緩存強制從服務(wù)器加載
12 Dom操作
節(jié)點獲取
方法返回值功能
document.getElementById(id)符合條件的一個節(jié)點通過id獲取節(jié)點
node.getElementsByTagName(標(biāo)簽名)偽數(shù)組/l類數(shù)組從node節(jié)點,通過元素標(biāo)簽名獲取元素節(jié)點
node.getElementsByClassName(class名)偽數(shù)組/l類數(shù)組通過class獲取符合條件的元素節(jié)點
document.getElementsByName(name屬性的值)節(jié)點通過name屬性的值獲取符合條件的元素節(jié)點
document.querSelector(css選擇器)一個元素節(jié)點,找到符合條件的第一個元素節(jié)點傳入的參數(shù)為css選擇器
document.querySelectorAll(css選擇器)一個偽數(shù)組
node.parentNodenode的父節(jié)點獲取node節(jié)點的父節(jié)點
節(jié)點元素樣式獲取
方法說明
node.currentStyle['height']? IE方法或者 getComputedStyle(node).['height']? 谷歌方法node表示元素節(jié)點,[] 里面是獲取的樣式屬性
node.getAttribute("class")獲取node節(jié)點的class屬性的值
node.setAttribute("class" , “box”)給node節(jié)點添加值為box的class屬性
node.removeAttribute("title")刪除node節(jié)點的tille屬性
node.innerHTML = "..."插入的html標(biāo)簽會被解析
node.innerText= "..."插入純文本,里面寫入html便簽也不會解析
node.outerHTML= "..."從外標(biāo)簽開始到外便簽結(jié)束? 會解析標(biāo)簽
訪問子節(jié)點方法
方法說明
childNodes()訪問當(dāng)前節(jié)點下所有的子節(jié)點
firstChild()訪問子節(jié)點中的首位
lastChild()訪問子節(jié)點中的最后一位
nextSibling()訪問當(dāng)前節(jié)點兄弟節(jié)點中的下一個節(jié)點
previousSibling()訪問當(dāng)前節(jié)點兄弟節(jié)點的上一個節(jié)點
節(jié)點操作
方法返回值說明
document.createElement()新創(chuàng)建的標(biāo)簽創(chuàng)建一個新節(jié)點
node1.appendChild(node2)將node2 節(jié)點 插入到node1 節(jié)點的末尾
document.createTextNode(文本)新創(chuàng)建的文本標(biāo)簽穿件文本節(jié)點(純文本)
box1.parentNode.insertBefore(box2, box1)將box2節(jié)點添加到box1的前面
box1.parentNode.replaceChild(box2, box1)
node.cloneNode()克隆出來的新節(jié)點克隆node節(jié)點本身和子節(jié)點
box.parentNode.removeChild(box)將box節(jié)點從頁面上刪除
ps:parentNode 表示的是此節(jié)點的上級父節(jié)點
元素寬高、邊距獲取
offsetWidth? ? 元素寬度獲取
offsetHeight? ? 元素高度獲取
offsetLeft? ? ? 元素距離左側(cè)距離獲取
offsetTop? ? 元素距離上面距離獲取
varoDiv=document.getElemenByid("div1")alert(oDiv.offsetWidth)// width + border + padding (眼睛實際看到的寬度)
瀏覽器寬高獲取
獲取瀏覽器高度寫法
varwindowHeight=document.documentElement.clientHeight||document.body.clientHeight
獲取瀏覽器寬度寫法
varwindowWidth=document.documentElement.clientWidth||document.body.clientWidth
13 事件與事件類型
鼠標(biāo)事件
事件名稱說明
click單機
dblclick雙擊
mouseover鼠標(biāo)移入(會重復(fù)觸發(fā))
mouseout鼠標(biāo)移出(會重復(fù)觸發(fā))
mousemove鼠標(biāo)移動(會不停觸發(fā))
mousedown鼠標(biāo)按下
mouseup鼠標(biāo)抬起
mouseenter鼠標(biāo)移入(不會重復(fù)觸發(fā))
mouseleave鼠標(biāo)移出(不會重復(fù)觸發(fā))
鍵盤事件
事件名稱說明
keydown鍵盤按下 (如果按下不放手會一直觸發(fā))
keyup鍵盤抬起
keypress鍵盤按下(只支持字符鍵)
window 事件
事件名稱說明
load當(dāng)頁面加載完成以后觸發(fā)
unload當(dāng)頁面解構(gòu)的時候觸發(fā)(刷新頁面,關(guān)閉當(dāng)前頁面) IE瀏覽器兼容
scroll頁面滾動事件
resize窗口大小發(fā)生變化時觸發(fā)
表單事件
事件名稱說明
blur失去焦點
focus獲取焦點
select當(dāng)我們在輸入框內(nèi)選中文本時候觸發(fā)
change當(dāng)我們對輸入框的文本進(jìn)行修改并且失去焦點的時候
submit當(dāng)我們點擊submit上的按鈕才能觸發(fā)
reset當(dāng)我們點擊reset上的按鈕才能觸發(fā)
14 事件對象獲取
oBtn.onclick=function(ev){// 事件對象獲取方式? 固定寫法vare=ev||window.eventalert(e)}
獲取當(dāng)前鼠標(biāo)的位置
x坐標(biāo)y坐標(biāo)說明
clientXclientY原點位置:可視窗口的左上角
pageXpageY原點位置:整個頁面的左上角(包含滾動出去的滾動距離)
screenXscreenY原點位置:電腦屏幕的左上角
document.onmousedown=function(ev){vare=ev||window.event;alert(e.clientX+","+e.clientY)alert(e.screenX+","+e.screenY)}
事件對象屬性
shiftKey? ? 按下shift鍵,為true,默認(rèn)為false
altKey
ctrlkey
metaKey
window系統(tǒng)? 按下window鍵為true
macos系統(tǒng)? ? 按下command鍵為true
注:和其他的操作進(jìn)行組合,形成一些快捷鍵的操作
document.onmousedown=function(ev){vare=ev||window.event;vararr=[]if(e.shiftKey){arr.push("shift")}if(e.altKey){arr.push("altKey")}if(e.ctrlKey){arr.push("ctrlKey")}}
鍵盤事件對象屬性
keyCode? 鍵碼
which
返回值:鍵碼返回的是大寫字母的ASCII碼值,不區(qū)分大小寫
格式:var which = e.which || keyCode
注:只在keydown下支持
charCode? 字符碼
which
返回值:字符碼區(qū)分大小寫,當(dāng)前按下鍵對應(yīng)的ASCII碼值
格式 : var which = e.which || charCode
注:只在keypress下支持
window.keypress=function(ev){vare=ev||window.eventvarwhich=e.which||e.charCodealert(which)// 可以通過判斷 獲取的到which 來 確認(rèn)執(zhí)行定義的函數(shù)}
Target目標(biāo)觸發(fā)
Target的指向就是觸發(fā)當(dāng)前事件的元素,this永遠(yuǎn)指向當(dāng)前函數(shù)的主人。
varoUl=document.getElementById("ul1")oUl.onclick=function(ev){vare=ev||window.eventvartarget=e.target||window.event.srcElementalert(this.tagName)alert(target.innerHTML)}
阻止事件冒泡
有瀏覽器兼容問題
cancelBubble = true
stopPropagation()
varaDivs=document.getElementsByTagName("div")for(vari=0;i<aDivs.length;i++){aDivs[i].onclick=function(ev){vare=ev||window.eventalert(this.id)cancelBubble=true// 阻止冒泡stopPropagation()// 阻止冒泡}}
事件委托
實現(xiàn)步驟:
找到當(dāng)前節(jié)點的父節(jié)點或則祖先節(jié)點
將事件添加到找到的這個父節(jié)點或則祖先節(jié)點上
找到觸發(fā)對象,判斷觸發(fā)對象是否是想要的觸發(fā)對象,進(jìn)行后續(xù)操作
如下:li 委托 ul 將點擊的li變成紅色
varoUl=document.getElmentById("ul1")oUl.onclick=function(ev){vare=ev||window.eventvartarget=e.target||window.event.srcElementif(target=e.nodeName.toLowerCase()=="li"){target.style.backgroundColor='red'}}<ul id="ul1"><li></li><li></li><li></li></ul>
事件監(jiān)聽器
removeEventListener() 刪除事件中的函數(shù)
格式:node.removeEventListener()
參數(shù):
第一個參數(shù):事件類型
第二個參數(shù):刪除函數(shù)的名稱
addEventListener()? ? 給元素的事件添加函數(shù)
格式: node.addEventListener("click")
參數(shù):
第一個參數(shù):事件類型
第二個參數(shù):綁定函數(shù)
第三個參數(shù):布爾值
true? 事件捕獲
false? 事件冒泡? 默認(rèn)
15 localStorage 本地存儲
只能存儲String
localStorage 對象
localStorage .setItem(name,value);? ? 寫入
localStorage .getItem(name);? 讀取
localStorage .removeItem(name);? ? 刪除
16? 強制改變this指向
call() 方法
格式:函數(shù)名.call()
參數(shù):
第一個參數(shù):傳入該函數(shù)this指向的對象,傳入什么強制指向什么
第二個參數(shù):將原函數(shù)的參數(shù)往后順延一位
apply() 方法
格式:函數(shù)名.apply()
參數(shù):
第一個參數(shù):傳入該函數(shù)this指向的對象,傳入什么強制
第二個參數(shù):數(shù)組? 數(shù)組放我們原有所有參數(shù)
bind() 方法
預(yù)設(shè)this指向
functionshow(x,y){alert(this)alert(x+","+y)}// call方法show.call("call",20,40)// apply 方法show.apply("apply",[20,40])// bind 方法show.bind("bind")(40,50)
17 ECMA6數(shù)組方法
Array.from()// 將偽數(shù)組轉(zhuǎn)換成真數(shù)組
方法返回值說明
find((item,index,arr) => {函數(shù)})找到的元素在數(shù)組中查找符合條件的元素,只要找到一個符合的元素,就終止遍歷
findIndex((item) => {函數(shù)})找到符合元素的下標(biāo)
數(shù)組.copywithin(開始下標(biāo),start,end)[start,end] 范圍數(shù)組內(nèi)容覆蓋
18 ECMA6對象合并
Object.assign 合并對象
將所有傳入的對象,都合并到第一個對象中
varobj1={a:10}varobj2={b:20,c:30}varobj3={d:40,f:["hello","world",true]}Object.assign(obj1,obj2,obj3)
19 Map映射
會將重復(fù)的合并
// map 映射letmap=newMap()// 添加數(shù)據(jù)map.set("張三","打魚的")map.set("李四","種地的")map.set("王五","挖煤的")map.set("李四","打獵的")// 取值alert(map.get("王五"))
20 ajax網(wǎng)絡(luò)請求
oBtn.onclick=function(){//1、創(chuàng)建ajax對象varxhr=null;try{xhr=newXMLHttpRequest();}catch(error){xhr=newActiveXObject("Microsoft.XMLHTTP");}//2、調(diào)用open/*
? ? ? ? ? ? ? ? ? ? 第一個參數(shù):請求方式 get post
? ? ? ? ? ? ? ? ? ? 第二個參數(shù):url
? ? ? ? ? ? ? ? ? ? 第三個參數(shù):是否異步
? ? ? ? ? ? ? ? ? ? ? ? true 異步? ? false 同步
? ? ? ? ? ? ? ? */// get 請求直接在open方法總將數(shù)據(jù)在url中通過 ? 拼接提交xhr.open("get","1.get.php?username=yyy&age=21&password=dasdsd",true);/*
? ? ? ? ? ? ? ? ? ? post? ? 提交數(shù)據(jù),需要通過send方法進(jìn)行提交
? ? ? ? ? ? ? ? *///3、調(diào)用sendxhr.send();//4、等待數(shù)據(jù)響應(yīng)xhr.onreadystatechange=function(){if(xhr.readyState==4){//判斷本次下載的狀態(tài)碼是多少if(xhr.status==200){alert(xhr.responseText);}else{alert("Error:"+xhr.status);}}}}
21 cookie本地存儲
可以設(shè)置過期時間
最大存儲4kb,每個域名下最多可以儲存50條數(shù)據(jù)
只能存字符串
cookie語法:
格式:name=value;[expires=data];[path=path];[domain=somewhere.com];[secure]
name? 鍵
value? 值? 都是自定義
注: 中括號參數(shù)屬于可選參數(shù),可以不添加
document.cookie='username=xxx'// 設(shè)置cookiealert(document.cookie)// 獲取cookie
cookie編碼中文
encodeURIComponent? ? 將中文編譯成對應(yīng)的字符
decodeURIComponent? ? 將對應(yīng)的字符編譯成中文
document.cookie='username=xxx'+encodeURIComponent("鋼鐵俠")// 設(shè)置cookiealert(decodeURIComponent(document.cookie))// 獲取cookie
expires: cookie過期時間
必須填寫,日期對象
系統(tǒng)會自動清除過期cookie
document.cookie=`username=xxx;expires=${時間對象}`
path:cookie限制訪問路徑
訪問限制,如果不去設(shè)置,默認(rèn)加載當(dāng)前,html文件的路徑
我們設(shè)置cookie路徑,和當(dāng)前文件的路徑,必須保持一致,如果不一致,cookie訪問失敗
document.cookie="username=xxx;path="+"/code14/cookie/demo"
domain:cookie限制訪問域名
如果不去設(shè)置,默認(rèn)加載的是當(dāng)前.html文件的服務(wù)器域名
如果加載當(dāng)前文件域名和設(shè)置? 的域名不一樣,設(shè)置cookie失敗
document.cookie="username=xxx;domain="+"localhosx"
Cookie的secure設(shè)置參數(shù)
如果不設(shè)置,設(shè)置cookie,可以通過http協(xié)議加載文件設(shè)置,也可以通過https協(xié)議加載cookie文件
設(shè)置這個字段之后,只能設(shè)置https協(xié)議加載cookie
22 構(gòu)造函數(shù)封裝
function Person(name,sex){// 這里this指向整個構(gòu)造函數(shù)對象this.name = name? ? this.sex = sex? ? this.showName = function (){console.log('我的名字叫' + this.name);}this.showSex = function (){console.log('我的性別是' + this.sex);}}var p1= new Person('張三','男')p1.showName()p1.showSex()var p2= new Person('李四','男')p2.showName()p2.showSex()
23 Prototype 原型對象
概念:每一個函數(shù)上,都有一個原型對象Prototype
用在構(gòu)造函數(shù)上,我們可以給構(gòu)造函數(shù)的原型Prototype,添加方法
1、如果將方法添加到構(gòu)造構(gòu)造函數(shù)的Prototype原型對象上,構(gòu)造函數(shù)構(gòu)造出來的對象共享原型上的所有方法
vararr1=[10,23,244,34]vararr2=[23,435,45,546,546]Array.prototype.sum=function(){varres=0;for(vari=0;i<this.length;i++){res+=this[i]}returnres}console.log(arr1.sum());console.log(arr2.sum());console.log(arr1.sum==arr2.sum);// true
24 原型鏈繼承
// Teddy.Prototype = Dog.Prototype()? 非常錯誤的寫法for(varfuncNameinDog.Prototype){Teddy.Prototype[funcName]=Dog.Prototype[funcName]}
25? __ proto __與instanceof 關(guān)鍵字
構(gòu)造函數(shù)構(gòu)造出來的對象,有一個屬性__ proto ,指向構(gòu)造出這個對象的構(gòu)造函數(shù)的原型 ,每個對象的proto__屬性指向自身構(gòu)造函數(shù)的prototype;
instanceof 關(guān)鍵字
功能:判斷某一個對象是否是這個構(gòu)造函數(shù)構(gòu)造出來
functionDog(obj){this.obj=obj}varxiaobai=newDog({name:'小白',type:'比熊',age:23})console.log(xiaobaiinstanceofDog);// trueconsole.log(xiaobaiinstanceofObject);// true
26 Promise構(gòu)造函數(shù)(解決回調(diào)地獄)
//在EcmaScript 6 中新增了一個API Promise//Promise是一個構(gòu)造函數(shù)varfs=require("fs")//創(chuàng)建Promise容器//1.給別人一個承諾 //? Promise容易一旦創(chuàng)建,就開始開始執(zhí)行里面的代碼varp1=newPromise(function(resolve,reject){fs.readFile('./date/a.txt','utf8',function(err,data){if(err){//失敗了,承諾容器中的任務(wù)失敗了//把容器中的Pending狀態(tài)改為成功Rejected//調(diào)用reject就相當(dāng)于調(diào)用了then方法的第二個參數(shù)函數(shù)reject(err);}else{//承諾任務(wù)中的任務(wù)成功了//把容器的Pending狀態(tài)改為成功Resolved//也就是說這里調(diào)用 的resolve方法實際上就是then方法傳遞的哪個funcionresolve(data);}})})varp2=newPromise(function(resolve,reject){fs.readFile('./date/b.txt','utf8',function(err,data){if(err){reject(err);}else{resolve(data);}})})varp3=newPromise(function(resolve,reject){fs.readFile('./date/c.txt','utf8',function(err,data){if(err){reject(err);}else{resolve(data);}})})//p1就是那個承諾//當(dāng)p1成功了然后(then)做指定的操作//then方法接收的function就是容器中的resolve函數(shù)p1.then(function(data){console.log(data);//當(dāng)p1讀取成功的時候//當(dāng)前函數(shù)中的return的結(jié)果就可以再后面的then中function接收到//當(dāng)return 1 2 3 后面就接收到123//我們可以return一個Promise對象returnp2;},function(err){console.log('讀取文件失敗',err);}).then(function(data){console.log(data);returnp3;},function(err){console.log(err);}).then(function(data){console.log(data);},function(err){console.log(err);})
1 過濾
三個最基本的過濾方法是:first(), last() 和 eq(),它們允許您基于其在一組元素中的位置來選擇一個特定的元素。
其他過濾方法,比如filter()和not()允許您選取匹配或不匹配某項指定標(biāo)準(zhǔn)的元素。這個過濾指的就是相當(dāng)于css中的選擇器,如:id選擇器,類選擇器,標(biāo)簽選擇器,子代選擇器等
/*
? ? filer 過濾? 對已經(jīng)獲取到的網(wǎng)頁元素進(jìn)行過濾
? ? not? filer的反義詞
? ? has? 擁有,直接判定子節(jié)點中是否有符合條件的元素
*/$(function(){$("div").filer(".box").css("backgroundColor","orange")$("div").not(".box").css("backgroundColor","orange")$("div").has(".box").css("backgroundColor","orange")})
2 查找
方法說明
prev()查找當(dāng)前兄弟節(jié)點中的上一個節(jié)點
next()查找當(dāng)前兄弟節(jié)點中的下一個節(jié)點
eq()通過已經(jīng)獲取到元素的偽數(shù)組下標(biāo)獲取指定元素的節(jié)點
$(function(){$("h3").prev().css("backgroundColor","red")$("h3").next().css("backgroundColor","bule")$("li").eq(3).css("backgroundColor","orange")// 獲取所有l(wèi)i標(biāo)簽中下標(biāo)為3的元素$("li:eq(4)").css("backgroundColor","orange")// 獲取所有l(wèi)i標(biāo)簽中下標(biāo)為4的元素})
3 設(shè)置和修改行間屬性 attr
$(function(){// 獲取屬性值alert($("#div1").attr("id"))alert($("#div1").attr("class"))// 設(shè)置屬性值$("#div1").attr("title","world")$("#div1").attr("calss","box2")// 一次性修改多條屬性$("#div1").attr({title:"world",class:"xxx",yyy:"zzz"})})
4 class 屬性添加與刪除
Class可以寫多個css樣式,addClass()可以添加class
removeClass()可以刪除class
$(function(){// 添加css 樣式$("#div1").addClass("box3 box4 box2")// 刪除css 樣式$("#div1").removeClass("box3 box2")})
5 元素寬高獲取
方法說明
width() 與 height()width
innerWidth() 與 innerHeight()width + padding
outerWidth() 與 outerHeight()width + border + padding
$(function(){alert($("#div1").width())// widthalert($("#div1").innerWidth())// width + paddingalert($("#div1").outerWidth())// width + border + paddingalert($("#div1").outerWidth(true))// width + border + padding + margin})
6 節(jié)點操作
下面每種標(biāo)簽的方法右邊寫著另外一種方法 作用是寫入的選擇器標(biāo)簽相反而已,一般用于方便其他樣式的操作,方便jquery的鏈?zhǔn)讲僮?/p>
insertBefore()? before()
insertAfter()? ? after()
appendTo()? 插入到子節(jié)點的末尾? ? appendChild(類似于js的方法)
append()插入到某節(jié)點
prependTo()? 插入到子節(jié)點的首位? ? prepend()
remove()刪除元素節(jié)點
并不會保留這個元素節(jié)點上之前的事件和行為
detach()? 刪除元素節(jié)點
會保留這個元素節(jié)點上之前的事件和行為
$(function(){// 找到span節(jié)點插入到div的前面$("span").insertBefore($("div"))// 找到div節(jié)點,插入到span節(jié)點的后面$("div").insertAfter($("span"))// 找到span節(jié)點,插入到div節(jié)點的子節(jié)點的末尾$("span").appendTo($("div"))})
7 事件綁定
on() 方法
給一個事件添加函數(shù)
$("div4").on("click",function(){alert("hello")})
同時給多個事件添加一個函數(shù), 多個事件之間可以通過空格隔開
vari=0$("div4").on("click mouseover",function(){$(this).html(i++)})
給不同的事件添加不同的函數(shù)
$("div4").on({click:function(){alert("點擊")},mouseover:function(){$(this).css("backgroundColor","orange")},mouseout:function(){$(this).css("backgroundColor","blue")}})
事件委托
// 第二個參數(shù),是觸發(fā)對象的選擇器$("ul").on("click","li",function(){$(this).css("backgroundColor","red")})
取消事件綁定 off 方法
$("#cancel").click(function(){$("#div1").off()// 取消所有事件上面的所有函數(shù)$("#div1").off("click")// 取消某一個事件下的所有函數(shù)$("#div1").off("click",show)// 取消某一個事件下指定的函數(shù)})
8 窗口滾動高度獲取 scrollTop
$(function(){$(document).click(function(){alert($(window).scrollTop())// 輸出滾動高度})})
9 事件阻止(事件冒泡、默認(rèn)行為阻止)
ev? pageX? which
preventDefault? ? ? stopPropagation
$(function(){$("div").click(function(ev){alert(this.id)ev.stopPropagation()})$("a").click(function(ev){// ev.preventDefault()// ev.stopPropagation()// 既阻止事件冒泡,又阻止默認(rèn)行為 returnfalse})})
10 鍵盤事件
鼠標(biāo)事件 與 鍵盤事件? keydown事件下用which可以輸出鍵盤按下的鍵碼支持所有按鍵包括功能鍵。 keypress事件下 用which可以輸出鍵盤按下的字符碼? 只支持字符鍵功能鍵不能輸出
ev? pageX
which
鼠標(biāo)事件: button
左鍵
滾輪
右鍵
keydown: keyCode 鍵碼
keypress: charCode? 字符碼
$(window).keypress(function(){alert(ev.which)// 獲取到字符碼})
11 獲取鼠標(biāo)的位置值? pageX 與 pageY
$(window).keypress(function(){alert(ev.pageX+","+ev.pageY)// 帶滾動距離alert(ev.clientX+","+ev.clientY)// 可視窗口alert(ev.which)})
12? 元素top與left值獲取
方法說明
offset()直接獲取當(dāng)前元素,距離最左邊的距離,margin不算數(shù)
position()直接獲取,當(dāng)前元素,距離第一個有定位父節(jié)點的距離,margin算在內(nèi)
offsetParent()查找第一個有定位的父節(jié)點,如果父節(jié)點沒有定位就繼續(xù)往上找,最終到html節(jié)點
$(function(){alert($("#div2").offset().left)alert($("#div2").position().left)$("#div2").offsetParent().css("backgroundColor","yellow")})
13 元素內(nèi)容獲取
val()? 獲取/ 設(shè)置表單元素的值
size()? 輸出,獲取網(wǎng)頁元素的個數(shù),類似于js中的 length
each()? 用來循環(huán)將元素節(jié)點內(nèi)容賦值成下標(biāo)值
html()? 獲取元素的里面的內(nèi)容
text()? 獲取元素的純文本內(nèi)容
attr()? 獲取標(biāo)簽行內(nèi)屬性值
css()? 獲取元素的style里面的屬性
$("input").each(function(index,item){$(item).val(index)})
14 jquery特效函數(shù)
hide()隱藏show()顯示? 淡入淡出? 這些效果都在hover移入移出方法下使用
hide(動畫持續(xù)的毫秒數(shù),回調(diào)函數(shù),動畫結(jié)束的時候執(zhí)行)
$(function(){$("#div1").hover(function(){$("#div2").hide(2000,function(){$("#div1").html("移入")})},function(){$("#div2").show(2000,function(){$("#div1").html("移出")})})})
slideDown()
slideUp()? ? 動畫效果是卷簾效果
fadeIn()? 淡入
fadeOut()? 淡出
fadeTo (動畫持續(xù)時間, 透明度0 ~ 1,回調(diào)函數(shù))
15 jquery的 animate 動畫
默認(rèn)的運動形式是? 滿快慢
勻速? linear
滿快慢? swing
擴展更多animate 的運動形式:
引入jquery-ui
$(function(){$("#div1").hover(function(){$("#div2").animate({width:300,height:300,opacity:0.5},4000,function(){$("#div1").html("移入")})},function(){$("#div2").animate({width:200,height:200,opacity:1},4000,function(){$("#div1").html("移出")})})})
Jquery引入后jquery可以設(shè)置顏色class顏色樣式刪除與添加時候的動畫效果,有了jqueryUi以后,addClass 和 removeClass 就變成了增強版方法
$("button").eq(0).click(function(){$("#div1").addClass("box",4000)})$("button").eq(0).click(function(){$("#div1").removeClass("box",4000)})
Jquery停止動畫函數(shù) stop() finish()
$("#div1").click(function(){$("#div1").animate({width:300},2000).animate({height:3000},2000)})$("#div1").click(function(){$("#div1").stop()// 停止第一個動畫,當(dāng)時后續(xù)動畫正常啟動$("#div1").stop(true)// 停止所有動畫$("#div1").stop(true,true)// 停止所用動畫,并且將當(dāng)前正在進(jìn)行的動畫,直接到達(dá)目的值$("#div1").finish()// 停止所有動畫,并且將所有的動畫都達(dá)到目的值})
delay()延遲下一個動畫執(zhí)行的時間
() 里面?zhèn)髟谛枰訒r多少時間后執(zhí)行
$("#div1").click(function(){$("div1").animate({width;300},2000).delay(4000).animate({height:300},2000)})
16 元素節(jié)點獲取
siblings()? 用來除當(dāng)前節(jié)點外,所有的兄弟節(jié)點
nextAll()? prevAll()
parentsUntil()? nextUntil( )? prevUntil()
$(function(){$("#p1").siblings().css("color","red")$("#p1").nextAll().css("color","red")$("#p1").prevAll().css("color","red")})
父節(jié)點的獲取
方法說明
parent()獲取父節(jié)點
parents()獲取父節(jié)點? 參數(shù)選擇器
closest()必須傳入?yún)?shù),參數(shù)也是選擇器,只獲得一個符合條件的元素,從自己開始去查找
$(function(){$("#p1").parent().css("color","red")$("#p1").parents(".box").css("color","red")$("#p1").closest("#div1").css("color","red")})
克隆節(jié)點
方法說明
clone()默認(rèn)只會克隆節(jié)點本身,并不會克隆我們元素節(jié)點的行為和事件
clone(true)既會克隆節(jié)點本身,還會克隆節(jié)點元素節(jié)點的行為和事件
$("button").click(function(){varnode=$("div1").clone(true)node.appendTo("#div2")})
多個選擇器拼接
add()? ? ? 可以將多個選擇器拼接在一起
slice()? slice(start, end)? ? [start, end] 獲取指定范圍內(nèi)獲取的元素節(jié)點
$("div").add("span").add("ul li")$("ul li").sclice(1,4).css("color","red")
表單數(shù)據(jù)串聯(lián)化
方法說明
serialize()將我們表單中的數(shù)據(jù)拼接成querystring(查詢字符串)name1=value1&name2=value2
search()?name1=value1&name2=value2
querystring()name1=value1&name2=value2
serializeArray()將表單數(shù)據(jù)拼接成數(shù)組
$(function(){console.log($("input").serialize())})
主動觸發(fā)事件
方法說明
trigger()主動觸發(fā)
ev.data
ev.target(兼容后觸發(fā)對象)
ev.type(輸出事件類型)
$("#play").on("play",function(){alert("開始播放音樂")})$("#play").on("next",function(){alert("切換到下一首歌曲")})$("#button").eq(0).click(function(){$("#play").trigger("play")})$("#button").eq(1).click(function(){$("#play").trigger("next")})
17? 對元素節(jié)點包裝
方法說明
wrap()每個獲取到的元素節(jié)點單獨包裝
wrapAll()整體包裝
wrapInner()內(nèi)部包裝
unwrap()刪除包裝? 刪除上面一層包裝,不包括body節(jié)點
$(function(){// 給頁面上所有的span 節(jié)點加包裝,直接Jq創(chuàng)建節(jié)點的代碼$("span").wrap("<p class="box" title="hello"></p>")$("span").wrapAll("<p class="box" title="hello"></p>")$("span").wrapInner("<p class="box" title="hello"></p>")$("span").unwrap()// 沒有參數(shù)})
18 cookie
$.cookie(name)? 通過name取值
$.cookie(name, value)? ? 設(shè)置name和value
$.cookie(name, value? ,{
可選項? ? ? ? ? raw:truevalue不進(jìn)行編碼? ? ? ? ? ? ? ? ? ? ? 默認(rèn)falsevalue要進(jìn)行編碼的
})
$.cookie(name, null)? 刪除cookie
$.cookie("變種人","X教授",{expires:7,raw:true})
19 ajax 網(wǎng)絡(luò)請求
$.ajax({type:"get",url:"https://api.asilu.com/weather/",data:{city:"深圳"},dataType:"jsonp",// 如果請求地址跨域,可以使用dataType來指定跨域的解決方式,這里使用了jsonpsuccess:function(data,statusText,xhr){// data 下載到的數(shù)據(jù)// statusText? 下載的狀態(tài)? success// xhr? ajax對象consloe.log(data+","+statusText)},erorr:function(msg){consloe.log(msg)}})
load方法
將url傳入以后,將下載到的數(shù)據(jù)直接填充到被選中元素的innerHTML中
$(function(){$("button").click(function(){$("div").load("2.txt")})})
get與post方法直接調(diào)用
$("button").eq(2).click(function(){$.post(1.post.php,{username:"tian",age:20,password:"123asd"},function(data,statusText,xhr){alert(data)})})
三、websocket通信協(xié)議
1 創(chuàng)建websocket對象
// H5 已經(jīng)直接提供了websocket 的API,所以可以直接調(diào)用// 1.創(chuàng)建 WebSocket // 參數(shù)1: WebSocket 的服務(wù)地址varsocket=newWebSocket('ws://echo.websocket.org')
2 websocket事件
事件事件處理程序描述
openSocket.onopen連接建立時觸發(fā)
messageSocket.onmessage客戶端接收服務(wù)器端數(shù)據(jù)時觸發(fā)
errorSocket.onerror通訊發(fā)生錯誤時觸發(fā)
closeSocket.onclose連接關(guān)閉時觸發(fā)
3 websocket方法
方法描述
Socket.send()使用連接發(fā)送數(shù)據(jù)
Socket.close()關(guān)閉連接
4 調(diào)用websocket對象事件與方法
// 2.open: 當(dāng)和 WebSocket 服務(wù)連接成功時候觸發(fā)socket.addEventListener('open',function(){div.innerHTML='連接服務(wù)成功'})// 3.主動的給websocket服務(wù)發(fā)送消息button.addEventListener('click',function(){varvalue=input.value? ? ? ? ? ? ? ? socket.send(value)})// 4.接收websocket服務(wù)的數(shù)據(jù) socket.addEventListener('message',function(e){console.log(e.data);div.innerHTML=div.innerHTML+','+e.data})// 5.當(dāng)websocket服務(wù)斷開是事件socket.addEventListener('close',function(){div.innerHTML='服務(wù)斷開連接'})
5 使用nodejs開發(fā)websocket服務(wù)
使用nodejs開發(fā)websocket需要依賴一個第三方包。Nodejs? Websocket
// 1.導(dǎo)入nodejs-websocket包constws=require("nodejs-websocket")constPORT=3000// 2.創(chuàng)建一個sever// 2.1 如何處理用戶請求// 每次只要有用戶連接,函數(shù)就會被執(zhí)行,會給當(dāng)前連接用戶創(chuàng)建一個 connect 對象constserver=ws.createServer(connect=>{console.log('有用戶連接');// 每當(dāng)接收到用戶傳遞過來的數(shù)據(jù),這個text事件會被觸發(fā)connect.on('text',(data)=>{console.log('接收到了用戶對的數(shù)據(jù)',data);// 給用戶一個響應(yīng)的數(shù)據(jù)// 對用戶放過來的數(shù)據(jù),把小寫轉(zhuǎn)換成大寫,并且拼接一點內(nèi)容connect.send(data.toUpperCase()+'!!!')})// 只要websocket鏈接斷開,close 事件就會觸發(fā)connect.on('close',()=>{console.log('連接斷開');})// 注冊一個error,處理用戶的錯誤信息connect.on('error',()=>{console.log('用戶連接異常');})})server.listen(PORT,()=>{console.log('websocket服務(wù)啟動成功,監(jiān)聽端口為:'+PORT);})
6 簡單聊天室代碼
// 1.導(dǎo)入nodejs-websocket包constws=require("nodejs-websocket")constPORT=3000constTYPE_ENTER=0constTYPE_LEAVE=1constTYPE_MSG=2/*
? ? 分析:
? ? ? ? 消息不應(yīng)該是簡單的字符串
? ? ? ? 這個消息應(yīng)該是一個對象
? ? ? ? type:消息的類型, 0:表示用戶進(jìn)入聊天室消息 1:表示用戶離開聊天室的消息 2:正常的聊天消息
? ? ? ? msg:消息的內(nèi)容
? ? ? ? time:聊天的具體時間
*/// 記錄當(dāng)前連接上來的總的用戶數(shù)量letcount=0// conn每個連接到服務(wù)器的用戶,都會有一個 conn 對象constserver=ws.createServer(conn=>{console.log('新的連接');count++conn.username=`用戶${count}`//1. 告訴所用用戶,有人加入聊天室broadcast({type:TYPE_ENTER,msg:`${conn.username}進(jìn)入聊天室`,time:newDate().toLocaleTimeString()})// 接收到了瀏覽器的數(shù)據(jù)conn.on('text',data=>{// 2.當(dāng)我們收到某個用戶的信息的時候,告訴所有用戶,發(fā)送的消息的內(nèi)容 是什么broadcast({type:TYPE_MSG,msg:`${conn.username}:${data}`,time:newDate().toLocaleTimeString()})})// 關(guān)閉連接的時候觸發(fā)conn.on('close',data=>{console.log('關(guān)閉連接');count--broadcast({type:TYPE_LEAVE,msg:`${conn.username}退出聊天室`,time:newDate().toLocaleTimeString()})// 3.告訴所有的用戶,有人離開了聊天室})// 發(fā)生異常,觸發(fā)conn.on('error',data=>{console.log('發(fā)生異常');})})// 給所有的用戶發(fā)送消息functionbroadcast(msg){// server.connections : 表示所有的用戶 server.connections.forEach(item=>{item.send(JSON.stringify(msg))})}server.listen(PORT,()=>{console.log('websocket服務(wù)啟動成功,監(jiān)聽端口為:'+PORT);})
7 socket.io框架(基于websocket)
框架說明文檔地址:https://socket.io/
node后端:
// 創(chuàng)建http服務(wù)器 consthttp=require('http')varfs=require('fs')constapp=http.createServer()app.on('request',(req,res)=>{fs.readFile('./index.html',function(err,data){if(err){res.writeHead(500)returnres.end('Error loading')}res.writeHead(200)res.end(data)})})app.listen(3000,()=>{console.log('listening on *:3000');});constio=require('socket.io')(app);// 監(jiān)聽了用戶連接 的事件// socket 表示用戶連接? // socket.emit? 表示觸發(fā)某個事件? 如果需要給瀏覽器發(fā)送數(shù)據(jù),需要觸發(fā)瀏覽器注冊的某個事件// socket.on 表示注冊某個事件? 如果需要獲取瀏覽器的數(shù)據(jù),需要注冊一個事件,等待瀏覽器觸發(fā)io.on('connection',socket=>{console.log('新用戶連接了');// sockrt.emit 方法表示給瀏覽器發(fā)送數(shù)據(jù)// 參數(shù)1:事件的名字// socket.emit('send', {name: 'zs'})// 參數(shù)1:事件名: 任意// 參數(shù)2: 獲取到的數(shù)據(jù)socket.on('hehe',data=>{console.log(data);socket.emit('send',data)})})
HTML前端:
<!DOCTYPEhtml><html lang="en"><head><title></title><meta charset="UTF-8"><meta name="viewport"content="width=device-width, initial-scale=1"><link href="css/style.css"rel="stylesheet"></head><body>hahha<script src="/socket.io/socket.io.js"></script><script>// 連接socket服務(wù)// 參數(shù):服務(wù)器地址varsocket=io('http://localhost:3000')// 接收服務(wù)器返回的數(shù)據(jù)// socket.on('send', data => {//? ? console.log(data);// })socket.emit('hehe',{name:'zs',age:'23'})socket.on('send',function(data){console.log(data);})</script></body></html>
基于express框架的socket.io:
constapp=require('express')();consthttp=require('http').Server(app);constio=require('socket.io')(http);app.get('/',(req,res)=>{res.sendFile(__dirname+'/index.html');});io.on('connection',(socket)=>{socket.on('hehe',function(data){console.log(data);})});// 啟動服務(wù)器? ? http.listen(3000,()=>{console.log('listening on *:3000');});
disconnect:后端監(jiān)聽用戶斷開事件
四、常用函數(shù)
filter過濾
過濾數(shù)組中的數(shù)據(jù)并返回過濾后的數(shù)據(jù)
cart=cart.filter(v=>v.checked);
forEach? 遍歷
遍歷數(shù)組中的對象
lettotalPrice=0;lettotalNum=0;cart.forEach(v=>{totalPrice+=v.num*v.goods_price;totalNum+=v.num;})
map? 映射
給數(shù)組中添加新的屬性與屬性值
constres=awaitrequest({url:"/my/orders/all",data:type});this.setData({orders:res.orders.map(v=>({...v,create_time_cn:(newDate(v.create_time*1000).toLocaleDateString())}))
Some()條件遍歷
遍歷數(shù)組中的屬性值進(jìn)行條件判斷,只要遇到一個判斷為true就終止函數(shù)遍歷,返回true。
// 1 獲取緩存中的商品收藏數(shù)組letcollect=wx.getStorageSync("collect")||[];// 2 判斷當(dāng)前商品是否被收藏letisCollect=collect.some(v=>v.goods_id===this.GoodsInfo.goods_id);
findindex()索引遍歷
獲取數(shù)組中可以匹配項的索引,如果在數(shù)組中沒有找到,返回值為-1
letindex=collect.findIndex(v=>v.goods_id===this.GoodsInfo.goods_id);
splice() 數(shù)組修改刪除
表示刪除數(shù)組中的數(shù)據(jù) index為需要開始刪除的索引,1 表示刪除一條
collect.splice(index,1);
split()? 字符分割
根據(jù)傳入函數(shù)中的字符將字符串分割并返回成數(shù)組
varstr='asdfgdh'letindex=str.split('d')console.log(index);//? ["as", "fg", "h"]
trim()去字符兩邊空格
去掉字符串兩邊的空格? ps: trimStart() 去除頭部空白 trimEnd() 去除尾部空白
value.trim()
replace() 修改字符
匹配字符串中的對應(yīng)字符并修改 (goods需要匹配字符,goodsList為需要修改為的數(shù)據(jù))
url=url.replace("/goods/","goodsList")
reduce() 求和函數(shù)
functionsum(...args){returnargs.reduce((p,c)=>p+c,0);}sum(1,2,3,4)
indexOf() 匹配字符下標(biāo)
匹配字符返回遍歷到的字符下標(biāo)
varstr='asdfgh'letindex=str.indexOf('f')console.log(index);// 3
字符查找
includes():查找對象屬性字符串中是否有相應(yīng)的“字符” 返回true或者false
startsWith()字符串中以傳入函數(shù)中的字符開頭返回true
endsWith()字符串中以傳入函數(shù)中的字符結(jié)尾返回true
if(params.url.includes("/my/")){// 拼接header 帶上tokenheader["Authorization"]=wx.getStorageSync("token");}
reverse() 反轉(zhuǎn)數(shù)組
varatr=[1,2,3,4]atr.reverse()console.log(atr);//? [4, 3, 2, 1]
find()? 查找函數(shù)
查找對數(shù)組中的值一次去匹配條件,如果符合返回符合的字符
vararr=['zhangsan','lisi','wangwu']varres=arr.find((item)=>{returnitem=='zhangsan'})console.log(res);//? zhangsan
flat() 數(shù)組扁平化
constarr=[1,[2,[3,[4,5]]],6]constres=arr.flat(Infinity);console.log(res);// [1,2,3,4,5,6]
結(jié)構(gòu)賦值技巧
用數(shù)組的值作為要生成對象的屬性名(也可以是對象賦值時都需要寫在 [ ] 里面)
vararr=['ews','sds']functionadd(i){if(!i){return{[arr[0]]:'test'}}else{return{[arr[1]]:'test'}}}console.log(add(1));// {sds: "test"}
五、typescript篇
1. ts類型
類型例子描述
number1, -33, 2.4數(shù)字
string‘hello’字符串
booleantrue, false布爾值 true 或 false
字面量其本身 let a: 10;限制變量的值就是該字面的值
any*任意類型
unknown*類型安全的any
void空值(undefined)沒有值(或undefined)
never沒有值不能是任何值
object{name:'cola'}任意js對象
array[1,2,3]數(shù)組
tuple[4,5]元素,Ts新增類型,固定長度數(shù)組
enumenum{A, B}枚舉,Ts中新增類型
2 變量賦值
leta:number;letb:number=123;letc=123// 聯(lián)合變量賦值letc:boolean|string// 類型是布爾值或字符串c=truec='heloo'// & 表示同時,即是字符串又是數(shù)字letj:{name:string}&{age:number}j={name:'孫悟空', age:21}// 聲明變量如果不指定類型,則Ts解析器會自動判斷變量的類型尾any,(隱式的any)letd;d=10;d='hello'd=true// 類型斷言,告訴解析器變量的實際類型s=easstring;s=<string>e;// viod 用來表示空,以函數(shù)為例,就表示沒有返回值functionfn():void{}// never 表示永遠(yuǎn)不會返回結(jié)果 (可以用來處理程序報錯)functionfn():never{thrownewError('報錯了')}// 創(chuàng)建對象leta:object;// 不建議a={}// 不建議letb:{name:string,age?:number}// 對象中的屬性指定類型,屬性名后面加問號表示此參數(shù)為可選屬性b={name:'孫悟空', age:12}letc:{name:string,[propName:string]:any}//? [propName: string] 表示任意字符串,它可以是任意類型c={name:'豬八戒',age:12,gender:'男'}letd:(a:number,b:number)=>number;// 設(shè)置函數(shù)結(jié)構(gòu)的類型聲明,傳入值為數(shù)字,返回值為數(shù)字,d=function(n1:number,n2:number):number{returnn1+n2;}// 數(shù)組lete:string[]// 表示字符串?dāng)?shù)組e=['a','b','c']letg:Array<number>// 與上面聲明方式一樣,這是數(shù)字類型數(shù)組// tuple元組? ? 固定長度的數(shù)組leth:[string,string]h=['hello','abc']// enum 枚舉? enumGender{Male=0,// 男Female=1// 女}leti:{name:string,gender:Gender}i={name:'孫悟空',? ? hender:Gender.Male// 性別: 男}// 類型別名typemytype=1|2|3|4|5;letk:1|2|3|4|5;letl:1|2|3|4|5;letm:mytype// 這樣m的類型也是 1 | 2 | 3 | 4 | 5;
3.函數(shù)傳參賦值:
function sum(a:number,b:number):number{return a + b;}const result = sum(123,234)
4.TS編譯選項
tsconfig.json 配置
{/*
? ? ? include? 用來指定那些 ts 文件需要被編譯? ** 任意目錄? * 任意文件
? ? ? exclude? 用來指定那些 ts 文件不許被編譯
? ? ? ? ? ? ? 默認(rèn)值: ["node_modules","bower_components","jspm_packages"]extends? 定義被繼承的配置文件? ? ? files? ? 指定被編譯的文件列表,只有需要編譯文件少時才會用到? ? ? compilerOptions? 編譯器的選項? */"include":["./src/**/*"],// "exclude":[//? "./src/hello/*"http:// ],"compilerOptions":{// 用來指定ts被編譯為es的版本"target":"ES6",// 指定要使用模塊化的規(guī)范"module":"system",// 用來指定項目中要使用的庫// "lib":[],// 指定編譯后文件所在的目錄"outDir":"./dist",// 設(shè)置outfile 后,所有全局作用域中的的代碼會合并到同一個 文件中// "outFile":"./dist/app.js",// 是否對js進(jìn)行編譯,默認(rèn)是false"allowJs":true,// 是否檢查js代碼"checkJs":false,// 是否移除注釋"removeComments":true,// 不生成編譯后的文件"noEmit":false,// 當(dāng)有錯誤的時候不生成編譯文件"noEmitOnError":true,// 所有嚴(yán)格檢查的總開關(guān)"strict":true,// 用來設(shè)置編譯后的js文件是否使用嚴(yán)格模式,默認(rèn)是false"alwaysStrict":true,// 不允許隱式的Any類型"noImplicitAny":true,// 不允許不明確類型的this"noImplicitThis":true,// 嚴(yán)格的檢查空值"strictNullChecks":true}}
5.webpack打包TS
5.1 tsconfig.json 配置
{"compilerOptions":{"module":"ES2015","target":"ES2015","strict":true}}
5.2 webpack.config.js 配置
// 引入一個包constpath=require('path')// 引入html插件constHTMLWebpackPlugin=require('html-webpack-plugin')// 引入clean 插件 打包時先清除dist目錄const{CleanWebpackPlugin}=require('clean-webpack-plugin')module.exports={// 指定入口文件entry:'./src/index.ts',// 指定打包文件所在的目錄output:{// 指定打包目錄path:path.resolve(__dirname,'dist'),// 打包后文件的名字filename:'bundle.js',// 告訴webpack不使用箭頭函數(shù)environment:{arrowFunction:false}},// 指定webpack 打包時要使用的模塊module:{// 指定加載規(guī)則rules:[{// test 指定規(guī)則生效的文件test:/\.ts$/,// 要使用的loadderuse:[// 配置babel 做兼容{// 指定加載器loader:"babel-loader",// 設(shè)置babeloptions:{// 設(shè)置預(yù)定義的環(huán)境presets:[[// 指定環(huán)境插件"@babel/preset-env",// 配置信息{// 要兼容的目標(biāo)瀏覽器targets:{"chrome":"58","ie":"11"},// 指定corejs版本"corejs":"3",// 使用corejs的方式? "usage" 表示按需加載"useBuiltIns":"usage"}]]}},'ts-loader'],// 要排除的文件exclude:/node-modules/}]},// 配置wenpack插件plugins:[// 打包前刪除dist目錄newCleanWebpackPlugin(),// 自動構(gòu)建html文件newHTMLWebpackPlugin({// title: "這是一個自定義的title"template:"./src/index.html"}),],// 用來設(shè)置引用模塊resolve:{extensions:['.ts','.js']}}
5.3 依賴包
{"name":"part2","version":"1.0.0","description":"","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack","start":"webpack serve --open chrome.exe"},"keywords":[],"author":"","license":"ISC","devDependencies":{"@babel/core":"^7.14.3","@babel/preset-env":"^7.14.2","babel-loader":"^8.2.2","clean-webpack-plugin":"^4.0.0-alpha.0","core-js":"^3.12.1","html-webpack-plugin":"^5.3.1","ts-loader":"^9.2.1","typescript":"^4.2.4","webpack":"^5.37.1","webpack-cli":"^4.7.0","webpack-dev-server":"^3.11.2"}}
6 class 類
6.1 類的基本使用
// 使用class 關(guān)鍵字來定義/*
? ? 對象包括包含兩個部分
? ? ? ? 屬性
? ? ? ? 方法
*/classPerson{/*
? ? ? ? 直接定義的屬性是實例屬性,需要通過對象的實例去訪問:
? ? ? ? ? ? const per = new Person()
? ? ? ? ? ? per.name
? ? ? ? 使用static開頭的是靜態(tài)屬性
? ? ? ? ? ? Person.age
? ? ? ? readonly 開頭的屬性表示一個只讀屬性
? ? */// 定義實例屬性readonlyname:string='孫悟空'// 在屬性前使用static關(guān)鍵字可以定義類屬性(靜態(tài)屬性)staticreadonlyage:number=18// 定義方法sayHello(){console.log('hello');}}constper=newPersonconsole.log(per);console.log(Person.age);per.sayHello()
6.2 構(gòu)造函數(shù)
classDog{name:stringage:number// 構(gòu)造函數(shù)會在對象創(chuàng)建的時候調(diào)用constructor(name:string,age:number){// 在實例方法中,this就表示當(dāng)前的實例// 在構(gòu)造函數(shù)中當(dāng)前對象就是新建的哪個對象// 可以通過this向新建的對象中添加屬性this.name=namethis.age=age// console.log(this);}back(){// alert('旺旺旺')// 在方法中可以通過this來表示當(dāng)前調(diào)用方法的對象console.log(this);}}constdog=newDog('小黑',12)constdog2=newDog('小白',23)console.log(dog);console.log(dog2);dog.back()
7 繼承
7.1 繼承使用 (extends關(guān)鍵字)
(function(){// 定義 Animal 類classAnimal{name:stringage:numberconstructor(name:string,age:number){this.name=namethis.age=age}sayHello(){console.log('動物在叫');}}/*
? ? ? ? Dog extends Animal
? ? ? ? ? ? 此時,Animal被稱為父類,Dog被稱為子類
? ? ? ? ? ? 使用繼承后,子類會擁有父類所有的方法和屬性
? ? ? ? ? ? 如果在子類中添加了和父類相同的方法,則子類方法會覆蓋父類的方法 ,這種叫方法重寫
? ? */// 定義一個狗的類// 使Dog類繼承Animal類classDogextendsAnimal{run(){console.log(`${this.name}再跑`);}}// 定義一個貓的類// 使Cat類繼承Animal類classCatextendsAnimal{sayHello(){console.log('喵喵喵');}}constdog=newDog('旺財',5)constcat=newCat('咪咪',3)console.log(dog);dog.sayHello()dog.run()console.log(cat);cat.sayHello()})()
7.1 super關(guān)鍵字
(function(){class Animal{name:string? ? ? ? constructor(name:string){this,name = name}sayHello (){console.log('動物在叫');}}class Dog extends Animal{age:number? ? ? ? constructor (name:string,age:number){// 如果在子類中寫了構(gòu)造函數(shù),此時在子類的構(gòu)造函數(shù)中必須對父類的構(gòu)造函數(shù)調(diào)用super(name)// 調(diào)用父類構(gòu)造函數(shù)this.age = age}sayHello (){// 在類的方法中 super 就表示當(dāng)前類的父類super.sayHello()}}const dog = new Dog('旺財',23)? ? dog.sayHello()})()
8 抽象類? (abstract 關(guān)鍵字)
(function(){/*
? ? ? ? 以 abstract 開頭的類是抽象類
? ? ? ? ? ? 抽象類和其他的類區(qū)別不大,只是不能用來創(chuàng)建對象?
? ? ? ? ? ? 抽象類就是專門用來被繼承的類
? ? ? ? ? ? 抽象類中可以添加抽象方法
? ? */abstract class Animal{name:string? ? ? ? constructor(name:string){this,name = name}// 定義一個抽象方法// 抽象方法使用 abstract 開頭,沒有方法體// 抽象方法只能定義在抽象類中,子類必須對抽象方法進(jìn)行重寫abstract sayHello ():void}class Dog extends Animal{sayHello (){console.log('旺旺旺旺');}}class Cat extends Animal{// 直接這個不重寫 父類定義的抽象方法就會報錯}const dog = new Dog('旺財')? ? dog.sayHello()})()
10 接口 (interface、implements 關(guān)鍵字)
(()=>{// 描述一個對象類型typemyType={name:string,age:number}constobj:myType={name:'sss',age:23}/*
? ? ? ? 接口用來定義一個類結(jié)構(gòu), 用來定義一個類中應(yīng)該包含那些屬性和方法
? ? ? ? ? ? 同時接口也可以當(dāng)成類型聲明去使用
? ? */interfacemyInterface{name:string,age:number}interfacemyInterface{gender:string}// 接口可以在定義類的時候去限制類的結(jié)構(gòu)// 接口中的所有屬性都不能有實際的值// 接口只定義對象的結(jié)構(gòu),而不考慮實際值// 在接口中所有方法都是抽象方法interfacemyinter{name:stringsayHello():void}/*
? ? ? ? 定義類時,可以使類去實現(xiàn)一個口接口
? ? ? ? ? ? 實現(xiàn)接口就是使類滿足接口的要求
? ? */classMyClassimplementsmyinter{name:stringconstructor(name:string){this.name=name}sayHello(){console.log('大家好'+this.name)}}constmyCalss=newMyClass('李四')myCalss.sayHello()})()
11 屬性的封裝 (public、private關(guān)鍵字 )
(()=>{// 表示人的類classPerson{//? Ts 可以在屬性前添加屬性的修飾符/*
? ? ? ? ? ? public 修飾的屬性可以在任意位置修改、訪問(包括子類)? 默認(rèn)值
? ? ? ? ? ? private 私有屬性,只能在類的內(nèi)部修改 訪問
? ? ? ? ? ? ? ? - 可以通過在類中添加方法使得私有屬性可以訪問
? ? ? ? ? ? protected? 受保護(hù)的,只能到當(dāng)前類和當(dāng)前的子類中訪問
? ? ? ? */private_name:string;private_age:number;constructor(name:string,age:number){this._name=namethis._age=age}// 定義方法,用來獲取name屬性getName(){returnthis._name}// 定義一個方法用來設(shè)置name屬性setName(value:string){this._name=value}getAge(){returnthis._age}setAge(value:number){// 判斷年齡是否合法if(value>=0){this._age=value}}// TS 中設(shè)置getter方法的方式getname(){returnthis._name}setname(value:string){this._name=value}getage(){returnthis._age}setage(value:number){if(value<0){return}this._age=value}}constpreson=newPerson('孫悟空',23)/*
? ? ? ? 現(xiàn)在屬性是在對象中設(shè)置的,屬性可以任意修改
? ? ? ? ? ? 屬性可以任意修改將會導(dǎo)致對象中的數(shù)據(jù)變得非常不安全
? ? */// preson.setName('租八戒')// preson.setAge(-33)preson.name='租八戒'preson.age=-3console.log(preson);// _name: "租八戒", _age: 23})()
12 泛型
// function fn(a: number):number {//? ? return a// }/*
? ? 在定義函數(shù)或是類時,如果遇到類型不明確就可以使用泛型
*/functionfn<T>(a:T):T{returna}// 可以直接調(diào)用具有泛型的函數(shù)fn(10)// 不指定泛型,TS可以自動對類型進(jìn)行推斷fn<string>('hello')// 指定泛型functionfn2<T,K>(a:T,b:K):T{console.log(b)returna}fn2(123,'hello')interfaceInter{length:number}// T extends Inter 表示泛型 T 必須是 Inter 實現(xiàn)類(子類)functionfn3<TextendsInter>(a:T):number{returna.length}fn3('123')fn3({length:232})classMyClass<T>{name:Tconstructor(name:T){this.name=name}}constmc=newMyClass<string>('詢')
14 命名空間 (namespace)
namespceA{interfaceAnmal{name:string;eat():viod}exportclassDogimplemnts Anmal{name:string;constructor(theName:string){this.name=theName}eat(){console.log(${this.name}吃狗糧)}}}namespceB{interfaceAnmal{name:string;eat():viod}exportclassDogimplemnts Anmal{name:string;constructor(theName:string){this.name=theName}eat(){console.log(${this.name}吃狗糧)}}}vard=newA.Dog('張三')d.eat()varf=newB.Dog('李四')f.eat()
15 裝飾器
裝飾器是一種特殊的聲明,它能夠被附加到類聲明,方法,屬性,或則參數(shù)上,可以修飾行為
常見裝飾器:類裝飾器、屬性裝飾器、方法裝飾器、參數(shù)裝飾器
裝飾器的寫法:普通裝飾器(無法傳參)、裝飾器工廠(可傳參)
類裝飾器:在類型聲明前被聲明,類裝飾器應(yīng)用于類構(gòu)造函數(shù),可用來監(jiān)視,修改或替換類定義,傳入一個參數(shù)
// 類裝飾器functionlogClass(params:any){console.log(params);// params 就是當(dāng)前類params.prototype.apiUrl='動態(tài)擴展的屬性'params.prototype.run=function(){console.log('我是一個run方法');}}@logClassclassHttpClient{constructor(){}getData(){}}varhttp:any=newHttpClient()console.log(http.apiUrl);http.run()
類裝飾器工廠:
functionlogClass(params:string){returnfunction(target:any){console.log(target);console.log(params);target.prototype.apiUrl=params}}@logClass('http://www.yes.com')classHttpClient{constructor(){}getData(){}}varhttp:any=newHttpClient()console.log(http.apiUrl);
屬性裝飾器:
// 屬性裝飾器functionlogProperty(params:any){returnfunction(target:any,attr:any){console.log(target);console.log(attr);target[attr]=params}}classHttpClient{@logProperty('http://weqweqwe.com')publicurl:any|undefinedconstructor(){}getData(){console.log(this.url);}}varhttp:any=newHttpClient()http.getData()