函数

2020/01/16 function

函数

这里是一些关于函数的使用,在某些场合之下很实用

奇怪的函数

自动执行,形成闭包

let x = 5
!function next(index){
if(x>0){
  console.log(index)
  next(--x)
}else{
  console.log('函数读取完了')
}
}(x)

深度优先遍历

举一个不巧当的例子,循环一个数组,打印出出数组对象里面每一项的的键和值;在对象的项数和深度不确定的时候,使用循环一层一层找。虽然能够实现树形结构从上往下一层一层打印,但是有一个很不好的地方就是循环,时间空间复杂度增长

反正大概思路就是这样的

let list = [{name:'sunseeker',info:{age:18,like:{people:'secret'}}},{add:'hunan'}]

const isObject = obj=>Object.prototype.toString.call(obj)==='[object Object]'

function depth(list){
  list.forEach(item=>{
    if(isObject(item)){
      next(item,'')
    }
  })
}
 function next(item,val){
   if(!isObject(item)) {
      console.log(item);
    }
    for(let i in item){
      if(isObject(item)){
        console.log(i);
        next(item[i],i)
      }
    }
 }

广度优先

先把第一层的第一个拿出来,遍历的时候,只要发现是数组,就往数组后面加,不做遍历。大概思路就是这样子

function breadth(list){
  let arr = list
  while(arr.length>0){
     let current = arr.shift()
     console.log(current)
     if(Array.isArray(current)){
     current.forEach(item=>{
       arr.push(item)
     })
     }
  }
}
const list = [[1],[2,[3,[4]]],[5],[6]]
breadth(list)


const fs = require('fs')
const path = require('path')

function wide(dir) {
 let arr = [dir]
 while (arr.length > 0) {
   let current = arr.shift()
   console.log(current)
   let stat = fs.statSync(current)
   if (stat.isDirectory()) {
     let files = fs.readdirSync(current)
     files.forEach(item => {
       arr.push(path.join(current, item))
     })
   }
 }
}
wide('src')

回调函数的作用

function preorder(dir, callback) {
  console.log(dir)
  fs.readdir(dir, (err, files) => {
    !function next(i) {
      console.log(i, 'i 有哪些值');
      if (i >= files.length) return callback()//这里有两个作用,第一是下一次遍历和全部遍历完,两种情况
      let child = path.join(dir, files[i])
      fs.stat(child, (err, item) => {
        if (item.isDirectory()) {
          preorder(child, () => next(i + 1))
        } else {
          console.log(child);
          next(i + 1)
        }
      })
    }(0)
  })
}
preorder('src', (data) => {
  console.log('裙摆')
})

箭头函数

箭头函数没有自己的 this 也没有 prototype 也没有 arguments 无法创建箭头函数的实例

let fn = () => {
    console.log(this);
    console.log(arguments);//Uncaught ReferenceError: arguments is not defined
}
console.log(fn.prototype);//undefined
fn();
new fn();

柯里化

本质上是降低通用性,提高适用性,柯里化就是层层包裹原函数,直到参数符合我们需要的为止,在执行,否者一直不执行

第一版

  function sub_curry(fn) {
    const argus = [].slice.call(arguments, 1)
    return function() {  // 不能用箭头函数,因为箭头函数没有arguments
      debugger
      const newArgus = argus.concat([].slice.call(arguments))
      return fn.apply(this,newArgus)
    }
  }

第二版,在第一版的基础上,只有函数的参数满足需要传入的参数,才会执行函数,否者就会一直等待

function curry(fn,length){
  length = length||fn.length// 计算函数参数的个数,知道参数个数满足条件,才会执行函数
  let slice = Array.prototype.slice
  return function(){
    if(arguments.length < length){
      let combined = [fn].concat(slice.call(arguments))// 把当前函数和函数的个数作为参数继续传递
      curry(sub_curry.apply(this.combined),length - arguments.length)
    } else {
      return fn.apply(this, arguments); // 这里是为了,把传给原函数的参数解构,也可以使用下面的一种实现方式,这里并没有this的问题,单单只是为了参数解构
      <!-- return fn(...arguments); -->
    }
  }
}

JavaScript 专题之函数柯里化


有时候,虽然素未谋面。却已相识很久,很微妙也很知足。在逝去的岁月里,我们在某一刻,共同经历着一样的情愫。

如果喜欢我的话,我们可以互相关注,相互学习的哟!互相鼓励,你的关注是我最大的动力来源

sunseekers

Search

    Table of Contents