1, isStatic: check whether the data is the original data except symbol

function isStatic(value) {
    return(
        typeof value === 'string' ||
        typeof value === 'number' ||
        typeof value === 'boolean' ||
        typeof value === 'undefined' ||
        value === null
    )
}
Copy the code

2. IsPrimitive: Check if the data is raw

function isPrimitive(value) {
    return isStatic(value) || typeof value === 'symbol'
}
Copy the code

Array, Functions, Objects, Regexes, New Number(0), and New String(“)

function isObject(value) {
    let type = typeof value;
    returnvalue ! = null && (type= ='object' || type= ='function');
}
Copy the code

4. IsObjectLike: Check whether value is a class object. If a value is a class object, it should not be null, and the result after typeof is “object”.

function isObjectLike(value) {
    returnvalue ! = null && typeof value =='object';
}
Copy the code

5. GetRawType: Gets the data type. The result is Number, String, Object, Array, etc

function getRawType(value) {
    return Object.prototype.toString.call(value).slice(8, -1)
}
//getoRawType([]) ==> Array
Copy the code

6. IsPlainObject: Determines whether the data is of type Object

function isPlainObject(obj) {
    return Object.prototype.toString.call(obj) === '[object Object]'
}
Copy the code

7. IsArray: Checks whether the data is an array

function isArray(arr) {
    return Object.prototype.toString.call(arr) === '[object Array]'
}
Copy the code

Mount isArray to Array

Array.isArray = Array.isArray || isArray;
Copy the code

IsRegExp: checks whether data is a regular object

function isRegExp(value) {
    return Object.prototype.toString.call(value) === '[object RegExp]'
}
Copy the code

9. IsDate: Determine whether data is a time object

function isDate(value) {
    return Object.prototype.toString.call(value) === '[object Date]'
}
Copy the code

10. IsNative: Determine whether value is a built-in function of the browser

The main code block after the built-in Function toString is [native code], while non-built-in functions are related code, so non-built-in functions can be copied.

function isNative(value) {
    return typeof value === 'function' && /native code/.test(value.toString())
}
Copy the code

IsFunction: check whether value is a function

function isFunction(value) {
    return Object.prototype.toString.call(value) === '[object Function]'
}
Copy the code

12. IsLength: Check if value is a valid class array length

function isLength(value) {
    return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= Number.MAX_SAFE_INTEGER;
}
Copy the code

IsArrayLike: Check if value is a class array

If a value is considered an array of classes, it is not a function, and value.length is an integer greater than or equal to 0 and less than or equal to number. MAX_SAFE_INTEGER. Here strings will also be treated as class arrays.

function isArrayLike(value) {
    returnvalue ! = null && isLength(value.length) && ! isFunction(value); }Copy the code

14. IsEmpty: check whether value isEmpty

If null, return true; If it is a class array, determine the length of the data; If the Object is an Object, check whether it has attributes. For other data, return false(or return true instead)

function isEmpty(value) {
    if (value == null) {
        return true;
    }
    if (isArrayLike(value)) {
        return! value.length; }else if(isPlainObject(value)){
        for (let key in value) {
            if (hasOwnProperty.call(value, key)) {
              return false; }}}return false;
}
Copy the code

Cached: Memory function: cached result of operation

function cached(fn) {
    let cache = Object.create(null);
    return function cachedFn(str) {
        let hit = cache[str];
        return hit || (cache[str] = fn(str))
    }
}
Copy the code

16. Camelize: Naming of horizontal turning hump

let camelizeRE = /-(\w)/g;
function camelize(str) {
    return str.replace(camelizeRE, function(_, c) {
        return c ? c.toUpperCase() : ' '; })} //ab-cd-ef ==> abCdEf // use memory functionlet _camelize = cached(camelize)
Copy the code

Horizontal naming: Split strings, concatenated with -, and converted to lowercase

let hyphenateRE = /\B([A-Z])/g;
function hyphenate(str){
    return str.replace(hyphenateRE, '- $1'ToLowerCase ()} //abCd ==> ab-cd // use the memory functionlet _hyphenate = cached(hyphenate);
Copy the code

Capitalize the first part of a string

function capitalize(str){
    returnStr.charat (0).toupperCase () + str.slice(1)} // ABC ==> ABC // use the memory functionlet _capitalize = cached(capitalize)
Copy the code

Extend: blends properties into the target object

function extend(to, _from) {
    for(let key in _from) {
        to[key] = _from[key];
    }
    return to
}
Copy the code

20, Object.assign: Copy Object attributes, shallow copy

Object.assign = Object.assign || function() {if(arguments.length == 0) throw new TypeError('Cannot convert undefined or null to object');
    
    let target = arguments[0],
        args = Array.prototype.slice.call(arguments, 1),
        key
    args.forEach(function(item){
        for(key in item){
            item.hasOwnProperty(key) && ( target[key] = item[key] )
        }
    })
    return target
}
Copy the code

You can shallow clone an Object using object. assign:

let clone = Object.assign({}, target)
Copy the code

A simple deep clone can use json.parse () and json.stringify (). These apis parse JSON data, so only primitive types and arrays and objects other than Symbol can be parsed

let clone = JSON.parse( JSON.stringify(target) )
Copy the code

21, Clone: clone data, can be deep clone

function clone(value, deep){
    if(isPrimitive(value)){
        return value
    }
    
    if(isArrayLike (value)) {/ / is a class Array value = Array. The prototype. Slice. The call (value)return value.map(item => deep ? clone(item, deep) : item)
       }else if(isPlainObject(value)){// Is an objectlet target = {}, key;
          for (key in value) {
            value.hasOwnProperty(key) && ( target[key] = deep ? clone(value[key], deep) : value[key] )
        }
    }
    
    let type = getRawType(value)
    
    switch(type) {case 'Date':
        case 'RegExp': 
        case 'Error': value = new window[type](value); break;
    }
    return value
}
Copy the code

22. Identify browsers and platforms

// The runtime environment is a browserlet inBrowser = typeof window ! = ='undefined'; // The operating environment is wechatlet inWeex = typeof WXEnvironment ! = ='undefined'&&!!!!! WXEnvironment.platform;let weexPlatform = inWeex && WXEnvironment.platform.toLowerCase(); // Browser UA judgmentlet UA = inBrowser && window.navigator.userAgent.toLowerCase();
let isIE = UA && /msie|trident/.test(UA);
let isIE9 = UA && UA.indexOf('msie 9.0') > 0;
let isEdge = UA && UA.indexOf('edge/') > 0;
let isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android');
let isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios');
letisChrome = UA && /chrome\/\d+/.test(UA) && ! isEdge;Copy the code

GetExplorerInfo: Get browser information

function getExplorerInfo() {
    let t = navigator.userAgent.toLowerCase();
    return 0 <= t.indexOf("msie")? { //ie < 11type: "IE", version: Number(t.match(/msie ([\d]+)/)[1]) } : !! t.match(/trident\/.+? rv:(([\d.]+))/) ? { // ie 11type: "IE",
        version: 11
    } : 0 <= t.indexOf("edge")? {type: "Edge",
        version: Number(t.match(/edge\/([\d]+)/)[1])
    } : 0 <= t.indexOf("firefox")? {type: "Firefox",
        version: Number(t.match(/firefox\/([\d]+)/)[1])
    } : 0 <= t.indexOf("chrome")? {type: "Chrome",
        version: Number(t.match(/chrome\/([\d]+)/)[1])
    } : 0 <= t.indexOf("opera")? {type: "Opera",
        version: Number(t.match(/opera.([\d]+)/)[1])
    } : 0 <= t.indexOf("Safari")? {type: "Safari",
        version: Number(t.match(/version\/([\d]+)/)[1])
    } : {
        type: t,
        version: -1
    }
}
Copy the code

24. IsPCBroswer: Checks whether the browser mode isPC

function isPCBroswer() {
    let e = navigator.userAgent.toLowerCase()
        , t = "ipad" == e.match(/ipad/i)
        , i = "iphone" == e.match(/iphone/i)
        , r = "midp" == e.match(/midp/i)
        , n = "rv:1.2.3.4" == e.match(/rv:1.2.3.4/i)
        , a = "ucweb" == e.match(/ucweb/i)
        , o = "android" == e.match(/android/i)
        , s = "windows ce" == e.match(/windows ce/i)
        , l = "windows mobile" == e.match(/windows mobile/i);
    return! (t || i || r || n || a || o || s || l) }Copy the code

25, unique: array to return a new array

function unique(arr){
    if(! IsArrayLink (arr)){// Is not an array-like objectreturn arr
    }
    let result = []
    let objarr = []
    let obj = Object.create(null)
    
    arr.forEach(item => {
        if(isStatic(item)){// is the original data except symbollet key = item + '_' + getRawType(item);
            if(! obj[key]){ obj[key] =true
                result.push(item)
            }
        }else{// Reference type and symbolif(! objarr.includes(item)){ objarr.push(item) result.push(item) } } })return resulte
}
Copy the code

26, Set simple implementation

window.Set = window.Set || (function () {
    functionSet(arr) { this.items = arr ? unique(arr) : []; this.size = this.items.length; // Array size} set. prototype = {add:function(value) {// Add the element, skip if the element already exists, and return the Set structure itself.if(! this.has(value)) { this.items.push(value); this.size++; }return this;
        },
        clear: function() {// Clear all members, no return value. this.items = [] this.size = 0 }, delete:function(value) {// Delete a value, return a Boolean value indicating whether the deletion was successful.return this.items.some((v, i) => {
                if(v === value){
                    this.items.splice(i,1)
                    return true
                }
                return false
            })
        },
        has: function(value) {// Returns a Boolean value indicating whether the value is a member of Set.return this.items.some(v => v === value)
        },
        values: function () {
            return this.items
        },
    }

    returnSet; } ());Copy the code

27, Repeat: Generate a repeated string consisting of N STR, which can be modified to fill an array, etc

function repeat(str, n) {
    let res = ' ';
    while(n) {
        if(n % 2 === 1) {
            res += str;
        }
        if(n > 1) {
            str += str;
        }
        n >>= 1;
    }
    return res
};
//repeat('123', 3) = = > 123123123Copy the code

28, dateFormater: format time

function dateFormater(formater, t){
    let date = t ? new Date(t) : new Date(),
        Y = date.getFullYear() + ' ',
        M = date.getMonth() + 1,
        D = date.getDate(),
        H = date.getHours(),
        m = date.getMinutes(),
        s = date.getSeconds();
    returnFormater. Replace (/ YYYY | YYYY/g, Y). The replace (/ YY/g | YY, Y.s ubstr (2, 2)). The replace (/ MM/g (M < 10?'0':' ') + M)
        .replace(/DD/g,(D<10?'0':' ') + D)
        .replace(/HH|hh/g,(H<10?'0':' ') + H)
        .replace(/mm/g,(m<10?'0':' ') + m)
        .replace(/ss/g,(s<10?'0':' ') + s)
}
// dateFormater('YYYY-MM-DD HH:mm', t) ==> 2019-06-26 18:30
// dateFormater('YYYYMMDDHHmm', t) ==> 201906261830
Copy the code

DateStrForma: Converts the specified string from one time format to another

The form from should correspond to the position of STR

function dateStrForma(str, from, to){
    //'20190626' 'YYYYMMDD' 'YYYY year MM month DD day '
    str += ' '
    let Y = ' '
    if(~(Y = from.indexOf('YYYY'))){
        Y = str.substr(Y, 4)
        to = to.replace(/YYYY|yyyy/g,Y)
    }else if(~(Y = from.indexOf('YY'))){
        Y = str.substr(Y, 2)
        to = to.replace(/YY|yy/g,Y)
    }

    let k,i
    ['M'.'D'.'H'.'h'.'m'.'s'].forEach(s =>{
        i = from.indexOf(s+s)
        k = ~i ? str.substr(i, 2) : ' '
        to = to.replace(s+s, k)
    })
    return to
}
// dateStrForma('20190626'.'YYYYMMDD'.'YYYY year MM month DD day ') ==> June 26, 2019 // dateStrForma('121220190626'.'----YYYYMMDD'.'YYYY year MM month DD day ') ==> June 26, 2019 // dateStrForma('26 June 2019'.'YYYY year MM month DD day '.'YYYYMMDD') ==> 20190626 // General can also use re implementation //'26 June 2019'.replace(/(\d{4}) year (\d{2}) month (\d{2}) day /,'$1 - $2 - $3') = = > 2019-06-26Copy the code

30, getPropByPath: get object property by string path: ‘obj[0].count’

function getPropByPath(obj, path, strict) {
      let tempObj = obj;
      path = path.replace(/\[(\w+)\]/g, '$1'); // Convert [0] to.0 path = path.replace(/^\.' '); // remove the initial.let keyArr = path.split('. '); // According to.cutlet i = 0;
      for (let len = keyArr.length; i < len - 1; ++i) {
        if(! tempObj && ! strict)break;
        let key = keyArr[i];
        if (key in tempObj) {
            tempObj = tempObj[key];
        } else {
            if(strict) {// Enable strict mode, no key found, throw new Error('please transfer a valid prop path to form item! ');
            }
            break; }}return{o: tempObj, // Original data k: keyArr[I], //key value v: tempObj? TempObj [keyArr[I]] : null // Key value}; };Copy the code

GetUrlParam: Gets the Url parameter and returns an object

function GetUrlParam() {let url = document.location.toString();
    let arrObj = url.split("?");
    let params = Object.create(null)
    if (arrObj.length > 1){
        arrObj = arrObj[1].split("&");
        arrObj.forEach(item=>{
            item = item.split("=");
            params[item[0]] = item[1]
        })
    }
    returnparams; } / /? a=1&b=2&c=3 ==> {a:"1", b: "2", c: "3"}
Copy the code

32, downloadFile: base64 Data export file, file download

function downloadFile(filename, data){
    let DownloadLink = document.createElement('a');
    if ( DownloadLink ){
        document.body.appendChild(DownloadLink);
        DownloadLink.style = 'display: none';
        DownloadLink.download = filename;
        DownloadLink.href = data;

        if ( document.createEvent ){
            let DownloadEvt = document.createEvent('MouseEvents');

            DownloadEvt.initEvent('click'.true.false);
            DownloadLink.dispatchEvent(DownloadEvt);
        }
        else if ( document.createEventObject )
            DownloadLink.fireEvent('onclick');
        else if (typeof DownloadLink.onclick == 'function') DownloadLink.onclick(); document.body.removeChild(DownloadLink); }}Copy the code

33. ToFullScreen: full screen

function toFullScreen() {let elem = document.body;
    elem.webkitRequestFullScreen
    ? elem.webkitRequestFullScreen()
    : elem.mozRequestFullScreen
    ? elem.mozRequestFullScreen()
    : elem.msRequestFullscreen
    ? elem.msRequestFullscreen()
    : elem.requestFullScreen
    ? elem.requestFullScreen()
    : alert("Browser does not support full screen");
}
Copy the code

34, exitFullscreen: exitFullscreen

function exitFullscreen() {let elem = parent.document;
    elem.webkitCancelFullScreen
    ? elem.webkitCancelFullScreen()
    : elem.mozCancelFullScreen
    ? elem.mozCancelFullScreen()
    : elem.cancelFullScreen
    ? elem.cancelFullScreen()
    : elem.msExitFullscreen
    ? elem.msExitFullscreen()
    : elem.exitFullscreen
    ? elem.exitFullscreen()
    : alert("Switchover failed. Try Esc to exit.");
}
Copy the code

RequestAnimationFrame: Window animation


window.requestAnimationFrame = window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    function(callback) {// To enablesetThe Timteout effect window.setTimeout(callback, 1000/60) is as close to 60 frames per second as possible; }; window.cancelAnimationFrame = window.cancelAnimationFrame || Window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame || window.oCancelAnimationFrame ||function(id) {// To makesetTimteout is as close to the 60 frames per second effect window.clearTimeout(id) as possible; }Copy the code

36. _isNaN: Checks whether data is a non-numeric value

Native isNaN converts arguments to numbers (valueof), while NULL, true, false, and arrays of length less than or equal to 1 (elements of non-nan data) are converted to numbers, which is not what I want. Symbol data does not have a Valueof interface, so isNaN throws an error, which is left behind to avoid errors

function _isNaN(v){
    return! (typeof v ==='string' || typeof v === 'number') || isNaN(v)
}
Copy the code

37, Max: Find the maximum value of non-nan data in the array

functionmax(arr){ arr = arr.filter(item => ! _isNaN(item))return arr.length ? Math.max.apply(null, arr) : undefined
}
//max([1, 2, '11', null, 'fdf'= = > 11, []])Copy the code

38, min: Find the minimum value in array non-nan data

functionmin(arr){ arr = arr.filter(item => ! _isNaN(item))return arr.length ? Math.min.apply(null, arr) : undefined
}
//min([1, 2, '11', null, 'fdf'= = > 1, []])Copy the code

39. Random: Returns a random number between lower-upper

Lower and upper must be non-nan data regardless of whether they are positive, negative or large

function random(lower, upper){
    lower = +lower || 0
    upper = +upper || 0
    return Math.random() * (upper - lower) + lower;
}
//random(0, 0.5) ==> 0.3567039135734613
//random(2, 1) ===> 1.6718418553475423
//random(-2, -1) ==> -1.4474325452361945
Copy the code

Keys: Returns an array of the self-enumerable properties of a given Object

Object.keys = Object.keys || function keys(object) {
    if(object === null || object === undefined){
        throw new TypeError('Cannot convert undefined or null to object');
    }
    let result = []
    if(isArrayLike(object) || isPlainObject(object)){
        for (let key in object) {
            object.hasOwnProperty(key) && ( result.push(key) )
        }
    }
    return result
}
Copy the code

Object.values: Returns an array of all enumerable property values for a given Object itself

Object.values = Object.values || function values(object) {
    if(object === null || object === undefined){
        throw new TypeError('Cannot convert undefined or null to object');
    }
    let result = []
    if(isArrayLike(object) || isPlainObject(object)){
        for (let key in object) {
            object.hasOwnProperty(key) && ( result.push(object[key]) )
        }
    }
    return result
}
Copy the code

Arr. fill: Fills the array with a value starting at start and ending at end (but not end), returning the array

Array.prototype.fill = Array.prototype.fill || function fill(value, start, end) {
    let ctx = this
    let length = ctx.length;
    
    start = parseInt(start)
    if(isNaN(start)){
        start = 0
    }else if (start < 0) {
        start = -start > length ? 0 : (length + start);
      }
      
      end = parseInt(end)
      if(isNaN(end) || end > length){
          end = length
      }else if (end < 0) {
        end += length;
    }
    
    while (start < end) {
        ctx[start++] = value;
    }
    return ctx;
}
//Array(3).fill(2) ===> [2, 2, 2]
Copy the code

43, arr.includes: used to determine whether an array contains a specified value. If true, false otherwise, you can specify the starting location of the query

Array.prototype.includes = Array.prototype.includes || function includes(value, start){
    let ctx = this
    let length = ctx.length;
    
    start = parseInt(start)
    if(isNaN(start)){
        start = 0
    }else if (start < 0) {
        start = -start > length ? 0 : (length + start);
      }
    
    let index = ctx.indexOf(value)
    
    return index >= start;
}
Copy the code

Arr. find: Returns the value of the first element in the array that passes the test (judged by fn)

Array.prototype.find = Array.prototype.find || function find(fn, ctx){
    ctx = ctx || this
    
    let result;
    ctx.some((value, index, arr), thisValue) => {
        return fn(value, index, arr) ? (result = value, true) : false
    })
    
    return result
}
Copy the code

Arr. FindIndex: Returns the index of the first element in the array that passes the test (judged in fn)

Array.prototype.findIndex = Array.prototype.findIndex || function findIndex(fn, ctx){
    ctx = ctx || this
    
    let result;
    ctx.some((value, index, arr), thisValue) => {
        return fn(value, index, arr) ? (result = index, true) : false
    })
    
    return result
}
Copy the code

Performance. Timing: Performance. Timing is used for performance analysis

window.onload = function() {setTimeout(function() {let t = performance.timing
        console.log('DNS query time: ' + (t.domainLookupEnd - t.domainLookupStart).toFixed(0))
        console.log('TCP connection Time: ' + (t.connectEnd - t.connectStart).toFixed(0))
        console.log('Request Request time:' + (t.responseEnd - t.responseStart).toFixed(0))
        console.log(Dom tree parsing time: + (t.domComplete - t.domInteractive).toFixed(0))
        console.log('White screen Time:' + (t.responseStart - t.navigationStart).toFixed(0))
        console.log('DomReady time:' + (t.domContentLoadedEventEnd - t.navigationStart).toFixed(0))
        console.log('onload time: ' + (t.loadEventEnd - t.navigationStart).toFixed(0))

        if(t = performance.memory){
            console.log('JS memory usage ratio:' + (t.usedJSHeapSize / t.totalJSHeapSize * 100).toFixed(2) + The '%')}}}Copy the code

47. Disable certain keyboard events

document.addEventListener('keydown'.function(event){
    return! ( 112 == event.keyCode || //F1 123 == event.keyCode || //F12 event.ctrlKey && 82 == event.keyCode || //ctrl + R event.ctrlKey && 78 == event.keyCode || //ctrl + N event.shiftKey && 121 == event.keyCode || //shift + F10
        event.altKey && 115 == event.keyCode || //alt + F4
        "A" == event.srcElement.tagName && event.shiftKey //shift+ click on a TAB) | | (event. ReturnValue =false)});Copy the code

Prohibit right clicking, selecting and copying

['contextmenu'.'selectstart'.'copy'].forEach(function(ev){
    document.addEventListener(ev, function(event){
        return event.returnValue = false})});Copy the code