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