摘要:常見內(nèi)存泄漏情形全局變量被忘記的或者閉包引用閉包概念有權(quán)訪問另一個(gè)函數(shù)作用域的變量的函數(shù)。會(huì)話存儲(chǔ)刷新頁面依舊存在,與在持久上不同外,其余一致。請(qǐng)求向指定的資源提交被處理的數(shù)據(jù),數(shù)據(jù)量和類型沒限制,不主動(dòng)緩存,頁面刷新數(shù)據(jù)會(huì)被重新提交。
defer 腳本延遲執(zhí)行,適用于外部腳本文件
async 立即下載,不保證順序(建議不修改DOM,避免重繪)
CDN加速 (Content Delivery Network,內(nèi)容分發(fā)網(wǎng)絡(luò)) 提高訪問網(wǎng)站的響應(yīng)速度
內(nèi)存
js內(nèi)存回收機(jī)制:解除引用
內(nèi)存溢出:內(nèi)存不夠,系統(tǒng)會(huì)提示內(nèi)存溢出,有時(shí)候會(huì)自動(dòng)關(guān)閉軟件
內(nèi)存泄漏:未能釋放已經(jīng)不再使用的內(nèi)存,不是指內(nèi)存在物理上的消失,而是內(nèi)存的浪費(fèi)。
常見內(nèi)存泄漏情形:1.全局變量、2.被忘記的Timers或者callbacks、3.閉包、4.DOM引用
閉包
概念:有權(quán)訪問另一個(gè)函數(shù)作用域的變量的函數(shù)。
作用:匿名自執(zhí)行函數(shù)、結(jié)果緩存、封裝、實(shí)現(xiàn)類和繼承
函數(shù)封裝模式
//工廠模式:在函數(shù)中返回一個(gè)創(chuàng)建并返回一個(gè)對(duì)象 function createClass0(params){ var o = new Object(); o.name = params; o.fn0 = function(){ console.log(this.name); } return o; } var obj = createClass0(params); console.log(obj.constructor == createClass0); //false console.log(obj instanceof createClass0); //false //構(gòu)造函數(shù)模式:es6的類也是通過該模式實(shí)現(xiàn) function Class0(params){ this.name = params; this.fn0 = fn0; this.fn1 = function(){ console.log(this.name) } } function fn0(){ console.log(this.name) } var obj = new Class0(params); console.log(obj.constructor == Class0); //true console.log(obj instanceof Class0); //true //原型模式:屬性與方法掛在原型鏈上 function Class0(){} Class0.prototype = { name: params, fn0: function(){ console.log(this.name) } } var obj = new Class0(); console.log(obj.constructor == Class0);//true console.log(obj instanceof Class0); //true Object.defineProperty(Class0.prototype,"constructor",{ enumerable: false, value: Class0 }) console.log(obj.constructor == Class0); //false //動(dòng)態(tài)原型模式: function Class0(params){ this.name = params; if(typeof this.fn0 != "function"){ Class0.prototype.fn0 = function(){ console.log(this.name) } } } var obj = new Class0(params); console.log(obj.constructor == Class0); //true console.log(obj instanceof Class0); //true //寄生構(gòu)造函數(shù)模式: function Class0(params){ var o = new Object(); o.name = params; return o; } var obj = new Class0(params); console.log(obj.constructor == Class0); //false console.log(obj instanceof Class0); //false //穩(wěn)妥構(gòu)造函數(shù)模式:無法訪問其屬性 function Class0(params){ var o = new Object(); var name = params; o.fn0 = function(){ console.log(name); } return o; } var obj = Class0(params); console.log(obj.constructor == Class0); //false console.log(obj instanceof Class0); //false //繼承:js沒有借口繼承,只有實(shí)現(xiàn)繼承,依靠原型鏈實(shí)現(xiàn) //經(jīng)典繼承:借用構(gòu)造函數(shù) function Class0(params){ this.name0 = params; this.fn0 = function(){ console.log(this.name); } } function subClass0(params){ Class0.call(this,params); this.name1 = params; subClass0.prototype.fn1 = function(){ console.log(this.name1); } } var obj = new subClass0(params); console.log(obj.constructor == subClass0); //true console.log(obj instanceof subClass0); //true console.log(obj.constructor == Class0); //false console.log(obj instanceof Class0); //false //組合繼承:es6類的繼承通過該模式實(shí)現(xiàn) function Class0(params){ this.name0 = params; this.fn0 = function(){ console.log(this.name0); } } function subClass0(params){ Class0.call(this,params); this.name1 = params; subClass0.prototype.fn1 = function(){ console.log(this.name1); } } subClass0.prototype = new Class0(); subClass0.prototype.constructor = subClass0; var obj = new subClass0(params); console.log(obj.constructor == subClass0); //true console.log(obj instanceof subClass0); //true console.log(obj.constructor == Class0); //false console.log(obj instanceof Class0); //true
BOM
概念:瀏覽器對(duì)象模型
核心對(duì)象:window,通過js訪問瀏覽器窗口的一個(gè)接口,也是ECMAScript規(guī)定的Global對(duì)象。
窗口框架:frame、iframe
窗口位置:window.screenLeft/window.screenX,window.moveBy(x,y); window.moveTo(x,y);
窗口大小:window.resizeTo(width,height); window.resizeBy(dWidth,dHeight);
導(dǎo)航彈窗:let win = window.open("..."); win.close();
location
hash:URL的hash字符串
host:服務(wù)器名稱和端口號(hào)
hostname:服務(wù)器名稱
href:當(dāng)前加載頁面的完整URL
pathname:URL中的目錄
port:URL中制定的端口號(hào)
prptocol:頁面使用的協(xié)議
search:URL的查詢字符串,以?開頭
改變URL會(huì)生成新記錄,禁用歷史記錄跳轉(zhuǎn)可通過location.replace("...")實(shí)現(xiàn)
刷新頁面:location.reload(); location.reload(true);
navigator
離線檢測(cè):onLine 地理信息:geolocation navigator.geolocation.getCurrentPosition((position)=>{ //成功的回調(diào) },(error)=>{ //錯(cuò)誤的回調(diào) },{ enableHighAccuracy: true, //盡可能使用最準(zhǔn)確的位置信息 timeout: 5000, //等待位置信息的最長(zhǎng)時(shí)間 maximumAge: 25000 //上一次取得坐標(biāo)信息的有效時(shí)間,時(shí)間到則重新獲取 }); //跟蹤監(jiān)控 let watchId = navigator.geolocation.watchPosition(position)=>{ //成功的回調(diào) },(error)=>{ //錯(cuò)誤的回調(diào) }); clearWatch(watchId); //關(guān)閉跟蹤 瀏覽器中安裝的插件信息:plugins //IE瀏覽器無效 function hasPlugin(name){ return Array.from(navigator.plugins).some(item => item.name.toLowerCase().includes(name.toLowerCase()) ) } hasPlugin("Flash"); //IE瀏覽器 function hasIEPlugin(name){ try{ new ActiveXObject(name); return true; }catch(ex){ return false; } } hasIEPlugin("ShockwaveFlash.ShockwaveFlash"); cookie是否啟用:cookieEnabled 瀏覽器所在的系統(tǒng)平臺(tái):platform 用戶代理:userAgent(可用于判斷瀏覽器引擎、版本、終端等) //簡(jiǎn)易的瀏覽器類型判斷 function browserType(){ //判斷瀏覽器類型 let userAgent = navigator.userAgent; let type; switch(userAgent){ case userAgent.includes("MSIE"): type = "IE"; break; case userAgent.includes("Firefox"): type = "Firefox"; break; case userAgent.includes("Chrome"): type = "Chrome"; break; case userAgent.includes("Opera"): type = "Opera"; break; case userAgent.includes("Safari"): type = "Safari"; break; case userAgent.includes("Netscape"): type = "Netscape"; break; default: console.log(userAgent); break; } return type; }
history
頁面前進(jìn):history.forward(); history.go(1);
頁面后退:history.back(); history.go(-1);
跳轉(zhuǎn)至可能存在的最近某個(gè)頁面(不存在則什么都不做):history.go("...");
歷史記錄數(shù)量:history.length(hash改變會(huì)使歷史記錄增加)
系統(tǒng)對(duì)話框
alert(val); //警告窗 confirm(val); //確認(rèn)窗,選擇OK,則返回true prompt(val,""); //輸入窗,選擇OK,則返回輸入框內(nèi)容,否則返回null
數(shù)據(jù)存儲(chǔ)
cookie:信息越大,對(duì)服務(wù)器的請(qǐng)求時(shí)間越長(zhǎng),故瀏覽器對(duì)其大小有限制,總量不到4K
//創(chuàng)建cookie function setCookie(name, value, expires, path, domain, secure) { var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);//防止中文亂碼,所以需要編碼 (expires instanceof Date) && (cookieText += "; expires=" + expires); //有效期 path && (cookieText += "; path=" + path); //設(shè)置域的路徑 domain && (cookieText += "; domain=" + domain); //設(shè)置哪個(gè)域的請(qǐng)求中都會(huì)包含該cookie信息,默認(rèn)為設(shè)置cookie的域 secure && (cookieText += "; secure"); //只有在使用SSL連接的時(shí)候才發(fā)送到服務(wù)器 document.cookie = cookieText; } //獲取cookie function getCookie(name) { var cookieName = encodeURIComponent(name) + "="; var cookieStart = document.cookie.indexOf(cookieName); var cookieValue = null; if (cookieStart > -1) { var cookieEnd = document.cookie.indexOf(";", cookieStart); if (cookieEnd == -1) { cookieEnd = document.cookie.length; } cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd)); } return cookieValue; } //刪除cookie function unsetCookie(name) { document.cookie = name + "= ; expires=" + new Date(0); }
localStorage:本地存儲(chǔ),容量5M左右,值類型限定為string類型,localStorage本質(zhì)上是對(duì)字符串的讀取,如果存儲(chǔ)內(nèi)容多的話會(huì)消耗內(nèi)存空間,會(huì)導(dǎo)致頁面變卡,另外在部分瀏覽器隱私模式下不可讀取。
sessionStorage:會(huì)話存儲(chǔ)(刷新頁面依舊存在),與localStorage在持久上不同外,其余一致。
indexedDB:儲(chǔ)存空間不少于250M,沒有上限,異步設(shè)計(jì),支持二進(jìn)制儲(chǔ)存(ArrayBuffer對(duì)象和Blob對(duì)象)
localforage:js庫,異步操作(自動(dòng)加載最佳驅(qū)動(dòng)程序,從IndexedDB到localStorage)
//存儲(chǔ) localforage.setItem("key", "value"); localforage.setItem("key", "value").then(()=>{ ... }).catch(err=>{ console.log(err); }); localforage.setItem("key", "value").then(()=>{ return localforage.getItem("key"); }).then(val=>{ console.log(val); }).catch(err=>{ console.log(err); }); //獲取 localforage.getItem("key").then(()=>{ ... }).catch(err=>{ console.log(err); }); //刪除 localforage.removeItem("key"); localforage.removeItem("key").then(()=>{ ... }).catch(err=>{ console.log(err); }); //清空 localforage.clear(); localforage.clear().then(()=>{ ... }).catch(err=>{ console.log(err); }) //遍歷 localforage.iterate((value, key)=>{ console.log(key,value); }).then(()=>{ ... }).catch(err=>{ console.log(err); });
DOM
//querySelector選擇器,返回匹配的一個(gè)元素 let parentElement = document.querySelector(".container"); //創(chuàng)建元素 let element = document.createElement("button"); //設(shè)置元素的屬性 element.setAttribute("onclick", `javascript:alert("click the span!");`); //設(shè)置內(nèi)容,innerText有兼容性問題,采用innerHTML較為方便 element.innerHTML = "創(chuàng)建元素添加的元素"; //設(shè)置內(nèi)聯(lián)樣式 element.style.color = "blue"; //在容器中末尾加入元素 parentElement.appendChild(element); //添加元素的另一種方式,該方式適合一次性創(chuàng)建多節(jié)點(diǎn) let elementHtml = `` parentElement.innerHTML += elementHtml; //元素的克隆.cloneNode(true),父節(jié)點(diǎn).parentNode,首個(gè)子節(jié)點(diǎn).firstChild、下一個(gè)兄弟節(jié)點(diǎn).nextElementSibling,加入到某個(gè)元素的前面refNode.parentNode.insertBefore(newNode,refNode) parentElement.insertBefore(parentElement.parentNode.cloneNode(true), parentElement.firstChild.nextElementSibling);//克隆一份parentElement的父節(jié)點(diǎn),并將其放在parentElement的第一個(gè)子元素的下一個(gè)元素的前面 let newElement = element.cloneNode(true); newElement.innerHTML = "newElement"; //容器的最后一個(gè)子元素.lastChild,上一個(gè)兄弟節(jié)點(diǎn).previousElementSibling,替換元素refNode.parentNode.insertBefore(newNode,refNode) parentElement.replaceChild(newElement, parentElement.lastChild.previousElementSibling);//替換parentElement最后一個(gè)子元素的上一個(gè)元素 //querySelectorAll選擇器返回NodeList let firstContainer = document.querySelectorAll(".container")[0]; //刪除元素node.parentNode.removeChild(node),元素子節(jié)點(diǎn).children firstContainer.removeChild(firstContainer.children[0]);//刪除firstContainer這個(gè)元素的第一個(gè)子元素 //動(dòng)態(tài)添加樣式規(guī)則 document.querySelector("head").innerHTML += `` //移動(dòng)滾動(dòng)條至firstContainer這個(gè)元素可見,true或不傳表示元素頂端對(duì)齊,false表示底端在可視區(qū)域中間 firstContainer.scrollIntoView(true); //獲取元素的真正樣式 window.getComputedStyle(element) console.log(window.getComputedStyle(firstContainer)) //獲取元素的真正樣式 console.log(firstContainer.style); //獲取元素的內(nèi)聯(lián)樣式 //獲取元素的尺寸及相對(duì)于瀏覽器可視窗口的位置(非文檔,故頁面發(fā)生滾動(dòng)會(huì)改變).getBoundingClientRect(),在計(jì)算坐標(biāo)使用時(shí)可用clientX配合getBoundingClientRect().left console.log(firstContainer.getBoundingClientRect());
事件流
事件流過程:捕獲過程、目標(biāo)、冒泡過程
事件捕獲:從大到小,極少使用
事件冒泡:從小到大,常用,雖然各瀏覽器有些差異
阻止冒泡:e.stopPropagation(),IE9前使用e.cancelBubble=true
阻止默認(rèn)行為:e.preventDefault(),IE9前使用e.returnValue=false
默認(rèn)行為:如表單按鈕的提交,標(biāo)簽的跳轉(zhuǎn)等
事件委托:利用事件冒泡,監(jiān)聽頂級(jí)的DOM(事件處理程序數(shù)量關(guān)系到頁面的整體運(yùn)行性能)
頁面事件
pageshow事件:頁面顯示時(shí)觸發(fā),事件目標(biāo)為document,但必須將其事件處理程序添加到window,參數(shù)為event
pagehide事件:頁面卸載時(shí)觸發(fā),事件目標(biāo)為document,但必須將其事件處理程序添加到window,參數(shù)為event
haschange事件:URL的參數(shù)列表發(fā)生變化時(shí)觸發(fā),但必須將其事件處理程序添加到window,參數(shù)為event
visibilitychange事件:綁定在document上,當(dāng)頁面最小化或切換瀏覽器標(biāo)簽等可見狀態(tài)改變觸發(fā),documen.hidden可查看頁面可見度狀態(tài)
document.addEventListener("visibilitychange",function(){ console.log(document.hidden); })
表單事件
默認(rèn)行為:表單中的最后一個(gè)按鈕會(huì)自動(dòng)提交表單
form.submit()主動(dòng)提交表單
form.reset()重置表單
form.checkValidity()表單驗(yàn)證配合require和pattern使用
noValidate屬性禁用表單驗(yàn)證
過濾輸入,屏蔽某些詞的默認(rèn)行為:監(jiān)聽keypress事件,e.preventDefault();
富文本編輯的實(shí)現(xiàn):
①iframe實(shí)現(xiàn),空文檔的designMode設(shè)置為on,getSeclection事件獲取具體信息;
②設(shè)置contenteditable屬性實(shí)現(xiàn),通過document.execCommand()實(shí)現(xiàn)富文本操作,如document.execCommand("blod", false, null);實(shí)現(xiàn)粗體文本。
鼠標(biāo)事件
雙擊事件順序:mousedown、mouseup、click、mousedown、mouseup、click、dblclick
移入容器事件順序過程:mouseover(在不同元素間觸發(fā))、mouseenter、mousemove、mouseout(在不同元素間觸發(fā))、mouseleave
右鍵點(diǎn)擊事件:contextmenu(H5事件)
位置信息:
clientX(鼠標(biāo)相對(duì)于瀏覽器窗口可視區(qū)域的X坐標(biāo))
offsetX(鼠標(biāo)相對(duì)于事件源元素的X坐標(biāo),存在兼容性問題)
screenX(鼠標(biāo)相對(duì)于用戶顯示器屏幕左上角的X坐標(biāo))
pageX(鼠標(biāo)相對(duì)于文檔區(qū)域的X坐標(biāo),存在兼容性問題)
event對(duì)象屬性:
type(事件類型)
detail(點(diǎn)擊次數(shù))
target(事件源元素)
path(數(shù)組,冒泡的路徑)
拖放事件
相關(guān)事件:dragstart、drag、dragend、dragenter、dragover、dragleave、drop
投放目標(biāo) 被拖拽的物體dragover(e){ e.preventDefault(); } drag(e){ e.dataTransfer.setData("id",e.target.id); } drop(e){ e.preventDefault(); let data = e.dataTransfer.getData("id"); e.target.appendChild(document.getElementById(data)); }
觸摸與手勢(shì)事件
移動(dòng)端點(diǎn)擊事件順序:touchstart、touchend、mouseover、mouseenter、mousemove、mousedown、mouseup、click
touchmove事件:需要阻止默認(rèn)行為以防止屏幕滾動(dòng)
touchcancel事件:當(dāng)系統(tǒng)停止跟蹤觸摸時(shí)觸發(fā)
gesturestart事件:當(dāng)一個(gè)手指已經(jīng)按在屏幕上而另一個(gè)手指又觸摸時(shí)觸發(fā)
gesturechange事件:當(dāng)觸摸屏幕的任何一個(gè)手指的位置發(fā)生變化時(shí)改變
gestureend事件:當(dāng)任何一個(gè)手指從屏幕上面移開時(shí)觸發(fā)
觸摸事件特有的event對(duì)象屬性:
touches(表示當(dāng)前跟蹤的觸摸操作的Touch對(duì)象的數(shù)組)
targetTouchs(特定于事件目標(biāo)的Touch對(duì)象的數(shù)組)
changeTouches(上次觸摸以來發(fā)生了什么改變的Touch對(duì)象的數(shù)組)
rotation(手勢(shì)變化引起的旋轉(zhuǎn)角度,從0開始,順正逆負(fù))
scal(手指間的距離變化,從1開始,與距離呈正相關(guān))
模擬事件
UIEvents UI事件
MouseEvents 鼠標(biāo)事件
MutationEvents DOM變動(dòng)事件
HTMLEvents HTML事件
模擬鼠標(biāo)點(diǎn)擊事件: 1.創(chuàng)建鼠標(biāo)事件的event對(duì)象 let event = document.createEvent("MouseEvents"); 2.設(shè)置觸發(fā)的參數(shù) //可簡(jiǎn)寫,如event.initMouseEvent("click"); event.initMouseEvent(事件類型,...event對(duì)象其他參數(shù)); /*參數(shù)順序:type、bubbles(是否冒泡)、cancelable(事件是否可取消)、view(document.defaultView)、detail、screenX、screenY、clientX、clientY、ctrlKey(是否按下ctrl)、altKey(是否按下alt)、shiftKey(是否按下shiftKey)、metaKey(是否按下metaKey)、button(表示按下哪個(gè)鼠標(biāo)鍵)、relatedTarget(事件相關(guān)的對(duì)象,用于模擬mouseover/mouseout)*/ 3.觸發(fā)事件 document.getElementById("btn").dispatchEvent(event);
媒體元素
音頻播放器:audio
視頻播放器:video
通過play()和pause()可手工控制媒體文件的播放和暫停,ended事件當(dāng)播放結(jié)束時(shí)觸發(fā)
繪圖技術(shù)
canvas:2D繪圖,可進(jìn)行圖片與圖像的互轉(zhuǎn),通過變換和合成繪制復(fù)雜圖像
//獲取canvas內(nèi)容生成的URI let imgURI = canvas.toDataURL("image/png"); let img = document.createElement("img"); img.src = imgURI; document.body.appendChild(img);
svg:支持事件驅(qū)動(dòng),通過foreignObject可實(shí)現(xiàn)svg和普通HTML元素的融合
WebGL:3D繪圖,非W3C標(biāo)準(zhǔn)
ajax
Asynchronous Javascript And XML,即異步JavaScript和XML,是一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的網(wǎng)頁開發(fā)技術(shù)。
//封裝ajax function ajax(obj) { var xhr = new XMLHttpRequest(); //創(chuàng)建XMLHttpRequest實(shí)例 obj.url = obj.url + "?rand=" + Math.random(); //為url加時(shí)間戳 if(obj.method === "get") obj.url += "&" + obj.data; if(obj.async) xhr.onreadystatechange = ()=>{ (xhr.readyState == 4) && callback(); } //異步請(qǐng)求當(dāng)readyState == 4才執(zhí)行回調(diào) xhr.open(obj.method, obj.url, obj.async); //發(fā)送請(qǐng)求 if(obj.method === "post"){ xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send(obj.data); }else{ xhr.send(null); } if(!obj.async) callback(); //同步請(qǐng)求 function callback() { if(xhr.status == 200){ obj.success(xhr.responseText); } //回調(diào)傳遞參數(shù) else{ console.log("獲取數(shù)據(jù)錯(cuò)誤!錯(cuò)誤代號(hào):" + xhr.status + ",錯(cuò)誤信息:" + xhr.statusText); } } } ajax({ method : "post/get", url : "...", data : "", success : (res)=>{ console.log(res); }, async : true });
get與post請(qǐng)求
get請(qǐng)求:從指定的資源請(qǐng)求數(shù)據(jù),數(shù)據(jù)量和類型有限制(因?yàn)閿?shù)據(jù)放在請(qǐng)求頭中,瀏覽器對(duì)其長(zhǎng)度有限制),會(huì)被緩存,且數(shù)據(jù)在url上可見,導(dǎo)致安全性相對(duì)低點(diǎn)。
post請(qǐng)求:向指定的資源提交被處理的數(shù)據(jù),數(shù)據(jù)量和類型沒限制,不主動(dòng)緩存,頁面刷新數(shù)據(jù)會(huì)被重新提交。
底層分析:對(duì)于get請(qǐng)求,瀏覽器會(huì)把http header和data一并發(fā)送出去,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù)),整個(gè)過程產(chǎn)生一個(gè)TCP數(shù)據(jù)包;對(duì)于post請(qǐng)求,瀏覽器先發(fā)送header,服務(wù)器響應(yīng)100 continue,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 ok(返回?cái)?shù)據(jù)),整個(gè)過程產(chǎn)生兩個(gè)TCP數(shù)據(jù)包,導(dǎo)致時(shí)間消耗,網(wǎng)絡(luò)環(huán)境暢通情況下可無視。
File API
let reader = new FileReader(); reader.readAsText(file,encoding); //以純文本的形式讀取文件,讀取到的文本保存在result屬性中 //reader.readAsDataURL(file); //讀取文件以數(shù)據(jù)URI的形式保存在result屬性中 //reader.readAsBinaryString(file); //讀取文件并將一個(gè)字符串保存在result屬性中,字符串中的每個(gè)字符表示一字節(jié) //reader.readAsArrayBuffer(file); //讀取文件并將一個(gè)包含文件內(nèi)容的ArrayBuffer保存在result屬性中 reader.progress = (event)=>{ if(event.lengthComputable){ console.log(event.loaded + "/" + event.total); } } reader.onerror = ()=>{ console.log(reader.error.code); } reader.onload = function(){ console.log(reader.result); }
對(duì)象防篡改
Object.preventExtensions(obj); //對(duì)象不可拓展,禁止添加屬性或方法 Object.seal(obj); //密封對(duì)象,不可刪除屬性和方法 Object.freeze(obj); //凍結(jié)對(duì)象,不可拓展、且密封、不可編輯
String、JSON、Object相互轉(zhuǎn)化
//js對(duì)象轉(zhuǎn)JSON function jsToJSON(obj){ let objFnToStr = fnToStr(obj); return JSON.stringify(objFnToStr); } //字符串轉(zhuǎn)JSON function strToJSON(str){ let obj = eval("("+str+")"); return jsToJSON(obj); } //JSON轉(zhuǎn)js對(duì)象 function JSONToJs(json){ let obj = JSON.parse(json); return strToFn(obj); } //將js對(duì)象中的函數(shù)字符串解析為函數(shù) function strToFn(obj){ var o = obj instanceof Array ? [] : {}; for(var k in obj) { switch(typeof(obj[k])){ case "object": o[k] = obj[k] ? strToFn(obj[k]) : null; break; case "string": o[k] = obj[k].match(/^s*(functions*(.*)s*)|((.*)s*=>s*)/) ? eval("("+obj[k]+")") : obj[k]; break; default: o[k] = obj[k]; break; } } return o; } //將js對(duì)象中的函數(shù)類型轉(zhuǎn)為字符串 function fnToStr(obj){ var o = obj instanceof Array ? [] : {}; for(var k in obj) { switch(typeof(obj[k])){ case "object": o[k] = obj[k] ? fnToStr(obj[k]) : null; break; case "function": o[k] = obj[k] + ""; break; default: o[k] = obj[k]; break; } } return o; }
定時(shí)器
//延遲調(diào)用 let timeId = setTimeout(fn,time); clearTimeout(timeId); //間歇調(diào)用 let timeId = setInterval(fn,time); clearInterval(timeId); //定時(shí)器中的定時(shí)器 setTimeout(function(){ //... setTimeout(arguments.callee, interval); }) //沉睡排序法 [1,5,2,4,100,3].forEach(n=>{ setTimeout(()=>{ console.log(n) }, n); })
html與文本的轉(zhuǎn)換
//字符串轉(zhuǎn)html字符串,參數(shù):html傳入的字符串,type是否返回標(biāo)簽結(jié)構(gòu),默認(rèn)只返回內(nèi)容,escape表示是否需要轉(zhuǎn)義 function escapeHtml(html,type,escape){ //type:content/html,escape:轉(zhuǎn)義/不轉(zhuǎn)義 let objE = document.createElement("div"); objE.innerHTML = html; type ? (escape ? (html.includes("&") ? (objE.innerText = html) : (objE.innerText = new Option(html).innerHTML)) : (html.includes("<") && (objE.innerText = html))) : (objE.innerHTML = objE.innerText); return objE.innerText; }
錯(cuò)誤處理
//監(jiān)聽除 try catch 捕捉的錯(cuò)誤 window.onerror = (...error)=>{ window.open("http://stackoverflow.com/search?q=[js] + "+error[0]); } //強(qiáng)制報(bào)錯(cuò) var err = new Error("錯(cuò)誤信息"); console.error(err); //單純?nèi)罩据敵觯挥绊懘a執(zhí)行 throw err; //顯示報(bào)錯(cuò),導(dǎo)致后面代碼不解析
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/98138.html
摘要:菜鳥教程這是一個(gè)屬性其值是字符串菜鳥教程同上這是一個(gè)屬性其值是字符串用于定義的函數(shù),可以通過來返回函數(shù)值。它們都有前綴,以便與用戶定義的屬性區(qū)分開來。 開篇語 我最近學(xué)習(xí)了js,取得進(jìn)步,現(xiàn)在學(xué)習(xí)vue.js.建議新手學(xué)習(xí),請(qǐng)不要用npm的方式(vue-cli,vue腳手架),太復(fù)雜了. 請(qǐng)直接下載vue.js文件本地引入,就上手學(xué)習(xí)吧參照菜鳥教程網(wǎng)站的vue.js教程http://...
1、對(duì)象具有唯一標(biāo)識(shí)性,即使完全相同的兩個(gè)對(duì)象也不是同一個(gè)對(duì)象。 (js創(chuàng)建的對(duì)象內(nèi)存地址不同)2、對(duì)象具有狀態(tài) 同一對(duì)象可能處于不同的狀態(tài)下 (js對(duì)象的屬性)3、對(duì)象具有行為 對(duì)象的狀態(tài) 可能因?yàn)樗男袨榘l(fā)生改變 (js對(duì)象的屬性) js對(duì)象獨(dú)特性:具有高度動(dòng)態(tài)性,js賦予使用者再運(yùn)行時(shí)修改對(duì)象狀態(tài)和行為的能力 屬性描述對(duì)象 數(shù)據(jù)屬性 value writable enumerable con...
摘要:鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇下的使用方法,傳送門使用構(gòu)建單頁應(yīng)用新篇華麗的分割線原文地址前言在最近學(xué)習(xí)的時(shí)候,看到國(guó)外一篇講述了如何使用和來構(gòu)建一個(gè)簡(jiǎn)單筆記的單頁應(yīng)用的文章。 鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇 vue2.0 下的 vuex 使用方法,傳送門:使用 Vuex + Vue.js 構(gòu)建單頁應(yīng)用【新篇】 ---------...
摘要:鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇下的使用方法,傳送門使用構(gòu)建單頁應(yīng)用新篇華麗的分割線原文地址前言在最近學(xué)習(xí)的時(shí)候,看到國(guó)外一篇講述了如何使用和來構(gòu)建一個(gè)簡(jiǎn)單筆記的單頁應(yīng)用的文章。 鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇 vue2.0 下的 vuex 使用方法,傳送門:使用 Vuex + Vue.js 構(gòu)建單頁應(yīng)用【新篇】 ---------...
摘要:鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇下的使用方法,傳送門使用構(gòu)建單頁應(yīng)用新篇華麗的分割線原文地址前言在最近學(xué)習(xí)的時(shí)候,看到國(guó)外一篇講述了如何使用和來構(gòu)建一個(gè)簡(jiǎn)單筆記的單頁應(yīng)用的文章。 鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇 vue2.0 下的 vuex 使用方法,傳送門:使用 Vuex + Vue.js 構(gòu)建單頁應(yīng)用【新篇】 ---------...
摘要:鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇下的使用方法,傳送門使用構(gòu)建單頁應(yīng)用新篇華麗的分割線原文地址前言在最近學(xué)習(xí)的時(shí)候,看到國(guó)外一篇講述了如何使用和來構(gòu)建一個(gè)簡(jiǎn)單筆記的單頁應(yīng)用的文章。 鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇 vue2.0 下的 vuex 使用方法,傳送門:使用 Vuex + Vue.js 構(gòu)建單頁應(yīng)用【新篇】 ---------...
閱讀 477·2021-11-22 12:05
閱讀 1541·2021-11-17 09:33
閱讀 3586·2021-11-11 16:54
閱讀 2673·2021-10-14 09:49
閱讀 4046·2021-09-06 15:01
閱讀 1828·2019-08-29 17:23
閱讀 701·2019-08-29 14:09
閱讀 720·2019-08-29 12:28