{for (var i = 1; i <= 3; i++) {console.log(i); // 1 2 3// setTimeout(function () {// console.log(i); // 4 4 4// }, 0);}}{var a = null;console.log(typeof a); // object}{var a = 100;function test() {console.log(a); // 100a = 10;console.log(a); // 10}test();console.log(a); // 10}{var uname = "jack";function change() {console.log(uname); // undefinedvar uname = "wcd";console.log(uname); // wcd}change();}{function createBase(baseNumber) {return function (N) {return baseNumber + N;};}let addSix = createBase(6);console.log(addSix(10)); // 16console.log(addSix(21)); // 27}{var name = "global";var obj = {name: "obj",sex: function () {this.name = "wcd";return function () {return this.name;};}};console.log(obj.sex().call(this)); // undefinedconsole.log(obj.sex().call(obj)); // wcd}{/*** 需求:假设需要对字符串进行字符长度限制* str为字符串,len为长度*/function setString(str, len) {var strlen = 0;var s = "";for (var i = 0; i < str.length; i++) {if (str.charCodeAt(i) > 128) {strlen += 2;} else {strlen++;}s += str.charAt(i);if (strlen >= len) {return s + "...";}}return s;}}{const isType = (obj, type) => {if (typeof obj !== 'object') return false;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;}const getRegExp = re => {var flags = '';if (re.global) flags += 'g';if (re.ignoreCase) flags += 'i';if (re.multiline) flags += 'm';return flags;}}
1~100的完全平方数
{// 1~100的完全平方数function isSqrt(n) {for (var i = 1; n > 0; i += 2) {n -= i;}return 0 == n;}for (var j = 1; j <= 100; j++) {if (isSqrt(j)) {console.log(j); // 1 4 9 16 25 36 49 64 81 100}}}
统计数组中相同项的个数
{// 统计数组中相同项的个数var cars = ["xiaoming", "xiaohong", "xiaohong", "xiaohong", "xiaolv", "xiaolan", "xiaohei"];var carsObj = cars.reduce(function (obj, name) {obj[name] = obj[name] ? ++obj[name] : 1;return obj;}, {});console.log(carsObj); // { xiaoming: 1, xiaohong: 3, xiaolv: 1, xiaolan: 1, xiaohei: 1 }}
判断数组或者一个字符串中出现次数最多的元素及其出现的次数
{// 判断数组或者一个字符串中出现次数最多的元素及其出现的次数function maxCountElement(arr) {var obj = {};for (var i = 0; i < arr.length; i++) {var key = arr[i];if (obj[key]) {obj[key]++;} else {obj[key] = 1;}}var maxCount = 0;var maxElement = arr[0];var eq = [];for (var key in obj) {if (maxCount < obj[key]) {maxCount = obj[key];maxElement = key;eq.length = 0;} else if (maxCount === obj[key]) {eq.push(key);}}if (eq.length > 0) {for (var j = 0; j < eq.length; j++) {maxElement += "," + eq[j];}}return `该数组中出现次数最多的元素:${maxElement},出现了:${maxCount}次`;}var arr = [1, 2, 2, 2, 3, 3, 3, 4, 5, 6];var res = maxCountElement(arr);console.log(res); // 该数组中出现次数最多的元素:2,3,出现了:3次}
判断回文字符串
{// 实现一个函数,判断输入是不是回文字符串(在我的理解,如果将一个字符串翻转过来,能和原字符串完全相等,那么就可以称之为“回文”)// onefunction Palindrome1(input) {if (typeof input !== "string") return false;return (input.split("").reverse().join("") === input);}// twofunction Palindrome2(line) {line += "";for (var i = 0, j = line.length - 1; i < j; i++, j--) {if (line.charAt(i) !== line.charAt(j)) {return false;}}return true;}}
trim
{String.prototype.trim = function () {return this.replace(/^\s+/, "").replace(/\s+$/, "");};}{// 正则实现trim()功能function myTrim(str) {let reg = /^\s+|\s+$/g;return str.replace(reg, "");}let str = " wcd ";console.log(myTrim(str)); // wcd}
检测平台(设备)类型
{// 检测平台(设备)类型let isWechat = /micromessenger/i.test(navigator.userAgent),isWeibo = /weibo/i.test(navigator.userAgent),isQQ = /qq\//i.test(navigator.userAgent),isIOS = /(iphone|ipod|ipad|ios)/i.test(navigator.userAgent),isAndroid = /android/i.test(navigator.userAgent);}
获取 URL 的中参数
{// 获取 URL 的中参数 (推荐 https://github.com/derek-watson/jsUri)// 正则function getQueryString(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");var r = window.location.search.substr(1).match(reg); //获取url中"?"符后的字符串并正则匹配var context = "";if (r != null) context = r[2];reg = null;r = null;return context == null || context == "" || context == "undefined" ? "" : context;}// such as:// alert(GetQueryString("参数名1"));// alert(GetQueryString("参数名2"));// alert(GetQueryString("参数名3"));// split拆分法function GetRequest() {var url = location.search; //获取url中"?"符后的字串var theRequest = new Object();if (url.indexOf("?") != -1) {var str = url.substr(1);strs = str.split("&");for (var i = 0; i < strs.length; i++) {theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);}}return theRequest;}var Request = new Object();Request = GetRequest();// var 参数1,参数2,参数3,参数N;// 参数1 = Request['参数1'];// 参数2 = Request['参数2'];// 参数3 = Request['参数3'];// 参数N = Request['参数N'];// 修改 URL 的中某个参数值//替换指定传入参数的值,paramName为参数,replaceWith为新值function replaceParamVal(paramName, replaceWith) {var oUrl = this.location.href.toString();var re = eval("/(" + paramName + "=)([^&]*)/gi");var nUrl = oUrl.replace(re, paramName + "=" + replaceWith);this.location = nUrl;window.location.href = nUrl;}/*** 指定参数名称,返回该参数的值 或者 空字符串* 不指定参数名称,返回全部的参数对象 或者 {}* 如果存在多个同名参数,则返回数组*/function getUrlParam(url, key) {var arr = {};url.replace(/\??(\w+)=(\w+)&?/g, function (match, matchKey, matchValue) {if (!arr[matchKey]) {arr[matchKey] = matchValue;} else {var temp = arr[matchKey];arr[matchKey] = [].concat(temp, matchValue);}});if (!key) {return arr;} else {for (ele in arr) {if ((ele = key)) {return arr[ele];}}return "";}}}
H5(ios)-在点击输入框,出现键盘后,弹出层被顶上去,而光标还停留在原处,即出现错位情况
{// 单个input(textarea)$("input.van-field__control, textarea.van-field__control").blur(function () {setTimeout(function () {var currentPosition = document.documentElement.scrollTop || document.body.scrollTop;window.scrollTo(0, currentPosition); //页面向上滚动}, 200);});// 多个input(textarea)$(function () {var setTimerTop = 0;$(document).on('blur', 'input.van-field__control, textarea.van-field__control', function () {event.preventDefault()setTimerTop = setTimeout(function () {window.scrollBy(0, 5); // 页面向上滚动window.scrollBy(0, -5);}, 500)}).on('focus', 'input.van-field__control, textarea.van-field__control', function () {clearTimeout(setTimerTop)})})// 多个input(textarea)-iframe情况$(function() {var setTimerTop = 0;$(document).on('blur', 'input.van-field__control, textarea.van-field__control', function() {event.preventDefault()setTimerTop = setTimeout(function() {parent.scrollBy(0, 5); // 页面向上滚动parent.scrollBy(0, -5);$('#hide-area-cb').focus();}, 500)}).on('focus', 'input.van-field__control, textarea.van-field__control', function() {clearTimeout(setTimerTop);}).on('focus', 'input.van-field__control[disabled]', function() {setTimerTop = setTimeout(function() {parent.scrollBy(0, 5); // 页面向上滚动parent.scrollBy(0, -5);}, 500)})})}
判断类型
// 判断类型function toType(obj) {return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();}
对象判空
注:永远不要使用构造函数创建对象
{function isEmptyObject(value) {return (value && Object.keys(value).length === 0 && value.constructor === Object);}}{function isEmptyObject(value) {return (Object.prototype.toString.call(value) === "[object Object]" &&JSON.stringify(value) === "{}");}}// Lodash_.isEmpty({});// jQueryjQuery.isEmptyObject({});
函数防抖
{// 简单 函数防抖function debounce(method, wait) {let timeout;// args为返回函数调用时传入的参数,传给methodreturn function (...args) {let context = this;if (timeout) {clearTimeout(timeout);}timeout = setTimeout(() => {// args是一个数组,所以使用fn.apply// 也可写作method.call(context, ...args)method.apply(context, args);}, wait);};}// 完整 函数防抖function debounce(method, wait, immediate) {let timeout;// debounced函数为返回值// 使用Async/Await处理异步,如果函数异步执行,等待setTimeout执行完,拿到原函数返回值后将其返回// args为返回函数调用时传入的参数,传给methodlet debounced = function (...args) {return new Promise(resolve => {// 用于记录原函数执行结果let result;// 将method执行时this的指向设为debounce返回的函数被调用时的this指向let context = this;// 如果存在定时器则将其清除if (timeout) {clearTimeout(timeout);}// 立即执行需要两个条件,一是immediate为true,二是timeout未被赋值或被置为nullif (immediate) {// 如果定时器不存在,则立即执行,并设置一个定时器,wait毫秒后将定时器置为null// 这样确保立即执行后wait毫秒内不会被再次触发let callNow = !timeout;timeout = setTimeout(() => {timeout = null;}, wait);// 如果满足上述两个条件,则立即执行并记录其执行结果if (callNow) {result = method.apply(context, args);resolve(result);}} else {// 如果immediate为false,则等待函数执行并记录其执行结果// 并将Promise状态置为fullfilled,以使函数继续执行timeout = setTimeout(() => {// args是一个数组,所以使用fn.apply// 也可写作method.call(context, ...args)result = method.apply(context, args);resolve(result);}, wait);}});};// 在返回的debounced函数上添加取消方法debounced.cancel = function () {clearTimeout(timeout);timeout = null;};return debounced;}}
生成 -0
// one// 首先创建一个8位的ArrayBufferconst buffer = new ArrayBuffer(8);// 创建DataView对象操作bufferconst dataView = new DataView(buffer);// 将第1个字节设置为0x80,即最高位为1dataView.setUint8(0, 0x80);// 将buffer内容当做Float64类型返回console.log(dataView.getFloat64(0)); // -0// twoconsole.log(0 * -1); // -0
reduce
{// 对后端返回的列表数据进行相同数据整合处理let oldList = [{ id: 111, date: "05-25", list: [1, 2, 3] },{ id: 222, date: "05-26", list: [4, 5] },{ id: 111, date: "05-25", list: [4, 5] }];function formatList() {return Array.from(oldList.reduce((dict, item) => {if (dict.has(item.id)) {dict.get(item.id).list.push(...item.list);} else {dict.set(item.id, {id: item.id,date: item.date,list: [...item.list]});}return dict;}, new Map())).map(item => ({date: item[1].date,id: item[1].id,list: item[1].list}));}console.log(formatList());// [// { id: 111, date: "05-25", list: [1, 2, 3, 4, 5] },// { id: 222, date: "05-26", list: [4, 5] }// ];// 数组list去重const data = [{ name: "Kris", age: "24" },{ name: "Andy", age: "25" },{ name: "Kitty", age: "25" },{ name: "Andy", age: "25" },{ name: "Kitty", age: "25" },{ name: "Andy", age: "25" },{ name: "Kitty", age: "25" }];let newData = Object.values(data.reduce((prev, cur, idx) => {let obj = {};const { name } = cur;obj[name] = cur;return {...prev,...obj};}, {}));console.log(newData)}{/*** reduce方法同时实现map和filter* 需求:假设现在有一个数列,你希望更新它的每一项(map的功能)然后筛选出一部分(filter的功能)。如果是先使用map然后filter的话,你需要遍历这个数组两次。 在下面的代码中,我们将数列中的值翻倍,然后挑选出那些大于50的数*/const numbers = [10, 20, 30, 40];const doubledOver50 = numbers.reduce((finalList, num) => {num = num * 2;if (num > 50) {finalList.push(num);}return finalList;}, []);console.log(doubledOver50); // [ 60, 80 ]}
实现数字金额转大写金额
function digitUppercase(n) {let fraction = ["角", "分"];let digit = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"];let unit = [["元", "万", "亿"],["", "拾", "佰", "仟"]];let head = n < 0 ? "欠" : "";n = Math.abs(n);let s = "";for (let i = 0; i < fraction.length; i++) {s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, "");}s = s || "整";n = Math.floor(n);for (let k = 0; k < unit[0].length && n > 0; k++) {let p = "";for (let j = 0; j < unit[1].length && n > 0; j++) {p = digit[n % 10] + unit[1][j] + p;n = Math.floor(n / 10);}s = `${p.replace(/(零.)*零$/, "").replace(/^$/, "零")}${unit[0][k]}${s}`;}return `${head}${s.replace(/(零.)*零元/, "元").replace(/(零.)+/g, "零").replace(/^整$/, "零元整")}`;}console.log(digitUppercase(7682.01)); // 柒仟陆佰捌拾贰元壹分console.log(digitUppercase(7682)); // 柒仟陆佰捌拾贰元整console.log(digitUppercase(951434677682.0)); // 玖仟伍佰壹拾肆亿叁仟肆佰陆拾柒万柒仟陆佰捌拾贰元整function noToChinese(num) {if (!/^\d*(\.\d*)?$/.test(num)) return;var digit = new Array("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖");var unit = new Array("", "拾", "佰", "仟", "萬", "億", "点", "");var a = ("" + num).replace(/(^0*)/g, "").split("."),k = 0,re = "";for (var i = a[0].length - 1; i >= 0; i--) {switch (k) {case 0:re = unit[7] + re;break;case 4:if (!new RegExp("0{4}\\d{" + (a[0].length - i - 1) + "}$").test(a[0]))re = unit[4] + re;break;case 8:re = unit[5] + re;unit[7] = unit[5];k = 0;break;}if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0)re = digit[0] + re;if (a[0].charAt(i) != 0) re = digit[a[0].charAt(i)] + unit[k % 4] + re;k++;}// 处理小数部分if (a.length > 1) {re += unit[6];for (var i = 0; i < a[1].length; i++) re += digit[a[1].charAt(i)];}return re;}
返回字符串的字节长度
function byteSize(str) {return new Blob([str]).size;}console.log(byteSize("Hello World")); // 11
平均数
// 平均数const average = (...nums) => nums.reduce((acc, val) => acc + val, 0) / nums.length;console.log(average(...[1, 2, 3])); // 2console.log(average(1, 2, 3)); // 2
日期
// 当前日期天数const dayOfYear = date => Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);console.log(dayOfYear(new Date())); // 302// 返回日期间的天数const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24);console.log(getDaysDiffBetweenDates(new Date('2019-01-01'), new Date('2019-10-29'))); // 301
解析有效日期
iOS 解析 YYYY-MM-DD HH:mm:ss 这种日期格式会报错 Invalid Date,Android 无问题
查看开发手册发现可用:YYYY/MM/DD HH:mm:ss,那么需替换其中的 - 为 /
const date = "2021-02-05 10:39:00";new Date(date.replace(/\-/g, "/"));
首(每个)字母大、小写
// 首字母大写const capitalize = ([first, ...rest]) => first.toUpperCase() + rest.join('');console.log(capitalize('fooBar')); // FooBarconsole.log(capitalize('fooBar', true)); // FooBar// 首字母小写const decapitalize = ([first, ...rest]) => first.toLowerCase() + rest.join('');console.log(decapitalize('FooBar')); // fooBarconsole.log(decapitalize('FooBar')); // fooBar// 每个单词首字母大写const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase());console.log(capitalizeEveryWord('hello world!')); // 'Hello World!'
平滑滚动至顶部
const scrollToTop = () => {const c = document.documentElement.scrollTop || document.body.scrollTop;if (c > 0) {window.requestAnimationFrame(scrollToTop);window.scrollTo(0, c - c / 8);}};
滚动到指定元素区域
const smoothScroll = element =>document.querySelector(element).scrollIntoView({behavior: 'smooth'});smoothScroll('#fooBar');
深克隆
const clone = parent => {// 维护两个储存循环引用的数组const parents = [];const children = [];const _clone = parent => {if (parent === null) return null;if (typeof parent !== 'object') return parent;let child, proto;if (isType(parent, 'Array')) {// 对数组做特殊处理child = [];} else if (isType(parent, 'RegExp')) {// 对正则对象做特殊处理child = new RegExp(parent.source, getRegExp(parent));if (parent.lastIndex) child.lastIndex = parent.lastIndex;} else if (isType(parent, 'Date')) {// 对Date对象做特殊处理child = new Date(parent.getTime());} else {// 处理对象原型proto = Object.getPrototypeOf(parent);// 利用Object.create切断原型链child = Object.create(proto);}// 处理循环引用const index = parents.indexOf(parent);if (index != -1) {// 如果父数组存在本对象,说明之前已经被引用过,直接返回此对象return children[index];}parents.push(parent);children.push(child);for (let i in parent) {// 递归child[i] = _clone(parent[i]);}return child;};return _clone(parent);};{const isComplexDataType = (obj) => (typeof obj === "object" || typeof obj === "function") && obj !== null;const deepClone = function (obj, hash = new WeakMap()) {// 日期对象直接返回一个新的日期对象if (obj.constructor === Date) {return new Date(obj);}//正则对象直接返回一个新的正则对象if (obj.constructor === RegExp) {return new RegExp(obj);}//如果循环引用了就用 weakMap 来解决if (hash.has(obj)) {return hash.get(obj);}let allDesc = Object.getOwnPropertyDescriptors(obj);//遍历传入参数所有键的特性let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc);//继承原型链hash.set(obj, cloneObj);for (let key of Reflect.ownKeys(obj)) {cloneObj[key] =isComplexDataType(obj[key]) && typeof obj[key] !== "function"? deepClone(obj[key], hash): obj[key];}return cloneObj;};}
