<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          41個(gè)最新的JavaScript開(kāi)發(fā)技巧,你必須要知道

          共 19226字,需瀏覽 39分鐘

           ·

          2020-08-03 13:41

          前言
          JS是前端的核心,但有些使用技巧你還不一定知道;本文梳理了JS的41個(gè)技巧,幫助大家提高JS的使用技巧。

          Array

          1、數(shù)組交集

          普通數(shù)組
          const arr1 = [1, 2, 3, 4, 5 , 8 ,9],arr2 = [5, 6, 7, 8, 9];
          const intersection = arr1.filter(function (val) { return arr2.indexOf(val) > -1 })console.log(intersection) //[5, 8, 9]
          數(shù)組對(duì)象
          數(shù)組對(duì)象目前僅針對(duì)value值為簡(jiǎn)單的Number,String,Boolan數(shù)據(jù)類(lèi)型
          const arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }, { name: 'name5', id: 5 }];const arr2 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];const result = arr2.filter(function (v) {return arr1.some(n => JSON.stringify(n) === JSON.stringify(v))})console.log(result); // [{ name: 'name1', id: 1 },{ name: 'name2', id: 2 },{ name: 'name3', id: 3 },{ name: 'name5', id: 5 }]

          2、數(shù)組并集

          普通數(shù)組
          const arr1 = [1, 2, 3, 4, 5, 8, 9]const arr2 = [5, 6, 7, 8, 9];const result = arr1.concat(arr2.filter(v => !arr1.includes(v)))console.log(result) //[1, 2, 3, 4,5, 8, 9]
          數(shù)組對(duì)象
          const arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }];const arr2 = [{ name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];let arr3 = arr1.concat(arr2);let result = [];let obj = [];result = arr3.reduce(function (prev, cur, index, arr) { obj[cur.id] ? '' : obj[cur.id] = true && prev.push(cur); return prev;}, []);console.log(result); //[{ name: 'name1', id: 1 },{ name: 'name2', id: 2 },{ name: 'name3', id: 3 },{ name: 'name4', id: 4 },{ name: 'name5', id: 5 }]

          3、數(shù)組差集

          數(shù)組arr1相對(duì)于arr2所沒(méi)有的
          普通數(shù)組
          const arr1 = [1, 2, 3, 4, 5, 8, 9]const arr2 = [5, 6, 7, 8, 9];const diff = arr1.filter(item => !new Set(arr2).has(item))console.log(diff) //[ 1, 2, 3, 4 ]
          數(shù)組對(duì)象
          // 對(duì)象數(shù)組let arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }];let arr2 = [{ name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];let result = arr1.filter(function (v) { return arr2.every(n => JSON.stringify(n) !== JSON.stringify(v))})console.log(result);?//?[?{?name:?'name2',?id:?2?},?{?name:?'name3',?id:?3?}?]

          4、數(shù)組補(bǔ)集

          兩個(gè)數(shù)組各自沒(méi)有的集合
          普通數(shù)組
          const arr1 = [1, 2, 3, 4, 5, 8, 9]const arr2 = [5, 6, 7, 8, 9];const difference = Array.from(new Set(arr1.concat(arr2).filter(v => !new Set(arr1).has(v) || !new Set(arr2).has(v)))) console.log(difference) //[ 1, 2, 3, 4, 6, 7 ]
          數(shù)組對(duì)象
          let arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }];let arr2 = [{ name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];let arr3 = arr1.concat(arr2);let result = arr3.filter(function (v) { return arr1.every(n => JSON.stringify(n) !== JSON.stringify(v)) || arr2.every(n => JSON.stringify(n) !== JSON.stringify(v))})console.log(result);?//?[{?name:?'name2',?id:?2?},{?name:?'name3',?id:?3?},{?name:?'name4',?id:?4?},{?name:?'name5',?id:?5?}]

          總結(jié)一下,差集就是數(shù)組arr1相對(duì)于arr2所沒(méi)有的集合,補(bǔ)集是兩個(gè)數(shù)組各自沒(méi)有的集合

          5、數(shù)組去重

          普通數(shù)組
          console.log(Array.from(new Set([1, 2, 3, 3, 4, 4]))) //[1,2,3,4]console.log([...new Set([1, 2, 3, 3, 4, 4])]) //[1,2,3,4]
          數(shù)組對(duì)象
          const arr = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }, { name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];const obj = [];const result = arr.reduce(function (prev, cur, index, arr) { obj[cur.id] ? '' : obj[cur.id] = true && prev.push(cur); return prev;}, []);console.log(result) //[{ name: 'name1', id: 1 },{ name: 'name2', id: 2 },{ name: 'name3', id: 3 },{ name: 'name4', id: 4 },{ name: 'name5', id: 5 }]

          6、數(shù)組排序

          普通數(shù)組
          console.log([1, 2, 3, 4].sort((a, b) => a - b)); // [1, 2,3,4] 升序console.log([1, 2, 3, 4].sort((a, b) => b - a)); // [4,3,2,1] 降序
          數(shù)組對(duì)象
          const arr1 = [{ name: "Rom", age: 12 }, { name: "Bob", age: 22 }].sort((a, b) => { return a.age - b.age })//升序const arr2 = [{ name: "Rom", age: 12 }, { name: "Bob", age: 22 }].sort((a, b) => { return -a.age + b.age })//降序console.log(arr2) // [{ name: 'Bob', age:22 }, { name: 'Rom', age: 12 }]console.log(arr1) // [ { name: 'Rom', age: 12 }, { name: 'Bob', age: 22 } ]
          兩個(gè)種類(lèi)型數(shù)組都可以使用sort排序,sort是瀏覽器內(nèi)置方法;
          默認(rèn)是升序排序,默認(rèn)返回一個(gè)函數(shù),有兩個(gè)參數(shù):
          (a, b) => a - b 是升序;
          (a, b) => b - a 是降序。

          7、最大值

          普通數(shù)組
          Math.max(...[1, 2, 3, 4]) //4Math.max.apply(this, [1, 2, 3, 4]) //4[1, 2, 3, 4].reduce((prev, cur, curIndex, arr) => { return Math.max(prev, cur);}, 0) //4
          取數(shù)組對(duì)象中id的最大值
          const arr = [{ id: 1, name: 'jack' },{ id: 2, name: 'may' },{ id: 3, name: 'shawn' },{ id: 4, name: 'tony' }]const arr1 = Math.max.apply(Math, arr.map(item => { return item.id }))const arr2 = arr.sort((a, b) => { return b.id - a.id })[0].idconsole.log(arr1) // 4console.log(arr2) // 4

          8、數(shù)組求和

          普通數(shù)組
          [1, 2, 3, 4].reduce(function (prev, cur) { return prev + cur;}, 0) //10
          數(shù)組對(duì)象
          const sum = [{age:1},{age:2}].reduce(function (prev, cur) { return prev + cur.age;}, 0) //3console.log(sum)

          9、數(shù)組合并

          普通數(shù)組
          const arr1 =[1, 2, 3, 4].concat([5, 6]) //[1,2,3,4,5,6]const arr2 =[...[1, 2, 3, 4],...[4, 5]] //[1,2,3,4,5,6]const arrA = [1, 2], arrB = [3, 4]const arr3 =Array.prototype.push.apply(arrA, arrB)//arrA值為[1,2,3,4]
          數(shù)組對(duì)象
          const arr4 = [{ age: 1 }].concat([{ age: 2 }])const arr5 = [...[{ age: 1 }],...[{ age: 2 }]]console.log(arr4) //[ { age: 1 }, { age: 2 } ]console.log(arr5) // [ { age: 1 }, { age: 2 } ]

          10、數(shù)組是否包含值

          普通數(shù)組
          console.log([1, 2, 3].includes(4)) //falseconsole.log([1, 2, 3].indexOf(4)) //-1 如果存在換回索引console.log([1, 2, 3].find((item) => item === 3)) //3 如果數(shù)組中無(wú)值返回undefinedconsole.log([1,?2,?3].findIndex((item)?=>?item?===?3))?//2?如果數(shù)組中無(wú)值返回-1
          數(shù)組對(duì)象
          const flag = [{age:1},{age:2}].some(v=>JSON.stringify(v)===JSON.stringify({age:2}))console.log(flag)

          11、數(shù)組每一項(xiàng)都滿(mǎn)足

          普通數(shù)組
          [1, 2, 3].every(item => { return item > 2 })
          數(shù)組對(duì)象
          const arr = [{ age: 3 }, { age: 4 }, { age: 5 }]arr.every(item?=>?{?return?item.age?>?2?})?//?true

          12、數(shù)組有一項(xiàng)滿(mǎn)足

          普通數(shù)組
          [1,?2,?3].some(item?=>?{?return?item?>?2?})
          數(shù)組對(duì)象
          const arr = [{ age: 3 }, { age: 4 }, { age: 5 }]arr.some(item => { return item.age < 4 }) // true

          13、版本號(hào)排序

          方法一
          function sortNumber(a, b) {return a - b}const b = [1,2,3,7,5,6]const a = ["1.5", "1.5", "1.40", "1.25", "1.1000", "1.1"];
          console.log(a.sort(sortNumber)); // [ 1, 2, 3, 5, 6, 7 ]console.log(b.sort(sortNumber)); //[ '1.1000', '1.1', '1.25', '1.40','1.5', '1.5' ]
          可見(jiàn)sort排序?qū)φ麛?shù)可以,類(lèi)似版本號(hào)這個(gè)格式就不適用了,因?yàn)閟ort函數(shù)在比較字符串的時(shí)候,是比較字符串的Unicode進(jìn)行排序的。
          方法二
          //假定字符串的每節(jié)數(shù)都在5位以下//去除數(shù)組空值||空格if (!Array.prototype.trim) {  Array.prototype.trim = function () {    let arr = []; this.forEach(function (e) {      if (e.match(/\S+/)) arr.push(e);    })    return arr;  }}
          //提取數(shù)字部分function toNum(a) { let d = a.toString(); let c = d.split(/\D/).trim(); let num_place = ["", "0", "00", "000", "0000"], r = num_place.reverse(); for (let i = 0; i < c.length; i++) { let len = c[i].length; c[i] = r[len] + c[i]; } let res = c.join(''); return res;}
          //提取字符function toChar(a) { let d = a.toString(); let c = d.split(/\.|\d/).join(''); return c;}
          function sortVersions(a, b) {
          let _a1 = toNum(a), _b1 = toNum(b); if (_a1 !== _b1) return _a1 - _b1; else { _a2 = toChar(a).charCodeAt(0).toString(16); _b2 = toChar(b).charCodeAt(0).toString(16); return _a2 - _b2; }}
          let arr1 = ["10", "5", "40", "25", "1000", "1"];let arr2 = ["1.10", "1.5", "1.40", "1.25", "1.1000", "1.1"];let arr3 = ["1.10c", "1.10b", "1.10C", "1.25", "1.1000", "1.10A"];console.log(arr1.sort(sortVersions)) //[ '1', '5', '10', '25', '40', '1000' ]console.log(arr2.sort(sortVersions)) //[ '1.1', '1.5', '1.10', '1.25', '1.40', '1.1000' ]console.log(arr3.sort(sortVersions)) // [ '1.10A', '1.10C', '1.10b', '1.10c', '1.25', '1.1000' ]
          可以看出這個(gè)函數(shù)均兼容整數(shù),非整數(shù),字母;
          字母排序是根據(jù)Unicode排序的,所以1.10b在1.10C的后面

          14、對(duì)象轉(zhuǎn)數(shù)組

          將數(shù)組的key和value轉(zhuǎn)化成數(shù)組
          Object.keys({ name: '張三', age: 14 }) //['name','age']Object.values({ name: '張三', age: 14 }) //['張三',14]Object.entries({ name: '張三', age: 14 }) //[[name,'張三'],[age,14]]Object.fromEntries([name, '張三'], [age, 14]) //ES10的api,Chrome不支持 , firebox輸出{name:'張三',age:14}

          15、數(shù)組轉(zhuǎn)對(duì)象

          將數(shù)組的值轉(zhuǎn)化為對(duì)象的value
          const arrName = ['張三', '李四', '王五']const arrAge=['20','30','40']const arrDec = ['描述1', '描述2', '描述3']const obj = arrName.map((item,index)=>{return { name: item, age: arrAge[index],dec:arrDec[index]}})
          console.log(obj) // [{ name: '張三', age: '20', dec: '描述1' },{ name: '李四', age: '30', dec: '描述2' },{ name: '王五', age: '40', dec: '描述3' }]

          16、數(shù)組解構(gòu)

          const arr=[1,2]; //后面一定要加分號(hào),因?yàn)椴患咏忉屍鲿?huì)認(rèn)為在讀數(shù)組[arr[1],?arr[0]]?=?[arr[0],?arr[1]];?//?[2,1]

          Object

          17、對(duì)象變量屬性

          const flag = true;const obj = { a: 0, [flag ? "c" : "d"]: 2};// obj => { a: 0, c: 2 }

          18、對(duì)象多余屬性刪除

          const { name, age, ...obj } = { name: '張三', age: 13, dec: '描述1', info: '信息' }console.log(name) // 張三console.log(age) // 13console.log(obj) // {dec: '描述1', info: '信息' }

          19、對(duì)象嵌套屬性解構(gòu)

          const { info:{ dec} } = { name: '張三', age: 13, info:{dec: '描述1', info: '信息' }}console.log(dec) // 描述1

          20、解構(gòu)對(duì)象屬性別名

          const { name:newName } = { name: '張三', age: 13 }console.log(newName) // 張三

          21、解構(gòu)對(duì)象屬性默認(rèn)值

          const { dec='這是默認(rèn)dec值' } = { name: '張三', age: 13 }console.log(dec) //這是默認(rèn)dec值

          22、攔截對(duì)象

          利用Object.defineProperty攔截對(duì)象
          無(wú)法攔截?cái)?shù)組的值
          let obj = { name: '', age: '', sex: '' }, defaultName = ["這是姓名默認(rèn)值1", "這是年齡默認(rèn)值1", "這是性別默認(rèn)值1"];Object.keys(obj).forEach(key => {Object.defineProperty(obj, key, { // 攔截整個(gè)object 對(duì)象,并通過(guò)get獲取值,set設(shè)置值,vue 2.x的核心就是這個(gè)來(lái)監(jiān)聽(tīng)get() {return defaultName; },set(value) { defaultName = value; } });});
          console.log(obj.name); // [ '這是姓名默認(rèn)值1', '這是年齡默認(rèn)值1', '這是性別默認(rèn)值1' ]console.log(obj.age); // [ '這是姓名默認(rèn)值1', '這是年齡默認(rèn)值1', '這是性別默認(rèn)值1' ]console.log(obj.sex); // [ '這是姓名默認(rèn)值1', '這是年齡默認(rèn)值1', '這是性別默認(rèn)值1' ]obj.name = "這是改變值1";console.log(obj.name); // 這是改變值1console.log(obj.age); // 這是改變值1console.log(obj.sex); // 這是改變值1
          let objOne = {}, defaultNameOne = "這是默認(rèn)值2";Object.defineProperty(obj, 'name', {get() {return defaultNameOne; },set(value) { defaultNameOne = value; }});console.log(objOne.name); // undefinedobjOne.name = "這是改變值2";console.log(objOne.name); // 這是改變值2
          利用proxy攔截對(duì)象
          let obj = { name: '', age: '', sex: '' }let handler = {get(target, key, receiver) { console.log("get", key); return Reflect.get(target, key, receiver); },set(target, key, value, receiver) { console.log("set", key, value); // set name 李四 // set age 24return Reflect.set(target, key, value, receiver); }};let proxy = new Proxy(obj, handler);proxy.name = "李四";proxy.age = 24;
          defineProterty和proxy的對(duì)比:
          1.defineProterty是es5的標(biāo)準(zhǔn),proxy是es6的標(biāo)準(zhǔn);
          2.proxy可以監(jiān)聽(tīng)到數(shù)組索引賦值,改變數(shù)組長(zhǎng)度的變化;
          3.proxy是監(jiān)聽(tīng)對(duì)象,不用深層遍歷,defineProterty是監(jiān)聽(tīng)屬性;
          4.利用defineProterty實(shí)現(xiàn)雙向數(shù)據(jù)綁定(vue2.x采用的核心)

          23、對(duì)象深度拷貝

          JSON.stringify深度克隆對(duì)象;
          1.無(wú)法對(duì)函數(shù) 、RegExp等特殊對(duì)象的克隆;
          2.會(huì)拋棄對(duì)象的constructor,所有的構(gòu)造函數(shù)會(huì)指向Object;
          3.對(duì)象有循環(huán)引用,會(huì)報(bào)錯(cuò)
          const objDeepClone = obj => {return clone(obj)}
          const isType = (obj, type) => {if (typeof obj !== 'object') return false;// 判斷數(shù)據(jù)類(lèi)型的經(jīng)典方法:const typeString = Object.prototype.toString.call(obj); let flag;switch (type) {case 'Array': flag = typeString === '[object Array]';break;case 'Date': flag = typeString === '[object Date]';break;case 'RegExp': flag = typeString === '[object RegExp]';break;default: flag = false; }return flag;};
          /*** deep clone* @param {[type]} parent object 需要進(jìn)行克隆的對(duì)象* @return {[type]} 深克隆后的對(duì)象*/const clone = parent => {// 維護(hù)兩個(gè)儲(chǔ)存循環(huán)引用的數(shù)組const parents = []const children = []
          const _clone = parent => {if (parent === null) return nullif (typeof parent !== 'object') return parent
          let child, proto
          if (isType(parent, 'Array')) {// 對(duì)數(shù)組做特殊處理 child = [] } else if (isType(parent, 'RegExp')) {// 對(duì)正則對(duì)象做特殊處理 child = new RegExp(parent.source, getRegExp(parent))if (parent.lastIndex) child.lastIndex = parent.lastIndex } else if (isType(parent, 'Date')) {// 對(duì)Date對(duì)象做特殊處理 child = new Date(parent.getTime()) } else {// 處理對(duì)象原型 proto = Object.getPrototypeOf(parent)// 利用Object.create切斷原型鏈 child = Object.create(proto) }
          // 處理循環(huán)引用const index = parents.indexOf(parent)
          if (index !== -1) {// 如果父數(shù)組存在本對(duì)象,說(shuō)明之前已經(jīng)被引用過(guò),直接返回此對(duì)象return children[index] } parents.push(parent) children.push(child)
          for (const i in parent) {// 遞歸 child[i] = _clone(parent[i]) }
          return child }return _clone(parent)}
          console.log(objDeepClone({ name: '張三', age: 23, obj: { name: '李四', age: 46}, arr:[1,2,3]})) // { name: '張三', age: 23, obj: { name: '李四', age: 46 }, arr:[ 1, 2, 3 ] }
          對(duì)象深度克隆實(shí)際上就是要兼容Array,RegExp,Date,F(xiàn)unction類(lèi)型;
          克隆函數(shù)可以用正則取出函數(shù)體和參數(shù),再定義一個(gè)函數(shù)將取出來(lái)的值賦值進(jìn)去
          詳細(xì)請(qǐng)戳對(duì)象深度拷貝

          24、對(duì)象是否相等

          如果用JSON.stringify轉(zhuǎn)化屬性順序不同,也不相等;
          而且不支持無(wú)法對(duì)函數(shù) 、RegExp等特殊對(duì)象的克隆
          function deepCompare(x, y) {var i, l, leftChain, rightChain;
          function compare2Objects(x, y) {var p;
          // remember that NaN === NaN returns false// and isNaN(undefined) returns trueif (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {return true; }
          // Compare primitives and functions. // Check if both arguments link to the same object.// Especially useful on the step where we compare prototypesif (x === y) {return true; }
          // Works in case when functions are created in constructor.// Comparing dates is a common scenario. Another built-ins?// We can even handle functions passed across iframesif ((typeof x === 'function' && typeof y === 'function') || (x instanceof Date && y instanceof Date) || (x instanceof RegExp && y instanceof RegExp) || (x instanceof String && y instanceof String) || (x instanceof Number && y instanceof Number)) {return x.toString() === y.toString(); }
          // At last checking prototypes as good as we canif (!(x instanceof Object && y instanceof Object)) {return false; }
          if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {return false; }
          if (x.constructor !== y.constructor) {return false; }
          if (x.prototype !== y.prototype) {return false; }
          // Check for infinitive linking loopsif (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {return false; }
          // Quick checking of one object being a subset of another.// todo: cache the structure of arguments[0] for performancefor (p in y) {if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {return false; } else if (typeof y[p] !== typeof x[p]) {return false; } }
          for (p in x) {if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {return false; } else if (typeof y[p] !== typeof x[p]) {return false; }
          switch (typeof (x[p])) {case 'object':case 'function':
          leftChain.push(x); rightChain.push(y);
          if (!compare2Objects(x[p], y[p])) {return false; }
          leftChain.pop(); rightChain.pop();break;
          default:if (x[p] !== y[p]) {return false; }break; } }
          return true; }
          if (arguments.length < 1) {return true; }
          for (i = 1, l = arguments.length; i < l; i++) {
          leftChain = []; //Todo: this can be cached rightChain = [];
          if (!compare2Objects(arguments[0], arguments[i])) {return false; } }
          return true;}
          const obj1 = { name: '張三', age: 23, obj: { name: '李四', age: 46 }, arr: [1, 2, 3],date:new Date(23),reg: new RegExp('abc'),fun: ()=>{} }const obj2 = { name: '張三', age: 23, obj: { name: '李四', age: 46 }, arr: [1, 2, 3],date: new Date(23),reg: new RegExp('abc'),fun: ()=>{}?}console.log(deepCompare(obj1,obj2))?//?true
          判斷對(duì)象是否相等,實(shí)際上就是要處理Array,Date,RegExp,Object,F(xiàn)unction的特殊類(lèi)型是否相等

          25、對(duì)象轉(zhuǎn)化為字符串

          通過(guò)字符串+Object 的方式來(lái)轉(zhuǎn)化對(duì)象為字符串(實(shí)際上是調(diào)用 .toString() 方法)
          'the Math object:' + Math.ceil(3.4) // "the Math object:4"'the JSON object:' + {name:'曹操'} // "the JSON object:[object Object]"
          覆蓋對(duì)象的toString和valueOf方法來(lái)自定義對(duì)象的類(lèi)型轉(zhuǎn)換
          2 * { valueOf: ()=>'4' } // 8'J' + { toString: ()=>'ava' } // "Java"
          當(dāng)+用在連接字符串時(shí),當(dāng)一個(gè)對(duì)象既有toString方法又有valueOf方法時(shí)候,JS通過(guò)盲目使用valueOf方法來(lái)解決這種含糊;
          對(duì)象通過(guò)valueOf方法強(qiáng)制轉(zhuǎn)換為數(shù)字,通過(guò)toString方法強(qiáng)制轉(zhuǎn)換為字符串
          '' + {toString:()=>'S',valueOf:()=>'J'} //J

          Function

          26、函數(shù)隱式返回值

          (()=>3)() //3(()=>(3))()
          函數(shù)省略大括號(hào),或者將大括號(hào)改成小括號(hào)可以確保代碼以單個(gè)語(yǔ)句的形式進(jìn)行求值

          27、函數(shù)自執(zhí)行

          const Func = function() {}(); // 常用
          (function() {})(); // 常用(function() {}()); // 常用[function() {}()];
          new function() {};new function() {}();void function() {}();typeof function() {}();delete function() {}();
          + function() {}();- function() {}();~ function() {}();! function() {}();

          28、函數(shù)異步執(zhí)行

          Promise
          Promise.reject('這是第二個(gè) reject 值').then((data)=>{console.log(data)}).catch(data=>{console.log(data) //這是第二個(gè) reject 值})
          Generator
          function* gen(x) {const y = yield x + 6;return y;}
          // yield 如果用在另外一個(gè)表達(dá)式中,要放在()里面// 像上面如果是在=右邊就不用加()function* genOne(x) {const y = `這是第一個(gè) yield 執(zhí)行:${yield x + 1}`;return y;}
          const g = gen(1);//執(zhí)行 Generator 會(huì)返回一個(gè)Object,而不是像普通函數(shù)返回return 后面的值g.next() // { value: 7, done: false }//調(diào)用指針的 next 方法,會(huì)從函數(shù)的頭部或上一次停下來(lái)的地方開(kāi)始執(zhí)行,直到遇到下一個(gè) yield 表達(dá)式或return語(yǔ)句暫停,也就是執(zhí)行yield 這一行// 執(zhí)行完成會(huì)返回一個(gè) Object,// value 就是執(zhí)行 yield 后面的值,done 表示函數(shù)是否執(zhí)行完畢g.next() // { value: undefined, done: true }// 因?yàn)樽詈笠恍?return y 被執(zhí)行完成,所以done 為 true
          Async/Await
          function getSomething() {return "something";}async function testAsync() {return Promise.resolve("hello async");}async function test() {const v1 = await getSomething();const v2 = await testAsync();console.log(v1, v2); //something 和 hello async}test();

          String

          29、字符串翻轉(zhuǎn)

          function reverseStr(str = "") {return str.split("").reduceRight((t, v) => t + v);}
          const str = "reduce123";console.log(reverseStr(str)); // "123recuder"

          30、url參數(shù)序列化

          將對(duì)象序列化成url參數(shù)傳遞
          function stringifyUrl(search = {}) {return Object.entries(search).reduce((t, v) => `${t}${v[0]}=${encodeURIComponent(v[1])}&`,Object.keys(search).length ? "?" : "" ).replace(/&$/, "");}
          console.log(stringifyUrl({ age: 27, name: "YZW" })); // "?age=27&name=YZW"

          31、url參數(shù)反序列化

          一般會(huì)通過(guò)location.search拿到路由傳遞的參數(shù),并進(jìn)行反序列化得到對(duì)象
          function parseUrlSearch() {const search = '?age=25&name=TYJ'return search.replace(/(^\?)|(&$)/g, "").split("&").reduce((t, v) => {const [key, val] = v.split("="); t[key] = decodeURIComponent(val);return t; }, {});}
          console.log(parseUrlSearch()); // { age: "25", name: "TYJ" }

          32、轉(zhuǎn)化為字符串

          const val = 1 + ""; // 通過(guò)+ ''空字符串轉(zhuǎn)化console.log(val); // "1"console.log(typeof val); // "string"
          const val1 = String(1);console.log(val1); // "1"console.log(typeof val1); // "string"

          Number

          33、數(shù)字千分位

          function thousandNum(num = 0) {const str = (+num).toString().split(".");const int = nums => nums.split("").reverse().reduceRight((t, v, i) => t + (i % 3 ? v : `${v},`), "").replace(/^,|,$/g, "");const dec = nums => nums.split("").reduce((t, v, i) => t + ((i + 1) % 3 ? v : `${v},`), "").replace(/^,|,$/g, "");return str.length > 1 ? `${int(str[0])}.${dec(str[1])}` : int(str[0]);}
          thousandNum(1234); // "1,234"thousandNum(1234.00); // "1,234"thousandNum(0.1234); // "0.123,4"console.log(thousandNum(1234.5678)); // "1,234.567,8"

          34、字符串轉(zhuǎn)數(shù)字

          方法一
          用*1來(lái)轉(zhuǎn)化為數(shù)字,實(shí)際上是調(diào)用.valueOf方法
          '32' * 1 // 32'ds' * 1 // NaNnull * 1 // 0undefined * 1 // NaN1 * { valueOf: ()=>'3' } // 3
          方法二
          + '123' // 123+ 'ds' // NaN+ '' // 0+ null // 0+ undefined // NaN+ { valueOf: ()=>'3' } // 3

          35、判斷小數(shù)是否相等

          肯定有人會(huì)說(shuō)這還不簡(jiǎn)單,直接用'==='比較;
          實(shí)際上0.1+0.2 !==0.3,因?yàn)橛?jì)算機(jī)不能精確表示0.1, 0.2這樣的浮點(diǎn)數(shù),所以相加就不是0.3了
          Number.EPSILON=(function(){ //解決兼容性問(wèn)題return Number.EPSILON?Number.EPSILON:Math.pow(2,-52);})();//上面是一個(gè)自調(diào)用函數(shù),當(dāng)JS文件剛加載到內(nèi)存中,就會(huì)去判斷并返回一個(gè)結(jié)果function numbersequal(a,b){ return Math.abs(a-b) }//接下來(lái)再判斷 const a=0.1+0.2, b=0.3;console.log(numbersequal(a,b)); //這里就為true了

          36、雙位運(yùn)算符

          雙位運(yùn)算符比Math.floor(),Math.ceil()速度快
          ~~7.5 // 7Math.ceil(7.5) // 8Math.floor(7.5) // 7

          ~~-7.5 // -7Math.floor(-7.5) // -8Math.ceil(-7.5) // -7
          所以負(fù)數(shù)時(shí),雙位運(yùn)算符和Math.ceil結(jié)果一致,正數(shù)時(shí)和Math.floor結(jié)果一致

          37、取整和奇偶性判斷

          取整
          3.3 | 0 // 3-3.9 | 0 // -3
          parseInt(3.3) // 3parseInt(-3.3) // -3
          // 四舍五入取整Math.round(3.3) // 3Math.round(-3.3) // -3
          // 向上取整Math.ceil(3.3) // 4Math.ceil(-3.3) // -3
          // 向下取整Math.floor(3.3) // 3Math.floor(-3.3) // -4
          判斷奇偶數(shù)
          const num=5;!!(num & 1) // true!!(num % 2) // true

          Boolean

          38、判斷數(shù)據(jù)類(lèi)型

          function dataTypeJudge(val, type) {const dataType = Object.prototype.toString.call(val).replace(/\[object (\w+)\]/, "$1").toLowerCase();return type ? dataType === type : dataType;}console.log(dataTypeJudge("young")); // "string"console.log(dataTypeJudge(20190214)); // "number"console.log(dataTypeJudge(true)); // "boolean"console.log(dataTypeJudge([], "array")); // trueconsole.log(dataTypeJudge({}, "array")); // false
          可判斷類(lèi)型:undefined、null、string、number、boolean、array、object、symbol、date、regexp、function、asyncfunction、arguments、set、map、weakset、weakmap

          39、使用Boolean過(guò)濾數(shù)組假值

          const compact = arr => arr.filter(Boolean)compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]) //[ 1, 2, 3, 'a', 's', 34 ]

          40、短路運(yùn)算

          ||(或)
          const flag = false || true //true// 某個(gè)值為假時(shí)可以給默認(rèn)值const arr = false || []
          &&(與)
          const flag1 = false && true //falseconst flag2 = true && true //true

          41、switch 簡(jiǎn)寫(xiě)

          可以用對(duì)象替代switch,提高代碼可讀性
          switch(a) {case '張三':return 'age是12'case '李四':return 'age是120'}
          // 使用對(duì)象替換后const obj ={'張三': 'age12','李四': 'age120',}console.log(obj['張三'])
          本文完~
          瀏覽 42
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  我想看操逼视频 | 最新操逼网站 | 亚洲aⅤ中文字幕 | 亚洲乱伦网站 | 国产小毛片 |