<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 共享onload事件 ``` function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { oldonload(); func(); } } } ``` ## 在現有的元素后插入一個新元素 ``` function insertAfter(newElement,targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement) { parent.appendChild(newElement); } else { parent.insertBefore(newElement,targetElement.nextSubling) } } ``` ## 查找下一個元素節點 ``` function getNextElement(node){ if (node.nodeType == 1) { return node ; } if (node.nextSibling) { return getNextElement(node.nextSibling); } return null ; } ``` ## 利用JS去更新某個元素的class屬性 ``` function addClass(element,value) { if (!element.className) { element.className = value; } else { newClassName = element.className; newClassName+= " "; newClassName+= value; element.className = newClassName; } } ``` ## ||短路符設置默認值 ``` let person = { name: '張三', age: 38 } let name = person.name || '佚名' ``` ## 字符串拼接使用`${}` ``` let person = { name: 'LiMing', age: 18 } // good function sayHi (person) { console.log(`大家好,我叫${person.name},我今年${person.age}了`) } // best function sayHi ({name, age}) { console.log(`大家好,我叫${name},我今年${age}了`) } ``` ## .函數使用箭頭函數 ``` let arr [18, 19, 20, 21, 22] // bad function findStudentByAge (arr, age) { return arr.filter(function (num) { return num === age }) } // good let findStudentByAge = (arr, age)=> arr.filter(num => num === age) ``` ## 函數參數校驗 ``` // good let checkoutType = () => { throw new Error('參數不能為空') } let findStudentByAge = (arr, age = checkoutType()) => arr.filter(num => num === age) ``` ## if 判斷的優化 ``` let commodity = { phone: '手機', computer: '電腦', television: '電視', gameBoy: '游戲機', } function price(name) { if (name === commodity.phone) { console.log(1999) } else if (name === commodity.computer) { console.log(9999) } else if (name === commodity.television) { console.log(2999) } else if (name === commodity.gameBoy) { console.log(3999) } } price('手機') // 9999 ``` 缺點:代碼太長了,維護和閱讀都很不友好 好一點的方法:`Switch` ``` let commodity = { phone: '手機', computer: '電腦', television: '電視', gameBoy: '游戲機', } const price = (name) => { switch (name) { case commodity.phone: console.log(1999) break case commodity.computer: console.log(9999) break case commodity.television: console.log(2999) break case commodity.gameBoy: console.log(3999) break } } price('手機') // 9999 ``` 更優的方法: 策略模式 策略模式利用組合、委托和多態等技術和思想,可以有效地避免多重條件選擇語句。它提供了對開放—封閉原則的完美支持,將算法封裝在獨立的 strategy 中,使得它們易于切換,易于理解,易于擴展。 ``` const commodity = new Map([ ['phone', 1999], ['computer', 9999], ['television', 2999], ['gameBoy', 3999], ]) const price = (name) => { return commodity.get(name) } price('phone') // 1999 ``` ## includes 的優化 `includes`是 ES7 新增的 API,與`indexOf`不同的是`includes`直接返回的是`Boolean`值,`indexOf`則 返回的索引值, 數組和字符串都有`includes`方法。 需求:我們來實現一個身份認證方法,通過傳入身份 Id 返回對應的驗證結果 ``` //old function verifyIdentity(identityId) { if (identityId == 1 || identityId == 2 || identityId == 3 || identityId == 4) { return '你的身份合法,請通行!' } else { return '你的身份不合法' } } //new function verifyIdentity(identityId) { if ([1, 2, 3, 4].includes(identityId)) { return '你的身份合法,請通行!' } else { return '你的身份不合法' } } ``` ## for 循環 在 JavaScript 中,我們可以使用`for()`,`while()`,`for(in)`,`for(of)`幾種循環,事實上,這三種循環中`for(in)`的效率極差,因為他需要查詢散列鍵,所以應該盡量少用。 for 循環是最傳統的語句,它以變量 i 作為索引,以跟蹤訪問的位置,對數組進行操作。 ``` var arr = ['a', 'b', 'c'] for (var i = 0, length = arr.length; i < length; i++) { console.log(arr[i]) //結果依次a,b,c } ``` 此時`arr.length`只需要計算一次,優化了性能。 ## 數組去重 利用 ES6 的`Set`方法。 `Set`本身是一個構造函數,用來生成`Set`數據結構。`Set`函數可以接受一個數組(或者具有 iterable 接口的其他數據結構)作為參數,用來初始化。`Set`對象允許你存儲任何類型的值,無論是原始值或者是對象引用。它類似于數組,但是成員的值都是唯一的,沒有重復的值。 ``` function unique4(arr) { return [...new Set(arr)] } console.log(unique4([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4])) // [1, 2, 3, 5, 6, 7, 4] ``` ## 箭頭函數 箭頭函數表達式的語法比函數表達式更簡潔。所以在開發中更推薦使用箭頭函數。特別是在`vue`項目中,使用箭頭函數不需要在更`this`重新賦一個變量。 ``` // old 使用functions var arr = [5, 3, 2, 9, 1] var arrFunc = arr.map(function (x) { return x * x }) console.log(arrFunc) // 使用箭頭函數 var arr = [5, 3, 2, 9, 1] var arrFunc = arr.map((x) => x * x) ``` 要注意的是,箭頭函數不綁定`arguments`,取而代之用`rest`參數…解決。 ``` // 不能使用 arguments let fun1 = (b) => { console.log(arguments) } fun1(2, 92, 32, 32) // Uncaught ReferenceError: arguments is not defined // 使用rest 參數 let fun2 = (...c) => { console.log(c) } fun2(3, 82, 32, 11323) // [3, 82, 32, 11323] ``` ## Dom 的創建 創建多個 dom 元素時,先將元素`append`到`DocumentFragment`中,最后統一將`DocumentFragment`添加到頁面。 常規方法; ``` for (var i = 0; i < 1000; i++) { var el = document.createElement('p') el.innerHTML = i document.body.appendChild(el) } ``` 使用`DocumentFragment`優化多次`append` ``` var frag = document.createDocumentFragment() for (var i = 0; i < 1000; i++) { var el = document.createElement('p') el.innerHTML = i frag.appendChild(el) } document.body.appendChild(frag) ``` 更優的方法:使用一次`innerHTML`賦值代替構建 dom 元素 ``` ar html = [] for (var i = 0; i < 1000; i++) { html.push('<p>' + i + '</p>') } document.body.innerHTML = html.join('') ``` ## 防抖與節流 在前端開發的過程中,我們經常會需要綁定一些持續觸發的事件,如`resize`、`scroll`、`mousemove`等等,但有些時候我們并不希望在事件持續觸發的過程中那么頻繁地去執行函數。這時候就用到防抖與節流。 案例 1:遠程搜索時需要通過接口動態的獲取數據,若是每次用戶輸入都接口請求,是浪費帶寬和性能的。 ``` <Select :remote-method="remoteMethod"> <Option v-for="item in temoteList" :value="item.value" :key="item.id">{{item.label}}</Option> </Select> <script> function debounce(fn, wait) { let timeout = null return function () { if (timeout !== null) clearTimeout(timeout) timeout = setTimeout(fn, wait) } } export default { methods:{ remoteMethod:debounce(function (query) { // to do ... }, 200), } } <script> ``` 案例 2:持續觸發`scroll`事件時,并不立即執行`handle`函數,當 1000 毫秒內沒有觸發`scroll`事件時,才會延時觸發一次`handle`函數。 ``` function debounce(fn, wait) { let timeout = null return function () { if (timeout !== null) clearTimeout(timeout) timeout = setTimeout(fn, wait) } } function handle() { console.log(Math.random()) } window.addEventListener('scroll', debounce(handle, 1000)) ``` ***** ## 異步加載 js 默認情況下,瀏覽器是同步加載 js 腳本,解析 html 過程中,遇到`<script>`標簽就會停下來,等腳本下載、解析、執行完后,再繼續向下解析渲染。 如果 js 文件體積比較大,下載時間就會很長,容易造成瀏覽器堵塞,瀏覽器頁面會呈現出“白屏”效果,用戶會感覺瀏覽器“卡死了”,沒有響應。此時,我們可以讓 js 腳本異步加載、執行。 ``` <script src="path/to/home.js" defer></script> <script src="path/to/home.js" async></script> ``` 上面代碼中,`<script>`標簽分別有`defer`和`async`屬性,瀏覽器識別到這 2 個屬性時 js 就會異步加載。也就是說,瀏覽器不會等待這個腳本下載、執行完畢后再向后執行,而是直接繼續向后執行 defer 與 async 區別: * defer:DOM 結構完全生成,以及其他腳本執行完成,才會執行(渲染完再執行)。有多個`defer`腳本時,會按照頁面出現的順序依次加載、執行。 * async:一旦下載完成,渲染引擎就會中斷渲染,執行這個腳本以后,再繼續渲染(下載完就執行)。有多個`async`腳本時,不能保證按照頁面出現順序加載、執行 ## import() ~~~js const btn = document.getElementById("btn"); btn.onclick = () => { import("./hello.js").then(module => { module.hello(); }); }; ~~~ ## 可選鏈操作符(?.) ~~~js const data = { name: "張三", age: 18, sex: "男" }; console.log(data?.friend?.name); ~~~ ## 空值合并運算符(??) ~~~js let a = 0; let b = a || "aaa"; let c = a ?? "aaa"; console.log("b的值是 " + b);//b的值是 aaa console.log("c的值是 " + c);//c的值是 0 ~~~ ## 箭頭函數 箭頭函數看起來會更加的簡潔,因為它允許你使用更短的語法來書寫函數: ~~~js const myFunction = function() { //... } ~~~ 到 ~~~js const myFunction = () => { //... } ~~~ 如果函數體中只包含一條語句,你甚至可以省略大括號并直接書寫這條語句: ~~~js const myFunction = () => doSomething() ~~~ 參數在括號中傳遞: ~~~js const myFunction = (param1, param2) => doSomething(param1, param2) ~~~ 如果該函數**只有一個**參數,那么可以省略掉括號: ~~~js const myFunction = param => doSomething(param) ~~~ 由于這種簡短的語法,使得我們可以更便捷的使用**比較簡短的函數** ## Using `let` `let` 是ES2015中引入的新功能,它本質上是具有塊級作用域的 `var` 。它可以被當前作用域(函數以及塊級作用域)以及子級作用域訪問到。 現代 JavaScript 開發者在 `let` 和 `var` 的選擇中可能會更傾向于前者。 ## Using `const` 使用變量 `var` 或 `let` 聲明的變量可以被重新賦值。 使用 `const` 聲明的變量一經初始化,它的值就永遠不能再改變,即不可重新被賦值。 ~~~js const a = 'test' ~~~ 我們不能再為 `a` 進行賦值操作。然而,`a` 如果它是一個具有屬性或者方法的對象,那么我們可以改變它的屬性或者方法。 `const` 并不意味著具有不可變性,只是保證用 `const` 聲明的變量的引用地址不被變更。 ## 隱式返回 箭頭函數支持隱式返回:可以正常的 `return` 一個返回值但是可以不使用 `return` 關鍵字。 隱式返回只在函數體內只包含一條語句的情況下生效: ~~~js const myFunction = () => 'test' myFunction() //'test' ~~~ 需要注意的一種情況,當返回一個對象時,記得將大括號括在括號中以避免產生歧義,誤將其(大括號)解析為函數體的大括號。 ~~~js const myFunction = () => ({ value: 'test' }) myFunction() //{value: 'test'} ~~~ ## class 定義 如下是一個 class 的例子: ~~~js class Person { constructor(name) { this.name = name } hello() { return 'Hello, I am ' + this.name + '.' } } ~~~ 在這個類的對象實例上調用: ~~~js const flavio = new Person('Flavio') flavio.hello() ~~~ ## Class 繼承 一個子類可以 extend 另一個類,通過子類實例化出來的對象可以繼承這兩個類的所有方法。 如果子類中的方法與父類中的方法名重復,那么子類中的同名方法優先級更高: ~~~js class Programmer extends Person { hello() { return super.hello() + ' I am a programmer.' } } const flavio = new Programmer('Flavio') flavio.hello() ~~~ ## 靜態方法 在類中,通常會把方法直接掛載到實例對象上,直接在實例對象上調用。 而靜態方法則是直接使用類名來調用,而不是通過對象實例調用: ~~~js class Person { static genericHello() { return 'Hello' } } Person.genericHello() //Hello ~~~ ## For-of循環 2009年的ES5引入了`forEach()`循環,雖然很好用,但是它跟`for`循環不一樣,沒法break。 ES2015引入了`**for-of**` **循環**,就是在`forEach`的基礎上加上了break的功能: ~~~js //iterate over the value for (const v of ['a', 'b', 'c']) { console.log(v); } //get the index as well, using `entries()` for (const [i, v] of ['a', 'b', 'c'].entries()) { console.log(index) //index console.log(value) //value } ~~~ ## 創建一個promise Promise API暴露了一個Promise構造函數,可以通過`new Promise()`來初始化: ~~~js let done = true const isItDoneYet = new Promise((resolve, reject) => { if (done) { const workDone = 'Here is the thing I built' resolve(workDone) } else { const why = 'Still working on something else' reject(why) } }) ~~~ ## 使用一個promise 上面講了怎么創建一個promise,下面就講怎么使用(consume)這個promise。 ~~~js const isItDoneYet = new Promise() //... const checkIfItsDone = () => { isItDoneYet .then(ok => { console.log(ok) }) .catch(err => { console.error(err) }) } ~~~ ## 鏈式promise的例子 Fetch API ~~~js const status = response => { if (response.status >= 200 && response.status < 300) { return Promise.resolve(response) } return Promise.reject(new Error(response.statusText)) } const json = response => response.json() fetch('/todos.json') .then(status) .then(json) .then(data => { console.log('Request succeeded with JSON response', data) }) .catch(error => { console.log('Request failed', error) }) ~~~ 檢查日期是否為工作日 ``` const isWeekday = (date) => date.getDay() % 6 !== 0; ``` 反轉字符串 ``` const reverse = (str) => str.split('').reverse().join(''); console.log(reverse('hello world'));; ``` 檢查當前 Tab 頁是否在前臺 ``` ~~~ const isBrowserTabInView = () => document.hidden; console.log(isBrowserTabInView()); ~~~ ``` 保留小數點(非四舍五入) ``` const toFixed = (n, fixed) => ~~(Math.pow(10, fixed) * n) / Math.pow(10, fixed); // Examples a=toFixed(25.198726354, 1); ``` 滾動到頁面頂部 ``` const goToTop = () => window.scrollTo(0, 0); ``` 獲取Cookie ~~~js const cookie = name => `; ${document.cookie}`.split(`; ${name}=`).pop().split(';').shift(); cookie('_ga'); ~~~ ~~~text /** * 將字節轉換為合理的容量單位 * @param {number} bytes Bytes in Number */ const humanFileSize = (bytes) => { let BYTES = bytes; const thresh = 1024; if (Math.abs(BYTES) < thresh) { return `${BYTES} B`; } const units = ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; let u = -1; const r = 10 ** 1; do { BYTES /= thresh; u += 1; } while (Math.round(Math.abs(BYTES) * r) / r >= thresh && u < units.length - 1); return `${BYTES.toFixed(1)} ${units[u]}`; }; /** * storage具有過期時間 * Caching values with expiry date to the LocalHost. * @param {string} key Local Storage Key * @param {any} value Local Storage Value * @param {number} ttl Time to live (Expiry Date in MS) */ const setLocalItem = (key, value, ttl = duration.month) => { const now = new Date(); // `item` is an object which contains the original value // as well as the time when it's supposed to expire const item = { value, expiry: now.getTime() + ttl, }; localStorage.setItem(key, JSON.stringify(item)); }; /** * storage具有過期時間 * Getting values with expiry date from LocalHost that stored with `setLocalItem`. * @param {string} key Local Storage Key */ const getLocalItem = (key) => { const itemStr = localStorage.getItem(key); // if the item doesn't exist, return null if (!itemStr) { return null; } const item = JSON.parse(itemStr); const now = new Date(); // compare the expiry time of the item with the current time if (now.getTime() > item.expiry) { // If the item is expired, delete the item from storage // and return null localStorage.removeItem(key); return null; } return item.value; }; ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看