• Vue data bidirectional binding
class Observer { constructor(obj) { this.walk(obj) } walk(obj) { for (let i in obj) { this.defineReactive(obj, i, Object [I])}} array() {const arrayProto = array.prototype Const methodsToPatch = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ] /** * Intercept mutating methods and emit events */ const that = this methodsToPatch.forEach(function Object. DefineProperty (arrayMethods, method, {enumerable:) {const original = arrayProto[method] false, configurable: true, writable: true, value: function mutator(... Args) {const result = original.apply(this, args) console.log(method, 'method operates on array ', args); let inserted switch (method) { case 'push': case 'shift': inserted = args break; case 'splice': inserted = args.slice(2) break; default: break; } if (inserted) that.walk(inserted) return result } }) }) return arrayMethods } defineReactive(obj, key, value) { if (Array.isArray(value)) { value.__proto__ = this.array() } if (value && typeof value === 'object') { This.walk (value)} object.defineProperty (obj, key, {get() {console.log(key, 'read '); Return value}, set(newVal) {console.log(key, 'set '); if (newVal ! == value) { value = newVal return value } } }) } } new Observer(obj)Copy the code
  • Deep copy

  • A shallow copy creates a new object with an exact copy of the original object’s property values. If the property is a primitive type, it copies the value of the primitive type, and if the property is a reference type, it copies the memory address, so if one object changes the address, it affects the other object.

  • A deep copy is a complete copy of an object from the heap, creating a new area of the heap to store the new object, and modifying the new object does not affect the original object.

Function deepClone(obj, Weakmap = new WeakMap()) {return new RegExp(obj)} if (obj instanceof Date) {return new RegExp(obj)} if (obj instanceof Date) { return new Date(obj) } if (typeof obj ! == 'object') {return obj} if (Weakmap.has (obj)) {return weakmap.get(obj)} // Let target = new Constructor () // Let target = reflect.construct (obj.__proto__. Constructor, []) Weakmap.set (obj, Target) / / superior to let target = Object. The prototype. ToString. Call (obj) = = = '[Object Array]'? []:{} for (let i in obj) { if (obj.hasOwnProperty(i)) { if (typeof obj[i] === 'object') { target[i] = deepClone(obj[i], weakmap) } else { target[i] = obj[i] } } } return target }Copy the code
// Flat array
let a = 'Hahaha'

let arr = [1.'2'.'3', a, [4.5[6[7[8]]]]]
function flat(arr) {
  let res = []
  for (let i of arr) {
    Array.isArray(i) ? res.push(... flat(i)) : res.push(i) }return res
}
function flat(arr) {
  while (arr.some(i= > Array.isArray(i))) { arr = [].concat(... arr) }return arr
}
function flat(arr) {
  return arr.reduce((i, j) = > {
    Array.isArray(j) ? i.push(... flat(j)) : i.push(j)return i
  }, [])
}
console.log(flat(arr));
Copy the code
// Publish subscribe mode
let eventEmitter = {
  list: {},
  on: function (events, fn) {
    let _this = this;
    (_this.list[events] || (_this.list[events] = [])).push(fn);
    return _this;
  },
  emit: function (. args) {
    let _this = this;
    let event = [].shift.call(args),
      fns = [..._this.list[event]];
    if(! fns || fns.length ===0) {
      return false;
    }
    fns.forEach(fn= > {
      fn.apply(_this, args)
    })
    return_this; }}function user1(content) {
  console.log('User 1 subscribes to :', content);
};
function user2(content) {
  console.log('User 2 subscribes to :', content);
};
/ / subscribe
eventEmitter.on('article', user1);
eventEmitter.on('article', user2);

eventEmitter.emit('article'.'Javascript publish-subscribe ');
Copy the code
//js concurrent request
class Scheduler {
            constructor(limit) {
                this.limit = limit
                this.number = 0
                this.queue = []
            }
            addTask(timeout, str) {
                this.queue.push([timeout, str])
            }
            start() {
                if (this.number < this.limit&&this.queue.length) {
                    var [timeout, str] = this.queue.shift()
                    this.number++
                    setTimeout(() = > {
                        console.log(str)
                        this.number--
                        this.start()
                    }, timeout * 1000);
                    this.start()
                }
            }
 }
 
 const scheduler = new Scheduler(2)
 scheduler.addTask(1.'1'); // output '1' after 1s
 scheduler.addTask(2.'2'); // output '2' after 2s
 scheduler.addTask(1.'3'); // output '3' after 2s
 scheduler.addTask(1.'4'); // output '4' after 3s
 scheduler.start();

Copy the code
/ / promise handwritten
let PENDING = 'pending'
let FULFILLED = 'fulfilled'
let REJECTED = 'rejected'
class myPromise {
  constructor(excutor) {
    value = ' ';
    reason = ' ';
    status = PENDING;
    queueRes = [];
    queueRej = [];
    excutor(this.reslove, this.reject)
  } 
  reslove = (value) = > {
    if (this.status === PENDING) {
      this.status = FULFILLED
      this.value = value
      while (this.queueRes.length) {
        this.queueRes.shift()(this.value)
      }
    }
  }
  reject = (reason) = > {
    if (this.status === PENDING) {
      this.status = REJECTED
      this.reason = reason
      while (this.queueRej.length) {
        this.queueRej.shift()(this.reason)
      }
    }
  }
  then(onFulfilled, onRejected) {
    // Implement no arguments for THEN
    typeof onFulfilled === 'function' ? onFulfilled : value= > value
    typeof onRejected === 'function' ? onRejected : reason= > reason
    const p2 = new myPromise((resolve, reject) = > {
      if (this.status === FULFILLED) {
        queueMicrotask(() = > {
          const x = onFulfilled(this.value);
          // handle return itself
          if (p2 === x) {
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))}if (x instanceof myPromise) {
            x.then(resolve, reject)
          } else {
            resolve(x)
          }
        })
      } else if (this.status === REJECTED) {
        onRejected(this.reason)
      } else if (this.status === PENDING) {
        this.queueRes.push(onFulfilled);
        this.queueRej.push(onRejected); }})return p2
  }
}

Copy the code
/ / the json across domains
function jsonp(url, callback) {
  const script = document.createElement('script')
  script.src = url
  document.body.appendChild(script)
  return new Promise((reslove, reject) = > {
    window[callback] = function (data) {
      try {
        reslove(data)
      } catch (error) {
        reject(error)
      } finally {
        document.body.removeChild(script)
        delete window[callback]
      }
    }
  })
}
jsonp('./json.json'.'fn').then((res) = > {
  console.log(res)
})
Copy the code
/ / the apply handwriting
Function.prototype.myApply = function (context, args) {
    context = context || window
    args = args ? args : []
    // Add a unique attribute to the context to avoid overwriting the original attribute
    const key = Symbol()
    context[key] = this
    // Call the function with an implicit binding
    constresult = context[key](... args)// Delete the added attribute
    delete context[key]
}

/ / handwritten bind
Function.prototype.myBind = function (context, ... args) {
    const fn = this
    args = args ? args : []
    return function newFn(. newFnArgs) {
        if (this instanceof newFn) {
            return newfn(... args, ... newFnArgs) }return fn.apply(context, [...args,...newFnArgs])
    }
}

Copy the code
// Implement anti-shake
function debounce(fn, delay) {
  let timer = null
  return function (. arg) {
    if (timer) {
      clearTimeout(timer)
    }
    let context = this
    timer = setTimeout(() = > {
      fn.apply(context, arg)
    }, delay)
  }
}
Copy the code
// Implement throttling
function throttle(fn, delay) {
  let timer = null
  return function (. arg) {
    let context = this
    if(! timer) { timer =setTimeout(() = > {
        fn.apply(context, arg)
        timer = null
      }, delay)
    }
  }
}
Copy the code
// Implement the function currie to 1
function add(. args) {
  return args.reduce((a, b) = > {
    return a + b
  })
}
function currying(fn) {
  let args = []
  return function temp(. newVal) {
    if (newVal.length) {
      args = [...args, ...newVal]
      return temp
    } else {
      let val = fn.apply(null, args)
      return val
    }
  }
}
let addCurry = currying(add)
console.log(addCurry(1.2.3) (2.3.6) ())// Implement the function coriolization 2
function add() {
   // On the first execution, an array is defined to store all the parameters
   var _args = Array.prototype.slice.call(arguments);
   // Internally declare a function that uses closure properties to hold _args and collect all parameter values
   var _adder = function() { _args.push(... arguments);return _adder;
   };
   // Take advantage of the toString implicit conversion feature to implicitly convert when finally executed and calculate the final value returned
   _adder.toString = function () {
       return _args.reduce(function (a, b) {
           return a + b;
       });
    }
    console.log(_adder);
   return _adder;
}
let a = add(1.2.3) (2) (3)
console.log(a);
Copy the code
// Turn the array into a tree
let input = [
  { id: 1.val: 'school'.parentId: null },
  { id: 2.val: 'class 1'.parentId: 1 },
  { id: 3.val: Class 2 ' '.parentId: 1 },
  { id: 4.val: Students' 1 '.parentId: 2 },
  { id: 5.val: Students' 2 '.parentId: 3 },
  { id: 6.val: Students' 3 '.parentId: 7 },
  { id: 7.val: 'class 3'.parentId: 1},]/ / 1
function arrToTree(arr) {
  let data = JSON.parse(JSON.stringify(arr))
  let c = data.filter(i= > {
    let arr = data.filter(j= > j['pid'] === i['id'])
    arr.length && (i['children'] = arr)
    return i.pid === 0
  })
  return c[0]}/ / 2
function arrToTree(arr) {
  let dataArr = JSON.parse(JSON.stringify(arr))
  let data = new Map(a)for (let i of dataArr) {
    data.set(i['id'], i)
  }
  for (let i of dataArr) {
    if (i.pid === 0) {
      continue
    }
    let y = data.get(i['pid'])
    y['children']? y['children'].push(i) : y['children'] = [i]
  }
  return data.get(1)}Copy the code
/ / virtual dom
// What a sense of achievement!
/ / sample
let virtualDom = {
  tag: 'div'.props: {
    value: 'the parent div'.color: 'red'
  },
  children: [{tag: 'span'.props: {
        value: 'son level span'.color: 'blue'
      },
      children: [{tag: 'div'.children: 'niubi',},],}, {tag: 'span'.children: 'world'},],}// Structuring
class Element {
  constructor(tag, props, children) {
    this.tag = tag;
    this.props = props;
    this.children = children; }}let createElement = (type, props, children) = > {
  return new Element(type, props, children)
}
// Convert the example
function toCdom(Vdom) {
  if (typeofVdom.children ! = ='object') {
    return createElement(Vdom['tag'], Vdom['props'] || {}, Vdom['children'])}else {
    let arr = []
    let _c = createElement(Vdom['tag'], Vdom['props'] || {}, arr)
    for (let i of Vdom['children']) {
      arr.push(toCdom(i))
    }
    return _c
  }
}
let _c = toCdom(virtualDom)
// Attribute judgment
function setAtr(node, key, value) {
  switch (key) {
    case 'value':
      if (node.tagName.toLowerCase() === 'input' ||
        node.tagName.toLowerCase() === 'textarea'
      ) {
        node.setAttribute(key, value)
      } else {
        node.setAttribute(key, value)
      }
      break;
    case 'style':
      node.style.cssText = value
      break;
    default:
      node.setAttribute(key, value)
      break; }}/ / render function
function render(_c) {
  let ele = document.createElement(_c['tag'])
  if (typeof _c['children']! = ='object') {
    ele.innerText = _c['children']}else {
    for (let i of _c['children']) {
      ele.appendChild(render(i))
    }
  }
  for (let i in _c['props']) {
    setAtr(ele, i, _c['props'][i])
  }
  return ele
}
console.log(render(_c));

Copy the code
// bytes interview question virtual DOM
let virtualDom = {
  tag: 'div'.children: [{tag: 'span'.children: [{tag: 'div'.children: 'niubi',},],}, {tag: 'span'.children: 'world'},],}function renderTOHtml(vdom) {
  let el = document.createElement(vdom.tag)
  if (typeof vdom.children == 'string') {
    vdom.children = [vdom.children]
  }
  vdom.children.forEach((child) = > {
    if (typeof child == 'object') {
      child = renderTOHtml(child)
    } else {
      child = document.createTextNode(child)
    }
    el.appendChild(child)
  })
  return el
}
let realDom = renderTOHtml(virtualDom)
console.log(realDom)
Copy the code
/ / url
function parseQueryString(url) {
  if (typeofurl ! = ='string') throw new Error('invalid url')
  const search = decodeURIComponent(url).split('? ') [1]
  if(! search)return {}
  return search.split('&').reduce((pre, cur) = > {
    console.log(pre, cur)
    const [key, value] = cur.split('=')
    pre[key] = value
    return pre
  }, {})
}
parseQueryString('http://iauto360.cn/index.php?key0=0&key1=1&key2=2')
Copy the code
// Data broker (vUE)
function proxy(vm, target, key) {
  Object.defineProperty(vm, key, {
    get() {
      return vm[target][key]
    },
    set(newVal) {
      vm[target][key] = newVal
    },
  })
}
let vm = {
  data() {
    return {
      title: 'New Language Standard'.list: {
        name: 'liuhuang'.age: '11',},}},}let data = vm.data
data = vm.data = typeof data === 'function' ? data.call(vm) : data || {}
for (let key in data) {
  proxy(vm, 'data', key)
}
console.log(vm.title)

Copy the code