• Customize various Javascipt API implementations
  • Improve JS core ability greatly, install force must learn
  • Online document preview yun.y2y7.com

Functions related to

call()

  • Syntax: call(fn, obj,… args)
  • Function: Execute fn, make this obj, and pass n arguments to fn
  • Function equivalent to the call method of a function object
function call(fn, obj, ... args) {
    // if obj is null or undefined, it points to a global object
    if (obj === null || obj === undefined) {
        obj = globalThis; // Global objects
    }
    // Add temporary methods for obj
    obj.temp = fn;
    // Execute the temporary method to pass in the parameter to get the result
    constreuslt = obj.temp(... args);// Delete temporary methods
    delete obj.temp;
    // Return the result
    return reuslt;
}


/ / test
function add(a, b) {
    // console.log(this);
    return a + b + this.c;
}
window.c = 10;
const obj = {
    c: 20};console.log(call(add, null.30.40)); // points to the window result 80
console.log(call(add, obj, 30.40)); // point to obj result 90
Copy the code

apply()

  • Syntax: apply(fn, obj, args)
  • Function: Execute fn, make this obj, and pass the args array to fn
  • The function is equivalent to the Apply method of a function object
function apply(fn, obj, args) {
    // if obj is null or undefined, it points to a global object
    if (obj === null || obj === undefined) {
        obj = globalThis; // Global objects
    }
    // Add temporary methods for obj
    obj.temp = fn;
    // Execute the temporary method to pass in the parameter to get the result
    constreuslt = obj.temp(... args);// Delete temporary methods
    delete obj.temp;
    // Return the result
    return reuslt;
}

/ / test
function add(a, b) {
    // console.log(this);
    return a + b + this.c
}
window.c = 10;
const obj = {
    c: 20
}

console.log(apply(add, null[30.40])); // points to the window result 80
console.log(apply(add, obj, [30.40]));  // point to obj result 90
Copy the code

bind()

  • Syntax: bind(fn, obj,… args)
  • Function: returns a new function that binds fn to this as obj and specifies n arguments
  • Function equivalent to the bind method of a function object
function bind(fn, obj, ... args1) {
    // Return the new function
    return function(. args2) {
        // The new function returns the result from the call function
        returncall(fn, obj, ... args1, ... args2) } }/ / test
function add(a, b) {
    // console.log(this);
    return a + b + this.c;
}
window.c = 10;
const obj = {
    c: 20};// bind bind this to return the new function
const fn1 = bind(add, obj, 30.40);
console.log(fn1()); / / 90

// The new function returned passes arguments
const fn2 = bind(add, obj);
console.log(fn2(30.50)); / / 100

// Pass some first and then pass the whole
const fn3 = bind(add, obj, 30);
console.log(fn3(60)); / / 110
Copy the code

Function anti-shake throttling

  • High frequency event triggers can cause pages to stall and cause unnecessary stress on the server if requests are sent
  • Frequent starts can be limited by shaking and throttling

Image stabilization

The function is executed n seconds after the event is triggered. If it is triggered again within n seconds, the timer is reset

Scene:

  • Input field real-time search association (keyUP /input)
function debounce(fn, delay) {
    // Timer variable
    let timerId;
    return function (. args) {
        / / determine
        if (timerId) {
            // Empty the timer
            clearTimeout(timerId);
        }
        // Start the timer execution function
        timerId = setTimeout(() = > {
            fn.apply(this, args);
            // Clear the current timer to prevent the next step into the if logic
            timerId = null;
        }, delay);
    };
}

/ / test
<input type="text" />
const input = document.querySelector("input");
const debounceTask = debounce((e) = > {
    console.log(e.target.value);
}, 500);
input.addEventListener("input", debounceTask);
Copy the code

The throttle

Once in a while, the function is executed

Scene:

  • Window resize
  • Page scroll
  • DOM element drag and drop implementation (Mousemove)
  • Buy crazy click
function throttle(fn, delay) {
    // Define the start time
    let start = 0;
    return function (. args) {
        let now = Date.now();
        // Determine the current time - the start time is greater than or equal to the delay time
        if (now - start >= delay) {
            // Execute the function
            fn.apply(this, args);
            // Change the start timestart = now; }}; }/ / test
function task() {
    console.log("run task");
}
const throttleTask = throttle(task, 1000);
window.addEventListener("scroll", throttleTask);
Copy the code

once

function once(fn) {
    // The identifier is used to control the function to be executed only once
    let done = false;
    return function (. args) {
        / / determine
        if(! done) { done =true;
            // Execute the function
            fn.call(this. args); }}; }/ / test
let pay = once(function (money) {
    console.log(` pay:${money} RMB`);
});
pay(5);
pay(5);
pay(5);
Copy the code

The function is currified

  • When a function has more than one argument, it is called by passing some of the arguments
  • It then returns a new function that takes the remaining arguments and returns the result
function curry(fn) {
    // Return the Currie function
    return function curryFn(. args1) {
        // Call the function if the parameters and arguments are the same
        if (fn.length === args1.length) returnfn(... args1);// Returns the function's cumulative arguments if there are not enough arguments
        return (. args2) = >curryFn(... args1, ... args2); }; }/ / test
function getSum(a, b, c) {
    return a + b + c;
}

let curried = curry(getSum);
console.log(curried(1) (2) (3)); / / 6
console.log(curried(1) (2.3)); / / 6
console.log(curried(1.2) (3)); / / 6
console.log(curried(1.2.3)); / / 6
Copy the code

An array of relevant

forEach

  • Iterate over each element of the corresponding array
export function forEach(arr, callback) {
    for (let i = 0; i < arr.length; i++) { callback(arr[i], i); }}Copy the code

map

  • Returns a new array of the return values of the callback function
function map(arr, callback) {
    // Prepare an array
    const result = [];
    / / loop
    for (let i = 0; i < arr.length; i++) {
        // Execute the function and pass in the array entry and index
        result.push(callback(arr[i], i));
    }
    // Returns the reassembled array
    return result;
}

/ / test
const arr = [2.3.4.5];
const newArr = map(arr, (item, index) = > {
    console.log("Each item in the array", item);
    console.log("Array index", index);
    return item * 10;
});
console.log(newArr); // [20, 30, 40, 50]
Copy the code

reduce

  • The callback function is executed once for each element of the array from left to right
  • The return value of the previous callback is passed to the next callback as an argument in a store
  • And returns the return value of the last callback function
function reduce(arr, callback, initValue) {
    // result assigns an initial value
    let result = initValue;
    / / loop
    for (let i = 0; i < arr.length; i++) {
        // The execution function passes in the initial value and array elements and reassigns the return value to result so that it can be used as the first argument to the callback next time
        result = callback(result, arr[i]);
    }
    // Returns the cumulative result
    return result;
}

/ / test
const arr = [1.2.3.4.5];
const result = reduce(
    arr,
    (pre, cur) = > {
        return pre + cur;
    },
    5
);
console.log(result); / / 20
Copy the code

filter

  • Return all in the filter functiontruePut the array element into a new array and return
function filter(arr, callback) {
    // Define the result array
    const result = [];
    / / loop
    for (let i = 0; i < arr.length; i++) {
        // Execute the callback function to pass in the array item and index to get the return value
        const res = callback(arr[i], i);
        // Returns true and pushes the result array
        if(res) { result.push(arr[i]); }}// Returns an array of results
    return result;
}

/ / test
const arr = [1.2.3.4.5];
const newArr = filter(arr, (item, index) = > {
    return item % 2= = =0;
});
console.log(newArr); / / (2, 4]
Copy the code

find

  • Find the first element that satisfies the test function and return the value of that element
  • If not found, returnundefined
function find(arr, callback) {
    / / loop
    for (let i = 0; i < arr.length; i++) {
        // Execute the callback function to pass in the array item and index to get the return value
        const res = callback(arr[i], i);
        // Determine true
        if (res) {
            // Returns the current traversal element
            returnarr[i]; }}// return undefined if none of these returns are true
    return undefined;
}

/ / test
const arr = [1.2.3.4.5.1024];
const result = find(arr, (item, index) = > {
    return item > 1000;
});
console.log(result); / / 1024
Copy the code

findIndex

  • Find the first element that satisfies the test function and return the index of that element
  • If not found, return- 1
function findIndex(arr, callback) {
    / / loop
    for (let i = 0; i < arr.length; i++) {
        // Execute the callback function to pass in the array item and index to get the return value
        const res = callback(arr[i], i);
        // Determine true
        if (res) {
            // Returns the index of the current traversal element
            returni; }}// If none of these returns are true, -1 is returned
    return -1;
}

/ / test
const arr = [1.2.3.4.5.1024];
const result = findIndex(arr, (item, index) = > {
    return item > 1000;
});
console.log(result); 5
Copy the code

every

  • Returns true if every element in the array satisfies the test function, false otherwise
function every(arr, callback) {
    / / loop
    for (let i = 0; i < arr.length; i++) {
        // Return false if one of the values returned by the callback is false
        if(! callback(arr[i], i)) {return false; }}// Otherwise return true
    return true;
}

/ / test
const arr = [1.2.3.4.5.1024];
const result1 = every(arr, (item, indx) = > {
    return item > 0;
});
console.log(result1); // true
Copy the code

some

  • Returns true if at least one element in the array satisfies the test function, false otherwise
function some(arr, callback) {
    / / loop
    for (let i = 0; i < arr.length; i++) {
        Return true if one of the values returned by the callback is true
        if (callback(arr[i], i)) {
            return true; }}// Otherwise return false
    return false;
}

/ / test
const result2 = some(arr, (item, indx) = > {
    return item > 10000;
});
console.log(result2); // true
Copy the code

Array to heavy

Methods a

  • Using ES6 syntax:… + Set or array. from() + Set
  • concise
function unique1(arr) {
    // Set is converted to a real array
    // return [...new Set(arr)];
    return Array.from(new Set(arr));
}

/ / test
const arr = [1.2.3.3.4.4.5];
const newArr = unique1(arr);
console.log(newArr); // [1, 2, 3, 4, 5]
Copy the code

Way 2

  • Use forEach() and indexOf() or includes()
  • The essence is double traversal, less efficient
function unique2(arr) {
    // Prepare the result array
    const result = [];
    / / loop
    arr.forEach((item) = > {
        // Array does not contain this item push
        / /! result.includes(item)
        if (result.indexOf(item) === -1) { result.push(item); }});// Returns an array of results
    return result;
}
Copy the code

Methods three

  • Use forEach() + object containers
  • It’s more efficient to just iterate
function unique3(arr) {
    // Prepare arrays and objects
    const result = [];
    const obj = {};
    / / loop
    arr.forEach((item) = > {
        // Use the object key to determine if it does not exist
        if(! obj[item]) { obj[item] =true; result.push(item); }});// Returns an array of results
    return result;
}
Copy the code

An array of merger

  • Merge n arrays or values with the current array to generate a new array. The original array is not changed
function concat(arr, ... args) {
    // The array to merge
    const result = [...arr];
    // Loop through the array of parameters passed in
    for (let i = 0; i < args.length; i++) {
        // Expand and push the result array if the item is an array
        if (Array.isArray(args[i])) { result.push(... args[i]); }else {
            // Otherwise, push directlyresult.push(args[i]); }}/ / return
    return result;
}

/ / test
const arr1 = [1.2];
const newArr = concat(arr1, 3[4.5], [6.7].8);
console.log(newArr); // [1, 2, 3, 4, 5, 6, 7, 8]
Copy the code

Array slice

  • Returns a shallow copy of the original array determined by start and end. The original array is not changed
function slice(arr, start = 0, end = arr.length) {
    // When the end is less than the beginning
    if (end < start) {
        end = arr.length;
    }
    // Result array
    const result = [];
    // Loop pushes when the index is greater than or equal to the beginning and less than the end
    for (let i = 0; i < arr.length; i++) {
        if(i >= start && i < end) { result.push(arr[i]); }}/ / return
    return result;
}

/ / test
const arr = [1.2.3.4];
const newArr = slice(arr, 1, -1);
console.log(newArr); // [1, 2, 3, 4]
Copy the code

Array flattening

  • Take all elements of a nested array (multidimensional) and put them into a new array (one-dimensional)
  • [1, [3, [2, 4]] ==> [1, 3, 2, 4]
  • Recursive + concat
function flat1(arr) {
    // Prepare the result array
    const result = [];
    / / loop
    for (let i = 0; i < arr.length; i++) {
        // If it is an array
        if (Array.isArray(arr[i])) {
            // Recursively expand and pushresult.push(... flat1(arr[i]));// result = result.concat(flatten(arr[i]))
        } else{ result.push(arr[i]); }}/ / return
    return result;
}

/ / test
const arr = [1.2[3.4[5.6]], 7];
const newArr = flat1(arr);
console.log(newArr); // [1, 2, 3, 4, 5, 6, 7]
Copy the code
  • some + + while + concat
function flat2(arr) {
    // The shallow clone passed into the array does not change the original array
    let result = [...arr];

    // When an array contains an array
    while (result.some((item) = > Array.isArray(item))) {
        // Expand mergeresult = [].concat(... result); }/ / return
    return result;
}
Copy the code

An array of block

  • Syntax: chunk(array, size)
  • Function: divide the array into multiple size length blocks, each block to form a small array, the whole to form a two-dimensional array
  • Such as: [1, 3, 5, 6, 7, 8] calls the chunk (arr, 4) = = > [[1, 3, 5, 6], [7, 8]]
function chunk(arr, size = 1) {
    // Prepare the result and temporary array
    const result = [];
    let temp = [];
    / / traverse
    arr.forEach((item) = > {
        // Push the result array when the temporary array is empty
        if (temp.length === 0) {
            result.push(temp);
        }
        // Push the items into the temporary array
        temp.push(item);
        // Reassign the empty array when the pushed item reaches the length of the incoming block
        if(temp.length === size) { temp = []; }});/ / return
    return result;
}

/ / test
const arr = [1.2.3.4.5.6.7];
const newArr = chunk(arr, 3);
console.log(newArr); // [[1, 2, 3], [4, 5, 6], [7]]
Copy the code

Array fetch difference

  • Syntax: Difference (ARR1, ARR2)
  • Function: Get an array of arR1 elements that are not in ARR2 (without changing the original array)
  • Example: difference([1,3,5,7], [5, 8]) ==> [1,3, 7]
unction difference(arr1, arr2 = []) {
  // The first array filters each item to determine that the second array does not contain this item and returns this item to form a new array
  return arr1.filter((item) = >! arr2.includes(item)); }/ / test
const newArr = difference([1.2.3.4], [3.4.5]);
console.log(newArr); / / [1, 2]
Copy the code

Deletes some elements of the array

pull(array, … values)

  • Delete the element in the original array that is the same as value, return the array of all deleted elements, change the original array
  • Such as: pull (,3,5,3,7] [1, 2, 7, 3, 7) = = = > the original array into [1, 5], the return value for,3,7 [3]

pullAll(array, values):

  • Function the same as pull, except that the parameters become arrays
  • Such as: pullAll ([1, 3, 5, 3, 7], [2, 7, 3, 7)) = = = > array into [1, 5], the return value for [3, 3, 7)
function pull(arr, ... args) {
    // Declare the result array
    const result = [];
    / / loop
    for (let i = 0; i < arr.length; i++) {
        // args if it contains an array entry
        if (args.includes(arr[i])) {
            / / push
            result.push(arr[i]);
            // Delete the current element
            arr.splice(i, 1);
            // subscript subtractioni--; }}// Returns an array of deleted elements
    return result;
}

function pullAll(arr, values) {
    // The second argument array is destructed directly
    returnpull(arr, ... values); }/ / test
const arr1 = [1.2.3.4];
const newArr1 = pull(arr1, 3.4.5);
console.log(arr1); / / [1, 2]
console.log(newArr1); / / [3, 4]

const arr2 = [1.2.3.4];
const newArr2 = pullAll(arr2, [3.4.5.6]);
console.log(arr2); / / [1, 2]
console.log(newArr2); / / [3, 4, 5]
Copy the code

Get the partial elements of the array

drop(array, count)

  • Gets the remaining elements of the current array after the count on the left is filtered out
  • Note: Do not change the current array, count is 1 by default
  • Drop ([1,3,5,7], 2) ===> [5, 7]

dropRight(array, count)

  • Gets the remaining elements of the current array after the count is filtered out
  • Note: Do not change the current array, count is 1 by default
  • DropRight ([1,3,5,7], 2) ===> [1,3]
function drop(arr, size = 1) {
    return arr.filter((item, index) = > index >= size);
}

function dropRight(arr, size = 1) {
    return arr.filter((item, index) = > index < arr.length - size);
}

/ / test
const arr = [1.2.3.4.5];
const newArr1 = drop(arr, 2);
const newArr2 = dropRight(arr, 3);
console.log(newArr1); / / [3, 4, 5]
console.log(newArr2); / / [1, 2]
Copy the code

Related objects

Create an object

  • The Object. Create () compatibility writing function creates a new Object based on obj
function ceateobject(obj) {
    // Create a temporary constructor
    function F() {}
    // Make the temporary constructor's prototype point to O, so that its new object, __proto__, points to O
    F.prototype = obj;
    // Return an instance of F
    return new F();
}
Copy the code

The custom of new

  • Syntax: newInstance(Fn,… args)
  • Function: creates an instance object of the Fn constructor
function newInstanceof(Fn, ... args) {
    // Create an empty object that inherits the constructor's Prototype property
    const object = Object.create(Fn.prototype);
    // Execute the constructor
    constresult = Fn.call(object, ... args);If the result is an object, return it directly, otherwise return the default this object
    return result instanceof Object ? result : object;
}

/ / test
function People(name) {
    this.name = name;
}
People.prototype.sayHello = function () {
    console.log("Hi");
};
const yun = newInstanceof(People, "yunmu");
console.log(yun); // People {name: 'yunmu'}
yun.sayHello(); // Hi
Copy the code

Custom instanceof

  • Syntax: myInstanceOf(obj, Type)
  • Check whether obj is an instance of Type Type
  • Implementation: Whether the prototype object of Type is an object in obj’s prototype chain, return true if it is, false otherwise
function myInstanceof(Fn, obj) {
    // Get the function display prototype
    const prototype = Fn.prototype;
    // Get the implicit prototype of obj
    let proto = obj.__proto__;
    // Iterate through the prototype chain
    while (proto) {
        // Check whether the prototypes are equal
        if (proto === prototype) {
            return true;
        }
        // If not equal to
        proto = proto.__proto__;
    }
    return false;
}

/ / test
function People(name) {
    this.name = name;
}
const yun = newInstanceof(People, "yunmu");
console.log(myInstanceof(People, yun)); // true
console.log(myInstanceof(Object, yun)); // true
console.log(myInstanceof(Object, People)); // true
console.log(myInstanceof(Function, People)); // true
console.log(myInstanceof(Function, yun)); // false
console.log(Object.__proto__ === Function.prototype); // true
console.log(Function.__proto__ === Function.prototype); // true
console.log(Object.__proto__.__proto__ === Object.prototype); // true
console.log(myInstanceof(Object.Object)); // true
console.log(myInstanceof(Function.Function)); // true
console.log(myInstanceof(Function.Object)); // true
console.log(myInstanceof(Object.Function)); // true
Copy the code

Merging multiple objects

  • Syntax: object mergeObject(… objs)
  • Function: Merge multiple objects, return a merged object (without changing the original object)
  • Example:
    • { a: [{ x: 2 }, { y: 4 }], b: 1}
    • { a: { z: 3}, b: [2, 3], c: ‘foo’}
    • After the merger: {a: [{x: 2}, {y: 4}, {3} z:], b: [1, 2, 3], c: ‘foo’}
function mergeObject(. objs) {
    // Define merge objects
    const result = {};
    // Iterate over the object
    objs.forEach((obj) = > {
        // Iterate over the object key name
        Object.keys(obj).forEach((key) = > {
            // The merged object has the same property
            if (result.hasOwnProperty(key)) {
                // merge into array
                result[key] = [].concat(result[key], obj[key]);
            } else {
                / / appendresult[key] = obj[key]; }}); });/ / return
    return result;
}

/ / test
const obj1 = { a: [{ x: 2 }, { y: 4}].b: 1 };
const obj2 = { a: { z: 3 }, b: [2.3].c: "foo" };
console.log(mergeObject(obj1, obj2)); // {a: [{x: 2}, {y: 4}, {z: 3}], b: [1, 2, 3], c:"foo"}
Copy the code

Shallow copy

  • Just copy the object itself reference address value, modify the original data, the new data will change
function shallowClone(target) {
    // Determine the object data type
    if (typeof target === "object"&& target ! = =null) {
        // Check whether it is an array
        if (Array.isArray(target)) {
            return [...target];
        } else {
            return{... target }; }}else {
        returntarget; }}/ / test
const obj = { a: 1.b: { m: 2}};const cloneObj = shallowClone(obj);
obj.b.m = Awesome!;
console.log(obj === cloneObj); //false
console.log(cloneObj);
Copy the code

Deep copy

  • Make a full copy of the new one, opening new space in the heap memory, and old and new data do not affect each other

The beggar version

function deepClone1(target) {
    return JSON.parse(JSON.stringify(target));
}
const obj = {
    a: 1.b: { m: 2 },
    c: [1.2.3].// Methods cannot be cloned
    d(){}};// Creates a circular reference
obj.c.push(obj.b);
obj.b.j = obj.c;
const cloneObj = deepClone1(obj);
obj.c.push(Awesome!);
console.log(obj);
console.log(cloneObj);
Copy the code

Sublimation version

function deepClone2(target, map = new Map(a)) {
    // Type judgment
    if (typeof target === "object"&& target ! = =null) {
        // Set the cache
        const cache = map.get(target);
        // Determine the cache
        if (cache) {
            return cache;
        }
        // Determine the container
        const result = Array.isArray(target) ? [] : {};
        // Set the cache
        map.set(target, result);
        / / traverse
        for (const key in target) {
            // Check whether it is a prototype
            if(target.hasOwnProperty(key)) { result[key] = deepClone2(target[key], map); }}// Returns the reference data from the clone
        return result;
    } else {
        // Return the basic data type
        returntarget; }}Copy the code

Interview bombast

  • Optimization traversal
function deepClone3(target, map = new Map(a)) {
    if (typeof target === "object"&& target ! = =null) {
        const cache = map.get(target);
        if (cache) {
            return cache;
        }
        const isArray = Array.isArray(target);
        const result = isArray ? [] : {};
        map.set(target, result);
        // Determine the array
        if (isArray) {
            / / array
            target.forEach((item, index) = > {
                result[index] = deepClone3(item, map);
            });
        } else {
            / / object
            Object.keys(target).forEach((key) = > {
                result[key] = deepClone3(target[key], map);
            });
        }
        return result;
    } else {
        returntarget; }}Copy the code

String correlation

String in reverse order

  • Grammar: reverseString (STR)
  • Function: Generates a string in reverse order
function reverseString(string) {
    // return string.split("").reverse().join("");
    return [...string].reverse().join("");
}

/ / test
console.log(reverseString("Hello Yunmu, don't be alone in 2022"));
Copy the code

Whether the string is palindrome

  • Grammar: palindrome (STR)
  • Function: Returns true if the given string is a palindrome. Otherwise return false
function palindrome(string) {
  return reverseString(string) === string;
}

/ / test
 console.log(palindrome("lil")); // true
Copy the code

Intercept string

  • Syntax: TRUNCate (STR, num)
  • Function: If the string length exceeds num, cut the preceding num length and start with… The end of the
function truncate(string, size) {
    return string.slice(0, size) + "...";
}

/ / test
 console.log(truncate("hello".3)); // hel...
Copy the code

DOM related

Handwritten DOM Event listener (with delegate)

  • Syntax: addEventListener(Element, type, fn, selector)
  • If a selector does not exist, it binds the event delegate to the element. If a selector does exist, it binds the event delegate to the parent element
function addEventListener(el, type, handler, selector) {
    / / determine
    if (typeof el === "string") {
        el = document.querySelector(el);
    }
    // Pass in the actual event element to fire
    if (selector) {
        // Bind events to the parent element
        el.addEventListener(type, function (e) {
            // Get the actual event source object
            const target = e.target;
            // The selector matches the corresponding element
            if (target.matches(selector)) {
                // Execute the handler to pass in context objects and event objectshandler.call(target, e); }}); }else{ el.addEventListener(type, handler); }}/ / test
<div>
    <p>p1</p>
    <p>p2</p>
    <p>p3</p>
    <a href="# #">a1</a>
</div>

// The event is delegated to the parent element when the inner A selector is clicked
addEventListener(
    "div"."click".function () {
        console.log(this.innerHTML);
    },
    "a"
);
Copy the code

Encapsulating DOM operations

  • The DOM manipulation itself has a lot of APIS, some of which are short and some of which are missing, such as returning all of its siblings and emptying internal elements
window.dom = {
    / / create the element For example the dom. The create (' < div > < span > hello < / span > < / div > ')
    create(string) {
        // Create a container template tag that can hold any element
        const container = document.createElement("template");
        // trim to prevent null characters
        container.innerHTML = string.trim();
        console.log(container.content.firstChild);
        // You must use.content otherwise you can't get it
        return container.content.firstChild;
        / / or
        // return container.content.children[0]
    },

    // Insert back to become brother
    after(node, newNode) {
        // Find the parent of the node and call insertBefore
        // Insert newNode before the next node
        return node.parentNode.insertBefore(newNode, node.nextSibling);
    },
    // Insert front to become brother
    before(node, newNode) {
        // Return the DOM native method of adding the previous node
        return node.parentNode.insertBefore(newNode, node);
    },
    // Insert child elements
    append(newNode, node) {
        return newNode.appendChild(node);
    },
    Dom.wrap (test, newDiv); // Wrap the element wrapped by the first argument
    // Put the new parent node in front of the old node, and then put the old node in the new parent node
    wrap(node, newNode) {
        // Place newNode before and after node
        dom.before(node, newNode);
        // Then put the node node inside the newNode
        dom.append(newNode, node);
    },
    // Remove the corresponding element
    remove(node) {
        node.parentNode.removeChild(node);
        // Returns the deleted node
        return node;
    },
    // Empty the inside of the element
    empty(node) {
        let firstChild = node.firstChild,
            array = [];
        while (firstChild) {
            array.push(dom.remove(node.firstChild));
            firstChild = node.firstChild;
        }
        // Returns the deleted node
        return array;
    },
    Pass in two parameters to query the value of the attribute
    attr(node, name, value) {
        if (arguments.length === 3) {
            / / overloaded
            // Sets an attribute and its value
            node.setAttribute(name, value);
        } else if (arguments.length === 2) {
            // View the value of an attribute of this node
            returnnode.getAttribute(name); }},// View the Settings element text
    text(node, string) {
        if (arguments.length === 2) {
            / / overloaded
            if ("innerText" in node) {
                / / compatible with ie
                return (node.innerText = string);
            } else {
                return(node.textContent = string); }}else if (arguments.length === 1) {
            if ("innerText" in node) {
                return node.innerText;
            } else {
                returnnode.textContent; }}},// View the contents of the Settings element (including tags)
    html(node, string) {
        if (arguments.length === 2) {
            node.innerHTML = string;
        } else if (arguments.length === 1) {
            returnnode.innerHTML; }},// style Three values set style, two values query style, uniform set style can be passed in the second parameter object
    style(node, name, value) {
        if (arguments.length === 3) {
            // dom.style(xxx,'color','red')
            node.style[name] = value;
        } else if (arguments.length === 2) {
            if (typeof name === "string") {
                // dom.style(xxx,'color')
                return node.style[name];
            } else if (name instanceof Object) {
                // dom.style(xxx,{color:'red'})
                const object = name;
                for (let key in object) {
                    // we cannot use style.key because key is a variablenode.style[key] = object[key]; }}}},class: {
        // Add the class name
        add(node, className) {
            node.classList.add(className);
        },
        // Remove the class name
        remove(node, className) {
            node.classList.remove(className);
        },
        // Whether the element has a class name
        has(node, className) {
            returnnode.classList.contains(className); }},// Bind events
    on(node, eventName, fn) {
        node.addEventListener(eventName, fn);
    },
    // Unbind events
    off(node, eventName, fn) {
        node.removeEventListener(eventName, fn);
    },
    // Find elements
    find(selector, scope) {
        return (scope || document).querySelectorAll(selector);
    },
    // Return the parent element
    parent(node) {
        return node.parentNode;
    },
    // Returns all inner element children
    children(node) {
        return node.children;
    },
    // Return all brothers
    siblings(node) {
        return Array.from(node.parentNode.children).filter((n) = >n ! == node); },// Find the next sibling element node
    next(node) {
        let x = node.nextSibling;
        while (x && x.nodeType === 3) {
            // 1 is the element node, 3 is the text node
            x = x.nextSibling;
        }
        return x;
    },
    // Find the last sibling element node
    previous(node) {
        let x = node.previousSibling;
        while (x && x.nodeType === 3) {
            // 1 is the element node, 3 is the text node
            x = x.previousSibling;
        }
        return x;
    },
    // Iterate over the node
    each(nodeList, fn) {
        for (let i = 0; i < nodeList.length; i++) {
            fn.call(null, nodeList[i]); }},// Returns the index of the element in its parent element
    index(node) {
        // Returns the list of elements
        const list = dom.children(node.parentNode);
        / / traverse
        for (let i = 0; i < list.length; i++) {
            if (list[i] === node) {
                returni; }}}};Copy the code

Handwritten Ajax request functions

  • Grammar: axios (options)
    • Parameter configuration objects: URL, method, params, and data
    • The return value is: Promise object
  • axios.get(url, options)
  • axios.post(url, data, options)
  • axios.put(url, data, options)
  • axios.delete(url, options)
  • Functionality: Utility functions that use XHR to send Ajax requests, similar to axios library functionality
function axios({ method, url, params, data }) {
    / / Promise style
    return new Promise((resolve, reject) = > {
        1. Create an XHR object
        const xhr = new XMLHttpRequest();
        // Set the response type to JSON
        xhr.responseType = "json";
        // 2. Listen for the event processing response
        xhr.onreadystatechange = function () {
            if(xhr.readyState ! = =4) return;
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
                // Pass the response information
                resolve({
                    status: xhr.status,
                    message: xhr.statusText,
                    data: xhr.response,
                });
            } else {
                Reject (reason)
                reject(new Error("Request failed: status:"+ xhr.status)); }};// Change the method to uppercase
        method = method.toUpperCase();
        // Concatenate params objects a=1&b=2
        let str = "";
        for (let key in params) {
            str += `${key}=${params[key]}& `;
        }
        str = str.slice(0, -1);
        url += url.includes("?")?"&" : "?";

        // 3. Prepare to send the request
        xhr.open(method, url + str, true);

        // If the request is not get, the request body parameters are carried
        if (method === "POST" || method === "PUT" || method === "DELETE") {
            xhr.setRequestHeader("Content-type"."application/json");
            xhr.send(JSON.stringify(data));
        } else {
            xhr.send(null); }}); } axios.get =function (url, options = {}) {
    const conifg = Object.assign(options, { method: "GET", url });
    return axios(conifg);
};

axios.post = function (url, options = {}) {
    const conifg = Object.assign(options, { method: "POST", url });
    return axios(conifg);
};

axios.put = function (url, options = {}) {
    const conifg = Object.assign(options, { method: "PUT", url });
    return axios(conifg);
};

axios.delete = function (url, options = {}) {
    const conifg = Object.assign(options, { method: "DELETE", url });
    return axios(conifg);
};

/ / test
const url1 =
      "https://www.fastmock.site/mock/13089f924ad68903046c5a61371475c4/api/register";

const url2 =
      "https://www.fastmock.site/mock/13089f924ad68903046c5a61371475c4/api/post";
const params = {
    a: 1.b: 2.c: 3};const data = {
    name: "yunmu"}; axios({url: url1,
    method: "POST",
    params,
    data,
}).then((res) = > {
    console.log(res);
});

axios
    .get(url2, {
    params,
})
    .then((res) = > console.log(res));
Copy the code

Handwritten event bus

  • EventBus: an eventBus object that contains all functionality
  • Eventbus. on(eventName, listener): binds event listener
  • Eventbus. emit(eventName, data): Emit events
  • Eventbus. off(eventName): unbind event listeners with the specified eventName. If unbind all is not specified
const eventBus = {
    // Save the type and callback containers
    callbacks: {
        // login: [fn1, fn2]}};// Bind events
eventBus.on = function (eventName, callback) {
    // Check that this type of event exists
    if (this.callbacks[eventName]) {
        / / push
        this.callbacks[eventName].push(callback);
    } else {
        // Construct this type array
        this.callbacks[eventName] = [callback]; }};// Trigger the event
eventBus.emit = function (eventName, data) {
    // Check that this type of event exists
    if (this.callbacks[eventName] && this.callbacks[eventName].length > 0) {
        // The function executes the incoming data in the array
        this.callbacks[eventName].forEach((event) = >event(data)); }}; eventBus.off =function (eventName) {
    // If the event name is passed in
    if (eventName) {
        // Delete the specified event
        delete this.callbacks[eventName];
    } else {
        / / to empty
        this.callbacks = {}; }};/ / test
eventBus.on("login".(data) = > {
    console.log('User has logged in, data${data}`);
});

eventBus.on("login".(data) = > {
    console.log('User has logged in, data${data}`);
});

eventBus.on("logout".(data) = > {
    console.log(The user has logged out of the data${data}`);
});

setTimeout(() = > {
    eventBus.emit("login"."YunMu");
    eventBus.emit("logout"."YunMu");
}, 1000);

eventBus.off("login");
eventBus.off();
Copy the code

Handwritten message subscription and publishing

  • PubSub: Manager of subscription/publish messages that contain all functionality
  • Pubsub. subscribe(MSG, subscriber): Subscribe message: specifies the message name and subscriber callback function
  • Pubsub. publish(MSG, data): Publish a message: specifies the message name and data
  • Pubsub. unsubscribe(flag): Unsubscribe a message or messages based on the flag
const PubSub = {
  id: 1.callbacks: {
    // pay:{
    // // token_1: fn1,
    // // token_2: fn2,
    // }}}; PubSub.subscribe =function (channel, callback) {
  // Unique number
  let token = "token_" + this.id++;
  // Determine if the callbacks have a channel
  if (this.callbacks[channel]) {
    / / in
    this.callbacks[channel][token] = callback;
  } else {
    // Construct the object store
    this.callbacks[channel] = {
      [token]: callback,
    };
  }
  return token;
};

// Subscribe channels
PubSub.publish = function (channel, data) {
  // Get all callback traversals for the current channel
  if (this.callbacks[channel]) {
    Object.values(this.callbacks[channel]).forEach((callback) = >callback(data) ); }};// Unsubscribe
PubSub.unsubscribe = function (flag) {
  // If there is no transmission, all will be cleared
  if(! flag) {this.callbacks = {};
    / / determine
  } else if (typeof flag === "string") {
    // If token_ is included
    if (flag.includes("token_")) {
      // Traverse the object to find the corresponding token
      const callbackobj = Object.values(this.callbacks).find((obj) = >
        obj.hasOwnProperty(flag)
      );
      if (callbackobj) {
        deletecallbackobj[flag]; }}else {
      // Delete all callbacks under this subscription
      delete this.callbacks[flag]; }}};/ / test
const id1 = PubSub.subscribe("pay".(data) = > {
    console.log("The merchant accepted the order.", data); 
});
const id2 = PubSub.subscribe("pay".(data) = > {
    console.log("The rider took the order.", data);
});

const id3 = PubSub.subscribe("cancel".(data) = > {
    console.log("The buyer canceled the order.", data);
});
PubSub.unsubscribe(id1);
PubSub.publish("pay", {
    title: "Shredded pork with fish flavor".price: 20.address: "xxx"}); PubSub.publish("cancel", {
    title: "Shredded pork with fish flavor".price: 20.address: "xxx"});Copy the code

Write a Promise

  • Define the overall structure
  • Implementation of the Promise constructor
  • Promise. Then ()/catch/finally () () implementation
  • Promise. Resolve ()/reject () implementation
  • The realization of the Promise. All/race ()

ES5 function class

function MyPromise(executor) {
  // State and value of the promise
  this.promiseState = "pending";
  this.promiseResult = null;
  // Save successful and failed callbacks
  this.callbacks = [];
  const resolve = (value) = > {
    // Determine the status
    if (this.promiseState ! = ="pending") return;
    // Change to success status and value
    this.promiseState = "fulfilled";
    this.promiseResult = value;
    // Iterate over successful callback execution
    setTimeout(() = > {
      this.callbacks.forEach((stateObj) = > {
        stateObj.onResolved(value);
      });
    });
  };
  const reject = (reason) = > {
    // Determine the status
    if (this.promiseState ! = ="pending") return;
    // Change to failed state and value
    this.promiseState = "rejected";
    this.promiseResult = reason;
    // Iterate over the failed callback
    setTimeout(() = > {
      this.callbacks.forEach((stateObj) = > {
        stateObj.onRejected(reason);
      });
    });
  };
  // throw throws an error into reject
  try {
    executor(resolve, reject);
  } catch(e) { reject(e); }}// Add the then method
MyPromise.prototype.then = function (onResolved, onRejected) {
  // If no successful or failed callback is passed, one is constructed by default
  if (typeofonResolved ! = ="function") {
    onResolved = (value) = > value;
  }
  if (typeofonRejected ! = ="function") {
    onRejected = (reason) = > {
      throw reason;
    };
  }

  return new MyPromise((resolve, reject) = > {
    const callback = (type) = > {
      try {
        // Get the result of callback function execution
        const result = type(this.promiseResult);
        / / determine
        if (result instanceof MyPromise) {
          // If it is a Promise object
          result.then(
            (res) = > {
              resolve(res);
            },
            (reason) = >{ reject(reason); }); }else {
          // The status becomes successfulresolve(result); }}catch(e) { reject(e); }};// Execute the then successful callback
    if (this.promiseState === "fulfilled") {
      setTimeout(() = > {
        callback(onResolved);
      });
    }
    // Execute then failed callback
    if (this.promiseState === "rejected") {
      setTimeout(() = > {
        callback(onRejected);
      });
    }
    // Save success and failure callbacks for PENDING
    if (this.promiseState === "pending") {
      this.callbacks.push({
        onResolved: () = > {
          callback(onResolved);
        },
        onRejected: () = >{ callback(onRejected); }}); }}); };// Catch instance method
MyPromise.prototype.catch = function (onRejected) {
  return this.then(undefined, onRejected);
};

// finally instance method
MyPromise.prototype.finally = function (callback) {
  return this.then(
    (value) = > {
      return MyPromise.resolve(callback()).then(() = > value);
    },
    (reason) = > {
      return MyPromise.resolve(callback()).then(() = > {
        throwreason; }); }); };// resolve static method
MyPromise.resolve = function (value) {
  return new MyPromise((resolve, reject) = > {
    if (value instanceof MyPromise) {
      value.then(
        (res) = > {
          resolve(res);
        },
        (reason) = >{ reject(reason); }); }else{ resolve(value); }}); };// reject static methods
MyPromise.reject = function (reason) {
  return new MyPromise((resolve, reject) = > {
    reject(reason);
  });
};

// all static method
MyPromise.all = function (promises) {
  / / count
  let count = 0;
  let arr = [];
  return new MyPromise((resolve, reject) = > {
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(
        (value) = > {
          // If one Promise succeeds, +1 until all are successful
          count++;
          arr[i] = value;
          if(count === promises.length) { resolve(arr); }},(reason) = >{ reject(reason); }); }}); };// race static method
MyPromise.race = function (promises) {
  return new MyPromise((resolve, reject) = > {
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(
        (value) = > {
          resolve(value);
        },
        (reason) = >{ reject(reason); }); }}); };Copy the code

ES6 class

class MyPromise {
  constructor(executor) {
    // State and value of the promise
    this.promiseState = "pending";
    this.promiseResult = null;
    // Save successful and failed callbacks
    this.callbacks = [];
    const resolve = (value) = > {
      // Determine the status
      if (this.promiseState ! = ="pending") return;
      // Change to success status and value
      this.promiseState = "fulfilled";
      this.promiseResult = value;
      // Iterate over successful callback execution
      setTimeout(() = > {
        this.callbacks.forEach((stateObj) = > {
          stateObj.onResolved(value);
        });
      });
    };
    const reject = (reason) = > {
      // Determine the status
      if (this.promiseState ! = ="pending") return;
      // Change to failed state and value
      this.promiseState = "rejected";
      this.promiseResult = reason;
      // Iterate over the failed callback
      setTimeout(() = > {
        this.callbacks.forEach((stateObj) = > {
          stateObj.onRejected(reason);
        });
      });
    };
    // throw throws an error into reject
    try {
      executor(resolve, reject);
    } catch(e) { reject(e); }}then(onResolved, onRejected) {
    // If no successful or failed callback is passed, one is constructed by default
    if (typeofonResolved ! = ="function") {
      onResolved = (value) = > value;
    }
    if (typeofonRejected ! = ="function") {
      onRejected = (reason) = > {
        throw reason;
      };
    }

    return new MyPromise((resolve, reject) = > {
      const callback = (type) = > {
        try {
          // Get the result of callback function execution
          const result = type(this.promiseResult);
          / / determine
          if (result instanceof MyPromise) {
            // If it is a Promise object
            result.then(
              (res) = > {
                resolve(res);
              },
              (reason) = >{ reject(reason); }); }else {
            // The status becomes successfulresolve(result); }}catch(e) { reject(e); }};// Execute the then successful callback
      if (this.promiseState === "fulfilled") {
        setTimeout(() = > {
          callback(onResolved);
        });
      }
      // Execute then failed callback
      if (this.promiseState === "rejected") {
        setTimeout(() = > {
          callback(onRejected);
        });
      }
      // Save success and failure callbacks for PENDING
      if (this.promiseState === "pending") {
        this.callbacks.push({
          onResolved: () = > {
            callback(onResolved);
          },
          onRejected: () = >{ callback(onRejected); }}); }}); }catch(onRejected) {
    return this.then(undefined, onRejected);
  }
  finally(callback) {
    return this.then(
      (value) = > {
        return MyPromise.resolve(callback()).then(() = > value);
      },
      (reason) = > {
        return MyPromise.resolve(callback()).then(() = > {
          throwreason; }); }); }static resolve(value) {
    return new MyPromise((resolve, reject) = > {
      if (value instanceof MyPromise) {
        value.then(
          (res) = > {
            resolve(res);
          },
          (reason) = >{ reject(reason); }); }else{ resolve(value); }}); }static reject(reason) {
    return new MyPromise((resolve, reject) = > {
      reject(reason);
    });
  }
  static all(promises) {
    / / count
    let count = 0;
    let arr = [];
    return new MyPromise((resolve, reject) = > {
      for (let i = 0; i < promises.length; i++) {
        promises[i].then(
          (value) = > {
            // If one Promise succeeds, +1 until all are successful
            count++;
            arr[i] = value;
            if(count === promises.length) { resolve(arr); }},(reason) = >{ reject(reason); }); }}); }static race(promises) {
    return new MyPromise((resolve, reject) = > {
      for (let i = 0; i < promises.length; i++) {
        promises[i].then(
          (value) = > {
            resolve(value);
          },
          (reason) = >{ reject(reason); }); }}); }}Copy the code

Data type judgment

  • Typeof is not an exact typeof object, and null is an exact typeof object
  • You can use the Object. The prototype. ToString implementation
function typeOf(data) {
  return Object.prototype.toString.call(data).slice(8, -1);
}

/ / test
console.log(typeOf(1)); // Number
console.log(typeOf("1")); // String
console.log(typeOf(true)); // Boolean
console.log(typeOf(null)); // Null
console.log(typeOf(undefined)); // Undefined
console.log(typeOf(Symbol(1))); // Symbol
console.log(typeOf({})); // Object
console.log(typeOf([])); // Array
console.log(typeOf(function () {})); // Function
console.log(typeOf(new Date())); // Date
Copy the code

ES5 inheritance (Parasitic combinatorial inheritance)

function People(name) {
    this.name = name;
}

People.prototype.eat = function () {
    console.log(this.name + " is eating");
};

function Stundent(name, age) {
    People.call(this, name);
    this.age = age;
}
Stundent.prototype = Object.create(People.prototype);
// The prototype object has a constructor attribute, which by default points to the prototype object's constructor.
Stundent.prototype.contructor = Stundent;

Stundent.prototype.study = function () {
    console.log(this.name + " is studying");
};

/ / test
let xiaoming = new Stundent("xiaoming".16);
console.log(xiaoming.name); // xiaoming
xiaoming.eat(); // xiaoming is eating
xiaoming.study(); // xiaoming is studying
Copy the code

Get URL parameters

URLSearchParams method

// Create an URLSearchParams instance
const urlSearchParams = new URLSearchParams(window.location.search);
// Convert the key-value pair list to an object
const params = Object.fromEntries(urlSearchParams.entries());
Copy the code

The split method

function getParams(url) {
    const result = {};
    if (url.includes("?")) {
        // Intercept path? The following parameter user=yunmu&age=16
        const str = url.split("?") [1];
        // split into ['user=yunmu', 'age=16']
        const arr = str.split("&");
        // Assign the opposite key value pair after traversal
        arr.forEach((item) = > {
            const key = item.split("=") [0];
            const val = item.split("=") [1];
            result[key] = decodeURIComponent(val); / / decoding
        });
    }
    / / return
    return result;
}

/ / test
const user = getParams("http://www.baidu.com?user=yunmu&age=16");
console.log(user); // {user: 'yunmu', age: '16'}
Copy the code