- 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 function
true
Put 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, return
undefined
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