常用微码


JavaScript

文件大小计算

/**
 * 文件大小计算
 * size: 文件大小 byte
 * result: 结果
 */
function getFileOfSize(size) {
    var result = 0;
    result = fileCalc(size, result);
    size = (size / Math.pow(1024,result)).toFixed(2);
    if (result == 1) {
        return size+"K";
    }else if (result == 2) {
        return size+"M";
    }else if (result == 3) {
        return size+"G";
    }
}

function fileCalc(size, result) {
    result++;
    size = (size / 1024).toFixed(2);
    if (size > 1024) {
        result = arguments.callee(size, result);
    }

    return result;
}

UUID生成

function UUID(){
    var d = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = (d + Math.random()*16)%16 | 0;
        d = Math.floor(d/16);
        return (c=='x' ? r : (r&0x7|0x8)).toString(16);
    });
    return uuid;
}

获取URL参数

function getQueryString(key){
    var reg = new RegExp("(^|&)"+key+"=([^&]*)(&|$)");
    var result = window.location.search.substr(1).match(reg);
    return result?decodeURIComponent(result[2]):null;
}

JS数字转汉字

var chnNumChar = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
var chnUnitSection = ["", "万", "亿", "万亿", "亿亿"];
var chnUnitChar = ["", "十", "百", "千"];

const SectionToChinese = section => {
  var strIns = '', chnStr = '';
  var unitPos = 0;
  var zero = true;
  while (section > 0) {
    var v = section % 10;
    if (v === 0) {
      if (!zero) {
        zero = true;
        chnStr = chnNumChar[v] + chnStr;
      }
    } else {
      zero = false;
      strIns = chnNumChar[v];
      strIns += chnUnitChar[unitPos];
      chnStr = strIns + chnStr;
    }
    unitPos++;
    section = Math.floor(section / 10);
  }
  return chnStr;
}

const NumberToChinese = num => {
  var unitPos = 0;
  var strIns = '', chnStr = '';
  var needZero = false;

  if (num === 0) {
    return chnNumChar[0];
  }

  while (num > 0) {
    var section = num % 10000;
    if (needZero) {
      chnStr = chnNumChar[0] + chnStr;
    }
    strIns = SectionToChinese(section);
    strIns += (section !== 0) ? chnUnitSection[unitPos] : chnUnitSection[0];
    chnStr = strIns + chnStr;
    needZero = (section < 1000) && (section > 0);
    num = Math.floor(num / 10000);
    unitPos++;
  }

  return chnStr;
}

module.exports = {
  NumberToChinese: NumberToChinese
}

有序数组插入数字

function insertNumber(arr, x) {
    
    //查找到第一个大于x的数字
    let b = newArr.find(e => e > x);
    
    
    if (b === undefined) { 
        // 如果b不存在,证明x是最大的数字,push到数组尾部
        newArr.push(x);
        
    } else {
    
        //获取b的index,把新的数字插入到b的位置
        let bIndex = newArr.indexOf(b)
        newArr.splice(bIndex, 0, x)
    }
    
    return arr;

}

两个有序数组合并成一个新的有序数组

function insert_some_numbers(arr1, arr2) {
    //创建新数组,并结构第一个数组
    var newArr = [...arr1];
    
    for (var i = 0; i < arr2.length; i++) {
        //获取第二个数组中的每一位
        x = arr2[i];
        
        //在新解构的数组中查找第一个比他大的数组
        let b = newArr.find(e => e > x);
        
        //获取到这个数字的索引并插入到他的前面
        let bindex = newArr.indexOf(b)
        newArr.splice(bindex === -1 ? newArr.length : bindex, 0, x)
    }
    return newArr;
}
let arr1 = [1, 2, 3, 4, 5, 6, 8, 9];
console.log(insert_some_numbers(arr1, [1, 2, 3]));

二分查找

function binarySearch(arr, x) {
    var left = 0; //左边界
    var right = arr.length - 1; //右边界
    var guess;  // 游标, 中间索引去小数点

    while (left <= right) { // 左侧边界小于右侧边界才执行
    
        guess = ((left + right) / 2) | 0;  //游标索引, 中间索引去小数点
        
        if (arr[guess] === x) return guess // 当游标索引就是查找的X的话,返回游标索引
        
        else if (arr[guess] > x) right = guess - 1 // 游标索引位 大于 x , 右边界移动到guess之前。
        
        else left = guess + 1 // 游标索引位 小于 x , 右边界移动到guess之后。
    }
    
    return -1; //未查找到
}

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(
    binarySearch(arr, 5) 
)

有序数组插入新数字

  • 模拟一个空位置循环比较
  • 从数组尾部向前比较,前面的那一位比x大,比x大的那个数字索引+1
  • 再跟前面的一位作比较,如果比X小, p+1位索引就被变量x 占了
function insert_number_3(arr, x) {
    //p是下一个待比较元素的索引
    //p-1是空位
    //p不能小于0, 当P小于0代表, x是最小的
    let p = arr.length - 1;
    while (p >= 0 && arr[p] > x) {
        arr[p + 1] = arr[p];
        p--;
    }
    arr[p + 1] = x;
}
let arr1 = [1, 2, 3, 4, 5, 6, 8, 9];
insert_number_3(arr1, 6)
console.log(arr1)

插入排序

function insertion_sort(arr) {
    //第一位不用去作比较,只有一位的数组可以看作为有序数组
    for (var i = 1; i < arr.length; i++) {
        insert(arr, i, arr[i]);
    }
}

function insert(arr, i, x) {
    let p = i - 1; // p 作为被首先比较的元素
    // arr[i] 也就是 x  是待插入的元素
    while (p >= 0 && arr[p] > x) {
        // 当待插入的元素
        arr[p + 1] = arr[p];
        p--;
    }
    arr[p + 1] = x;
}

选择排序

// 找到第一个最小的,放在第一位
// 再找到第二个最小的, 放在第二位
function select(array) {

    var len = array.length;
    
    //第零位到倒数第二位
    for (var i = 0; i < len - 1; i++) { 
        
        //先认定数组中的第i位是最小的, 再逐次跟后面的作比较
        var minnum = array[i];
        
        //第一位到最后一位
        for (var j = i + 1; j < len; j++) { 
            
            // 如果后面的更小的话, 做值的交换
            if (array[j] < minnum) {
                //值交换
                [array[j], minnum] = [minnum, array[j]]
            }
        }
        //比较过后, 给第i位赋值
        array[i] = minnum;
    }
}

var arr = [4, 5, 8, 9, 4, 2, 15, 6]
select(arr)
console.log(arr)

冒泡排序

  • 先找出最大的,再找出最小的
  • 性能最差
  • 排序次数: arr.length的等差数列求和次 -> n**n/2 -n/2 次
function bubble_sort(arr) {
    //值交换函数
    function swap(arr, x, j) {
        [arr[x],arr[j]] = [arr[j], arr[i]]
    }
    
    //先找出最大的,再找出最小的
    for (let i = arr.length - 1; i >= 1; i--) {
        //从1开始,每一次都和前一位作比较。
        for (let j = 1; j <= i; j++) {
            arr[j] < arr[j - 1] && swap(arr, j-1, j)
        }
    }
}

const arr2 = [91, 60, 96, 9, 30, 20, 31, 77, 81, 24];
bubble_sort(arr2)
console.log(arr2);

合并排序

//将数组分成两个数组, 
// 索引 [a,b) 和 [b,c)

//合并函数部分,
function merge(arr, a, b, c) {
    // 此时arr1 和 arr2 是 两个有序数组
    let arr1 = arr.slice(a, b);
    let arr2 = arr.slice(b, c);

    //在两个数组后面布置哨兵
    arr1.push(Infinity);
    arr2.push(Infinity);
    //设置两个数组的比较位置的索引的游标索引
    // 如果这个数字被赋值,则索引+1
    var i = 0, j = 0;
    //循环给arr赋值
    for (let k = a; k < c; k++) {
        //k : 下一个写入位置
        //i : arr1中的回写位置
        //j :  arr2中的回写位置
        arr[k] = arr1[i] < arr2[j] ? arr1[i++] : arr2[j++];
    }
}

function mergeSort(arr, a, c) {
    //判断数组长度是否为1
    if (c - a < 2) { return };
    const b = Math.ceil((a + c) / 2);
    //左侧部分递归
    mergeSort(arr, a, b);
    //右侧部分递归
    mergeSort(arr, b, c);
    //执行拼接
    merge(arr, a, b, c);
}

// 把数组拆成一个,一个的数组, 在执行拼接

双路快速

function quickSort(arr) {
    //递归出口,数组长度为0
    if (arr.length == 0) return [];
    // 建立比较数字, 左侧数组, 右侧数组
    var left = [];
    var right = [];
    var pivot = arr[0];
    //从数组第一位开始比较
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] < pivot) {
            left.push(arr[i]);
        } else {
            right.push(arr[i]);
        }
    }
    // 递归 连接数组, 这个函数是纯函数,结果不会改变原数组。
    return quickSort(left).concat(pivot, quickSort(right))
}
let arr = [4, 51, 59, 13, 1, 31, 3, 1, 8];
let result = quickSort(arr);
console.log(result)

三路快排

function qSort3(arr) {
    if (arr.length == 0) {
        return [];
    }
    //定义三个数组
    var left = [];
    //三路快排的核心是多了一个中间数组, 中间数组放相等的值,避免了不必要的比较
    var center = []; 
    var right = [];

    //设置一个比较值
    var pivot = arr[0];

    //循环比较部分
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] < pivot) {
            left.push(arr[i]);
        } else if (arr[i] == pivot) {
            center.push(arr[i]);
        } else {
            right.push(arr[i]);
        }
    }
    //循环递归 大于比较值的部分和小于比较值的部分
    return [...qSort3(left), ...center, ...qSort3(right)];
}
var newArr = qSort3([9, 4, 10, 8, 12, 2, 6, 7, 3, 1, 1, 0, 9, 1, 0])
console.log(newArr)

深度克隆

function deepClone2(origin, target) {
    var target = target || ((origin instanceof Array) ? [] : {});

    for (var prop in origin) {
        if (origin.hasOwnProperty(prop)) {
            if (typeof origin[prop] == 'object') {
                if (Object.prototype.toString.call(origin[prop]) === '[object Array]') {
                    target[prop] = [];
                } else {
                    target[prop] = {};
                }
                deepClone2(origin[prop], target[prop]);
            } else {
                target[prop] = origin[prop]
            }
        }
    }
    return target;
}

数组扁平化

function platArray(arr) {
    var newArr = [];
    function pushToArray(arr) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] instanceof Array) {
                pushToArray(arr[i])
            } else {
                newArr.push(arr[i])
            }
        }
    }
    pushToArray(arr)
    return newArr;
}
console.log(platArray([[1, 2], [[[[3]]]], [{ name: "lyz", info: { age: "24" } }], [4, [5, [6]]]]));
// [1, 2, 3, { name: 'lyz', info: { age: '24' } }, 4, 5, 6]

字符串反转

var str = 'abcde';

function strReverse(str) {
    // new String 出来的类数组是不能修改某一位的,
    // writeable是false;
    var strObj = [...new String(str)];
    var times = strObj.length / 2 | 0;
    for (var i = 0; i < times; i++) {
        var y = strObj.length - 1 - i;
        [strObj[i], strObj[y]] = [strObj[y], strObj[i]];

    }
    return strObj.join('');
}

console.log(strReverse(str));

简易Promise

//executor 函数是同步执行的函数 ,包含有两个参数 resolve reject
// promise对象有三种状态 pending, fulfilled 和 rejected

function myPromise(executor) {
    //在 es5中函数中执行函数的this指向问题
    var _this = this;

    // 设置初始状态和resolve和reject函数初始参数
    _this.status = "pending";
    _this.resolveValue = null;
    _this.rejectValue = null;

    function resolve(value) {
        if (_this.status === 'pending') {
            _this.status = "fulfilled";
            _this.resolveValue = value;
        }
    }
    
    function reject(reason) {
        if (_this.status === 'pending') {
            _this.status = "rejected";
            _this.rejectValue = reason;
        }
    }
    
    //使用try catch来处理Promise中抛出异常的情况
    try {
        executor(resolve, reject)
    } catch (e) {
        //如果抛出异常 , 执行reject就可以了
        reject(e)
    }

}

//Promise原型链上的方法then的实现

myPromise.prototype.then = function (onFulfilled, onRejected) {
    var _this = this;
    
    if (_this.status === "fulfilled") {
        onFulfilled(_this.resolveValue)
    }
    if (_this.status === "rejected") {
        onRejected(_this.rejectValue)
    }
}

异步的简易版Promise

//executor 函数是同步执行的函数 ,包含有两个参数 resolve reject
// promise对象有三种状态
// pending, fulfilled 和 rejected

function myPromise(executor) {
    //在 es5中函数中执行函数的this指向问题
    var _this = this;

    // 设置初始状态和resolve和reject函数初始参数
    _this.status = "pending";
    _this.resolveValue = null;
    _this.rejectValue = null;

    //执行数组, 里面存入函数
    _this.ResolveCallbackList = [];
    _this.RejectCallbackList = [];

    function resolve(value) {
        if (_this.status === 'pending') {
            _this.status = "fulfilled";
            _this.resolveValue = value;
            //执行的时候已经可以是异步了, 如果是异步的时候, 
            //数组里面有函数,不然没有函数
            _this.ResolveCallbackList.forEach(function (ele) {
                ele();
            })
        }
    }
    function reject(reason) {
        if (_this.status === 'pending') {
            _this.status = "rejected";
            _this.rejectValue = reason;
            //执行的时候已经可以是异步了, 如果是异步的时候, 
            //数组里面有函数,不然没有函数
            _this.RejectCallbackList.forEach(function (ele) {
                ele();
            })
        }
    }
    //使用try catch来处理Promise中抛出异常的情况
    try {
        executor(resolve, reject)
    } catch (e) {
        //如果抛出异常 , 执行reject就可以了
        reject(e)
    }

}

//Promise原型链上的方法then的实现

myPromise.prototype.then = function (onFulfilled, onRejected) {
    var _this = this;
    if (_this.status === "fulfilled") {
        onFulfilled(_this.resolveValue)
    }
    if (_this.status === "rejected") {
        onRejected(_this.rejectValue)
    }
    
    //增加pending状态的判断, 如果是pending, 存入到相应的执行事件的数组当中。
    if (_this.status === "pending") {
        onFulfilled && _this.ResolveCallbackList.push(function () {
            onFulfilled(_this.resolveValue);
        });
        onRejected && _this.RejectCallbackList.push(function () {
            onRejected(_this.rejectValue);
        })
    }
}

Promise.all

MyPromise.all = function(promises) {
    return new Promise(function (resolve, reject) {
        //类型判断
        if (!isArray(promises)) {
            return reject(new TypeError('arguments must be an array'));
        }
        //目前已经resolve的数量
        var resolvedCounter = 0;
        //获取参数数组长度
        var promisesNum = promises.length;
        // 全部成功是的返回值是一个数组,数组里面是每一个成功的promise的resolve的参数
        var resolvedValues = new Array(promiseNum);
        //对数组进行遍历,因为是异步,所以要防止产生闭包。
        for (var i = 0; i < promiseNum; i++) {
            (function (i) {
                Promise.resolve(promises[i]).then(function (value) {
                    resolvedCounter++
                    resolvedValues[i] = value
                    // 只有resolve的数量和promise的数量一致的时候才会触发最外层的resolve执行
                    if (resolvedCounter == promisesNum) {
                        return resolve(resolvedValues)
                    }
                }, function (reason) {
                    return reject(reason)
                })
            })(i)
        }
    })
}

解构原始数据

const rawUser = {
   name: 'John',
   surname: 'Doe',
   email: 'john@doe.com',
   displayName: 'SuperCoolJohn',
   joined: '2016-05-05',
   image: 'path-to-the-image',
   followers: 45
   ...
}
//提取出两个部分,分别是用户及用户信息
let user = {}, userDetails = {};
({ name: user.name, surname: user.surname, ...userDetails } = rawUser);

console.log(user); // outputs { name: "John", surname: "Doe" }
console.log(userDetails); // outputs { email: "john@doe.com", displayName: "SuperCoolJohn", joined: "2016-05-05", image: "path-to-the-image", followers: 45 }

动态属性名

const dynamic = 'email';
let user = {
    name: 'John',
    [dynamic]: 'john@doe.com'
}
console.log(user); // outputs { name: "John", email: "john@doe.com" }

CSS

超过2行显示点点点

overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;

空心箭头

.u-arrow {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-top: 2px solid #62B4FB;
    border-right: 2px solid #62B4FB;
}

.u-arrow-up {
    margin: 0 0 -2px 5px;
    transform: rotate(-45deg);
}

.u-arrow-down {
    margin: 0 0 2px 5px;
    transform: rotate(135deg);
}

.u-arrow-left {
    transform: rotate(-135deg);
}

.u-arrow-right {
    transform: rotate(45deg);
}

爱心

#heart {
  position: relative;
  width: 100px;
  height: 90px;
}
#heart:before,
#heart:after {
  position: absolute;
  content: "";
  left: 50px;
  top: 0;
  width: 50px;
  height: 80px;
  background: red;
  border-radius: 50px 50px 0 0;
  transform: rotate(-45deg);
  transform-origin: 0 100%;
}
#heart:after {
  left: 0;
  transform: rotate(45deg);
  transform-origin: 100% 100%;
}

太极

#yin-yang {
  width: 96px;
  box-sizing: content-box;
  height: 48px;
  background: #eee;
  border-color: red;
  border-style: solid;
  border-width: 2px 2px 50px 2px;
  border-radius: 100%;
  position: relative;
}
#yin-yang:before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  background: #eee;
  border: 18px solid red;
  border-radius: 100%;
  width: 12px;
  height: 12px;
  box-sizing: content-box;
}
#yin-yang:after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: red;
  border: 18px solid #eee;
  border-radius: 100%;
  width: 12px;
  height: 12px;
  box-sizing: content-box;
} 

放大镜

#magnifying-glass {
  font-size: 10em;
  display: inline-block;
  width: 0.4em;
  box-sizing: content-box;
  height: 0.4em;
  border: 0.1em solid red;
  position: relative;
  border-radius: 0.35em;
}
#magnifying-glass:before {
  content: "";
  display: inline-block;
  position: absolute;
  right: -0.25em;
  bottom: -0.1em;
  border-width: 0;
  background: red;
  width: 0.35em;
  height: 0.08em;
  transform: rotate(45deg);
}

#lock {
  font-size: 8px;
  position: relative;
  width: 18em;
  height: 13em;
  border-radius: 2em;
  top: 10em;
  box-sizing: border-box;
  border: 3.5em solid red;
  border-right-width: 7.5em;
  border-left-width: 7.5em;
  margin: 0 0 6rem 0;
}
#lock:before {
  content: "";
  box-sizing: border-box;
  position: absolute;
  border: 2.5em solid red;
  width: 14em;
  height: 12em;
  left: 50%;
  margin-left: -7em;
  top: -12em;
  border-top-left-radius: 7em;
  border-top-right-radius: 7em;
}
#lock:after {
  content: "";
  box-sizing: border-box;
  position: absolute;
  border: 1em solid red;
  width: 5em;
  height: 8em;
  border-radius: 2.5em;
  left: 50%;
  top: -1em;
  margin-left: -2.5em;
}

小程序重置button样式


button {
  margin: 0;
  padding: 0;
  background-color: transparent;
  line-height: inherit;
  border-radius: 0;
  border: none;
}
button::after{
  border: none;
}

vue

识别ie浏览器


/**
 * 识别ie--浅识别
 */
export const isIe = () => {
    let explorer = window.navigator.userAgent;
        //判断是否为IE浏览器
    if (explorer.indexOf("MSIE") >= 0) {
        return true;
    }else {
        return false
    }
}

颜色16进制转rgba


/**
 * 颜色转换16进制转rgba
 * @param {String} hex 
 * @param {Number} opacity 
 */
export function hex2Rgba(hex, opacity) {
	if(!hex) hex = "#2c4dae";
    return "rgba(" + parseInt("0x" + hex.slice(1, 3)) + "," + parseInt("0x" + hex.slice(3, 5)) + "," + parseInt("0x" + hex.slice(5, 7)) + "," + (opacity || "1") + ")";
}

去除html标签


// 去除html标签
export const htmlSafeStr = (str) => {
    return str.replace(/<[^>]+>/g, "")
}

获取url参数对象


/* 获取url参数 */
export const getQueryString = () => {
    let qs = location.href.split('?')[1] || '',
        args = {},
        items = qs.length ? qs.split("&") : [];
        items.forEach((item,i) => {
            let arr = item.split('='),
                name = decodeURIComponent(arr[0]),
                value = decodeURIComponent(arr[1]);
                name.length && (args[name] = value)
        })
    return args;
}

解析url参数


/* 解析url参数 */
export const paramsToStringify = (params) => {
    if(params){
        let query = [];
        for(let key in params){
            query.push(`${key}=${params[key]}`)
        }
        return `${query.join('&')}`
    }else{
        return ''
    }
}

数据转化为数组


export const toArray = (data) => {
    return Array.isArray(data) ? data : [data]
}

带参数跳转url(hash模式)


/**
 *  带参数跳转url(hash模式)
 * @param {String} url 
 * @param {Object} params 
 */
export const toPage = (url, params) => {
    if(params){
        let query = [];
        for(let key in params){
            query.push(`${key}=${params[key]}`)
        }
        window.location.href = `./index.html#/${url}?${query.join('&')}`;
    }else{
        window.location.href = `./index.html#/${url}`;
    }
}

控制字符串显示,超出指定字数则显示省略号


/**
 * 指定字符串 溢出显示省略号
 * @param {String} str
 * @param {Number} num
 */
export const getSubStringSum = (str = "", num = 1) => {
    let newStr;
    if(str){
        str = str + '';
        if (str.trim().length > num ) {
            newStr = str.trim().substring(0, num) + "...";
        } else {
            newStr = str.trim();
        }
    }else{
        newStr = ''
    }
    return newStr;
}

生成uuid


/**
 * 生成uuid
 * @param {number} len 生成指定长度的uuid
 * @param {number} radix uuid进制数
 */
export function uuid(len, radix) {
    let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
    let uuid = [], i;
    radix = radix || chars.length;
 
    if (len) {
      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
    } else {
      let r;
 
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
      uuid[14] = '4';
 
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random()*16;
          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
        }
      }
    }
 
    return uuid.join('');
}

生成指定格式的时间字符串


/**
 * 生成指定格式的时间
 * @param {*} timeStemp 时间戳
 * @param {*} flag 格式符号
 */
export function formatTime(timeStemp, flag) {
    let time = new Date(timeStemp);
    let timeArr = [time.getFullYear(), time.getMonth() + 1, time.getDate()];
    return timeArr.join(flag || '/')
}

扫描下方二维码阅读当前文章

浏览器、微信扫码

评 论:

好文推荐

扫描下方二维码阅读文章

浏览器、微信扫码
每天进步一点点~