Array.prototype.map 1 2 3  [1 ,2 ]._map (i  =>  i * 2 ) [2 ,4 ]
 
mdn 里的 map 
1 2 map (function (element, index, array ) {  }, thisArg)
 
1 2 3 4 5 6 7 8 9 10 11 Array .prototype  ._map  = function  (fn ) {     if  (typeof  fn !== 'function' ) return      const  array = this      const  newArray = []     for  (let  i = 0 ; i < array.length ; i++) {                  newArray.push (fn.call (arguments [1 ], array[i], i, array))     }     return  newArray }
 
Array.prototype.filter 和 map 没什么区别
1 2 3  [1 ,2 ]._filter (i  =>  i>1 ) [2 ]
 
1 2 3 4 5 6 7 8 9 10 11 Array .prototype  ._filter  = function (fn ) {     if  (typeof  fn !== 'function' ) return      const  array = this      const  newArray = []     for  (let  i = 0 ; i < array.length ; i++) {         if  (fn.call (arguments [1 ], array[i], i, array)) {             newArray.push (array[i])         }     }     return  newArray }
 
Array.prototype.reduce 1 2 3  [1 ,2 ,3 ]._reduce ((left, right ) =>  left + right)6 
 
mdn 
1 reduce (function (previousValue, currentValue, currentIndex, array ) {  }, initialValue)
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Array .prototype  ._reduce  = function (fn ) {     if  (typeof  fn !== 'function' ) return      const  array = this      let  flag     if  (arguments [1 ]) {         preValue = arguments [1 ]         flag = true      } else  {         preValue = array[0 ]         flag = false      }     for  (let  i = flag ? 0  : 1 ; i < array.length ; i++) {         preValue = fn (preValue, array[i], i, array)     }     return  preValue }
 
Object.create 创建一个新对象,使用现有的对象来作为新创建对象的原型
1 2 3 4 5 6 7 const  _objectCreate  = proto => {     if  (typeof  proto !== 'object'  || proto === null ) return      function  fn ( ) {}     fn.prototype   = proto     return  new  fn () }
 
Function.prototype.call 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Function .prototype  .myCall  = function (context ) {     let  context = context || window           context.fn  = this ;     let  args = [...arguments ].slice (1 )          let  result = context.fn (...args)          delete  context.fn      return  result }
 
Function.prototype.bind 1 2 3 4 5 6 7 8 9 10 11 12 13 Function .prototype  .myBind  = function (context ) {     if  (typeof  this  !== 'function' ) throw  new  TypeError ('Error' )     let  fn = this      let  args = [...arguments ].slice (1 )          return  function  F ( ) {                  if  (this  instanceof  F) {             return  new  fn (...args, ...arguments )         }         return  fn.apply (context, [...args, ...arguments ])     } }
 
new 实例化 1 2 3 4 5 6 7 8 9 function  Person (name, age ) {     this .name  = name;     this .age  = age; }Person .prototype  .getName  = function ( ) {     return  this .name  }let  p = _new (Person , "sillywa" , 23 )
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function  _new ( ) {          let  obj = {}               let  [Con , ...args] = arguments      obj.__proto__  = Con .prototype                let  res = Con .call (obj, ...args)               return  res instanceof  Object  ? res : obj }
 
instanceof 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function  myInstanceof (left, right ) {   let  p = Object .getPrototypeOf (left)   let  prototype = right.prototype    while  (p) {     if  (p === prototype) return  true      p = Object .getPrototypeOf (p)   }   return  false  }console .log (myInstanceof (5 , Number ));console .log (myInstanceof (5 , Object ));console .log (myInstanceof (5 , String ));console .log (5  instanceof  Number );console .log (5  instanceof  Object );console .log (new  Number (5 ) instanceof  Number );console .log (new  Number (5 ) instanceof  Object );
 
==扁平数据结构转Tree== 总的来说就两步:
创建当前 id 的 map
 
将当前 id 的 map 放入 pid 的 map 的 children 中
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 let  arr = [   {id : 1 , name : '部门1' , pid : 0 },   {id : 2 , name : '部门2' , pid : 1 },   {id : 3 , name : '部门3' , pid : 1 },   {id : 4 , name : '部门4' , pid : 3 },   {id : 5 , name : '部门5' , pid : 4 }, ]function  arrayToTree (arr ) {   const  result = []   const  map = {}   arr.forEach ((item, index ) =>  {     const  { id, pid } = item               if  (!map[id]) {       map[id] = {         children : [],       }     }          map[id] = {       ...item,       children : map[id]['children' ]     }     const  treeItem = map[id]          if  (pid === 0 ) {       result.push (treeItem)     } else  {       if  (!map[pid]) {         map[pid] = {           children : []         }       }       map[pid].children .push (treeItem)     }   })   return  result }
 
只执行一次的 once 实现一个 once 函数,记忆返回结果只执行一次
类似于 lodash.once
1 2 3 4 5 6 7 8 9 10 const  f  = (x ) => x;const  onceF = once (f);console .log (onceF (3 ))console .log (onceF (100 ))
 
1 2 3 4 5 6 7 8 9 10 11 function  once (f ) {   let  result   let  flag = false    return  (...args ) =>  {     if  (flag) return  result     result = f (...args)     flag = true      return  result   } }
 
无限累加的 sum 参数无限,调用次数无限
1 2 3 4 5 sum (1 , 2 , 3 ).valueOf (); sum (2 , 3 )(2 , 4 ).valueOf (); sum (1 )(2 )(3 )(4 ).valueOf (); sum (2 )(4 , 1 )(2 ).valueOf (); sum (1 )(2 )(3 )(4 )(5 )(6 ).valueOf (); 
 
1 2 3 4 5 function  sum (...args ) {   const  f  = (...rest ) => sum (...args, ...rest)   f.valueOf  = () =>  args.reduce ((x, y ) =>  x + y, 0 )   return  f }
 
用于函数合成的 compose 实现一个 compose 函数,进行函数合成,比如 redux 中的 compose,react 高阶组件连续调用时的 compose
1 2 3 4 5 6 const  add10  = (x ) => x + 10 ;const  mul10  = (x ) => x * 10 ;const  add100  = (x ) => x + 100 ;compose (add10, mul10, add100)(10 );
 
错误的(我最初写的) 
1 2 3 4 5 6 7 8 9 10 function  compose ( ) {   const  funcs = Array .from (arguments ).reverse ()   const  n = funcs.length    return  (num ) =>  {     for  (let  i = 0 ; i < n; i++) {       num = funcs[i](num)     }     return  num   } }
 
显然没有考虑函数的参数个数与返回值个数的问题,只用了一个num,默认一个参数了。
正确版 
利用 array.reduce  函数
上一次的返回结果会作为下一次的参数,a 为上一个值,b为当前值
1 2 3 function  compose (...funcs ) {     return  funcs.reduce ((a,b ) =>  (...args ) =>  a (b (...args))) }
 
是一个正向的,从左向右递推的过程。
如果 a 是函数,b是参数,就是 (a,b) => a(b)
但是要考虑到 b 也是函数,所以 b 也得调用一下,得到返回值后再作为 a 的参数传入
格式化时间 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function  dateFormat (date ) {   let  year = date.getFullYear ()   let  month = showTime (date.getMonth () + 1 )   let  day = showTime (date.getDay ())   let  hours = showTime (date.getHours ())   let  minutes = showTime (date.getMinutes ())   let  second = showTime (date.getSeconds ())   const  str = `${year} -${month} -${day} -${hours} -${minutes} -${second} `    return  str }function  showTime (t ) {   let  time   time = t > 10  ? t : '0'  + t   return  time }console .log (dateFormat (new  Date (Date .now ())))