Shallow copy
let obj = { a: 1, b: 2 }
Object.assign({},obj) // This contains the original Object class Symbol attribute processing, for in does not
Keys (obj) cannot get symbol
If you want to complete the needs of the collocation of the Object. GetOwnPropertySymbols (obj) / / special Symbols attributes
Object. GetOwnpropertySymbols (obj) special symbol
function shallowClone(obj){
let type = Object.prototype.toString.call(obj)
let contor = obj.constructor;
if(type === '[object Symbol]' || type === '[object Bigint]') return Object(obj);
if(type === '[object RegExp]' || type === '[object Date]') return new contor(obj)
if(type === '[object Error]') return new contor(obj.message)
if(type === '[object Function]') {
return function(){
return obj.call(this. arguments) } }if(type === '[object Array]' || type === '[object Object]') {// This contains the Symbol attribute,
return type === '[object Array]'? [...obj] : {... obj} }return obj
}
Copy the code
Deep copy
function deepClone(obj,cache = new Set(a)){
let type = Object.prototype.toString.call(obj);
let contor = obj.constructor;
// If it is not an array or an object, just copy it
if(type ! = ='[object Array]'|| type ! = ='[object Object]') return shallowClone(obj);
// To prevent infinite nesting dolls
if(cache.has(obj)) return obj;
cache.add(obj)
let keys = [
...Object.keys(obj),
...Object.getOwnPropertySymbols(obj)
]
let result = new contor();
keys.forEach(itm= > {
result[key] = deepClone(obj[key], cache)
})
return result
}
Copy the code
Class arrays are converted to arrays
- Array.prototype.slice.call(arguments)
- Array.from(document.querySelectorAll(‘div’))
- […document.querySelectorAll(‘div’)]
- Array.prototype.concat.apply([],arguments)
- [].forEach.call(arguments,(itm) => { console.log(itm) })
Array methods
forEach
MDN: developer.mozilla.org/zh-CN/docs/…
Array.prototype.forEach = function(callback,context){
let self = this;
i = 0;
len = self.length;
context = context === null ? window : context;
for(; i<len; i++){typeof callback === 'function' ? callback.call(context,self[i]) : null}}Copy the code
for in
When you use “for in”, it’s best to use “obj. HasOwnProper” to tell if it’s a private property of obj
Poor performance because it iterates through all enumerable attributes (including the prototype chain)
for of
Iterator returns an object containing the next method, which in turn returns an object with two attributes: value and done: whether the traversal is complete
For example,
let arr = [1.2.3.4.5]
for(let key ofArr){} is equivalent to obj[Symbol.iterator] = function(){
let self = this;
idx = 0;
return {
// Include the next method, execute it
// done:false or true done or not done
// value: indicates the value of each time
next(){
// Finally greater than the maximum index
if(idx > self.length - 1) {return {
done: true.value: undefined}}return {
done: false.value: self[idx++]
}
}
}
}
// let itor = arr[Symbol.iterator]()
// itor.next()
Copy the code
How can objects be traversed through for of
let ab = {
name: 'brush'.age: '18'
}
function createSymbolIterator(obj){
let arr = Object.entries(obj);
let idx = 0;
return {
next(){
if(idx > self.length - 1) {return {
done: true.value: undefined}}return {
done: false.value: arr[idx++]
}
}
}
}
ab[Symbol.iterator] = function(){
return createSymbolIterator(ab)
}
for(let key of ab){
console.log(key)
}
Copy the code
To realize the call
Eval method: developer.mozilla.org/zh-CN/docs/…
Function.prototype.call_ = function (obj) {
// Check whether it is null or undefined, and consider passing arguments that are not objects
// The purpose is to prevent errors
obj = obj ? Object(obj) : window;
let args = [];
// Note that I starts at 1
let len = arguments.length;
for (var i = 1, i < len; i++) {
args.push("arguments[" + i + "]");
};
obj.fn = this; // This is the function fn
eval("obj.fn(" + args + ")"); / / execution fn
delete obj.fn; / / delete the fn
};
Copy the code
To realize the bind
Function.prototype.bind=function (context,... params){
let self = this;
return function proxy(args){
self.apply(context,params.concat(args))
}
}
Copy the code
Use setTimeout to implement setInterval
Difficulty: How to save the value after multiple updates of setTimeout
const utils = (
function () {
let interVal = 0;
let interObj = {};
var _setInterval = function (fn,t){
var newInterVal = ++interVal;
function next(){
interObj[newInterVal] = setTimeout(() = > {
fn();
next();
},t)
}
next();
return newInterVal;
}
var _clearInterval = function (id){
clearTimeout(interObj[id])
}
return {setInterval: _setInterval,clearInterval: _clearInterval}
}
)()
Copy the code