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

Array
1、數(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ì)象目前僅針對(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ù)組并集
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]
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ù)組
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 ]
// 對(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ǔ)集
普通數(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 ]
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?}]
5、數(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]
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ù)組排序
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] 降序
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 } ]
默認(rèn)是升序排序,默認(rèn)返回一個(gè)函數(shù),有兩個(gè)參數(shù):
(a, b) => a - b 是升序;
(a, b) => b - a 是降序。
7、最大值
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
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ù)組求和
[1, 2, 3, 4].reduce(function (prev, cur) {return prev + cur;}, 0) //10
const sum = [{age:1},{age:2}].reduce(function (prev, cur) {return prev + cur.age;}, 0) //3console.log(sum)
9、數(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]
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ù)組是否包含值
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
const flag = [{age:1},{age:2}].some(v=>JSON.stringify(v)===JSON.stringify({age:2}))console.log(flag)
11、數(shù)組每一項(xiàng)都滿(mǎn)足
[1, 2, 3].every(item => { return item > 2 })
const arr = [{ age: 3 }, { age: 4 }, { age: 5 }]arr.every(item?=>?{?return?item.age?>?2?})?//?true
12、數(shù)組有一項(xiàng)滿(mǎn)足
[1,?2,?3].some(item?=>?{?return?item?>?2?})
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é)數(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' ]
字母排序是根據(jù)Unicode排序的,所以1.10b在1.10C的后面
14、對(duì)象轉(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ì)象
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ì)象
無(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); // 這是改變值1let 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
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;
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ì)象深度拷貝
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 parentlet child, protoif (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 ] }
克隆函數(shù)可以用正則取出函數(shù)體和參數(shù),再定義一個(gè)函數(shù)將取出來(lái)的值賦值進(jìn)去
詳細(xì)請(qǐng)戳對(duì)象深度拷貝
24、對(duì)象是否相等
而且不支持無(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 cachedrightChain = [];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
25、對(duì)象轉(zhuǎn)化為字符串
'the Math object:' + Math.ceil(3.4) // "the Math object:4"'the JSON object:' + {name:'曹操'} // "the JSON object:[object Object]"
2 * { valueOf: ()=>'4' } // 8'J' + { toString: ()=>'ava' } // "Java"
對(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))()
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.reject('這是第二個(gè) reject 值').then((data)=>{console.log(data)}).catch(data=>{console.log(data) //這是第二個(gè) reject 值})
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
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ù)序列化
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ù)反序列化
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ù)是否相等
實(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)算符
~~7.5 // 7Math.ceil(7.5) // 8Math.floor(7.5) // 7~~-7.5 // -7Math.floor(-7.5) // -8Math.ceil(-7.5) // -7
37、取整和奇偶性判斷
3.3 | 0 // 3-3.9 | 0 // -3parseInt(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
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
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ě)
switch(a) {case '張三':return 'age是12'case '李四':return 'age是120'}// 使用對(duì)象替換后const obj ={'張三': 'age12','李四': 'age120',}console.log(obj['張三'])

評(píng)論
圖片
表情
