【Javascript】循环,函数,调用栈,闭包,递归

❤️ Author: 老九
☕️ 个人博客:老九的CSDN博客
🙏 个人名言:不可控之事 乐观面对
😍 系列专栏:

函数

  • 形参不需要定义var,函数可以付给一个变量
  • 函数就可以看作一个值,值就要用变量来指向。
  • function在一行的开头时,表达的是函数声明语句,而不是表达式,所以没有求值结果
  • 使用函数声明形式创建的函数function(){ } 它会在所有的代码执行之前就被创建,所以我们在可以函数声明前调用函数,使用函数表达式创建函数不会被声明提前。
  • var的定义也可以实现提前,下面的打印的a是undefined,下面这个会将a的定义提前,但是赋值还是在原来的位置
  • 下面就出现了let变量,let变量在定义前是不能被使用的,定义前的这部分区域也就叫做TDZ(temper dead zone暂时性死区),并且let定义的变量不能重复定义,第三let可以解决闭包问题。
  • 1.let定义的变量在块级作用域内,var是在函数作用域2.let定义的变量不能重复定义3.let定义的变量没有将定义提升,但有TDZ行为,即该作用域内定义完成之前不能使用该变量
    在这里插入图片描述

在这里插入图片描述

补充:我们要注意函数的值传递和引用传递,值传递是不会改变的,而引用传递是可以改变的

作用域

  • 函数中的变量每次调用都会重新创建,定义在任意函数之外的变量称为全局变量(全局作用域),如果在函数中没有用var定义变量,并且全局变量中有一个x,那么就是使用的全局变量的x。
  • 定义在函数中的变量叫做局部作用域
  • 函数还可以在其他函数中定义,这样就会产生多层次的局部作用域

全局作用域自动存在
其他作用域都是通过函数的运行产生的
函数不运行,是不会产生作用域的
函数运行多次,会产生多个作用域
函数运行完后,作用域往往会销毁掉

例子

<script>
  //接受一个n,判断它是否是素数
  var isPrime = function (n) {
    for (var i = 2; i <= Math.sqrt(n); i++) {
      if (n % i == 0) {
        return false
      }
    }
    return true
  }
</script>

<script>
  //判断十进制数字的位数
  debugger
  var digitWidth = function (n) {
    var c = 0
    do {
      var digit = n % 10
      c++
      n = (n - digit) / 10
    } while (n > 0)
    return c
  }
  console.log(digitWidth(10))
</script>

<script>
  var chessBoard = function (size) {
    var a = ''
    var b = ''
    for (var i = 0; i < size; i++) {
      if (i % 2) {
        a += ' '
        b += '#'
      } else {
        a += '#'
        b += ' '
      }
    }
    var result = ''
    for (var i = 0; i < size; i++) {
      if (i % 2) {
        result += a
      } else {
        result += b
      }
      result += '\n'
    }
    return result
  }
  console.log(chessBoard(8))
</script>

  • 这道题注意if括号里的顺序问题
<script>
  var fizzBuzz = function (n) {
    for (var i = 1; i < n; i++) {
      if (i % 3 == 0 && i % 5 == 0) {
        console.log('fizz buzz')
      } else if (i % 5 == 0) {
        console.log('buzz')
      } else if (i % 3 == 0) {
        console.log('fizz')
      } else {
        console.log(i)
      }
    }
  }
</script>
<script>
  //求一个正数的平方根(二分法)
  function sqrt(n) {
    var l = 0
    var r = n
    while (r - l > 0.000001) {
      var m = (l + r) / 2
      if (m * m == n) {
        return m
      } else if (m * m < n) {
        l = m
      } else if (m * m > n) {
        r = m
      }
    }
    return (l + r) / 2
  }
</script>

<script>
  //判断一个数是不是水仙花数
  function digitWidth(n) {
    var width = 0
    do {
      var digit = n % 10
      n = (n - digit) / 10
      width++
    } while (n > 0)
    return width
  }
  function power(x, n) {
    var exp = 1
    for (var i = 0; i < n; i++) {
      exp *= x
    }
    return exp
  }
  function isNarcissistic(n) {
    var width = digitWidth(n)
    var m = n
    var sum = 0

    do {
      var digit = m % 10
      sum += power(digit, width)
      m = (m - digit) / 10
    } while (m > 0)

    if (sum == n) {
      return true
    } else {
      return false
    }
  }

  for (var i = 1; i < 10000; i++) {
    if (isNarcissistic(i)) {
      console.log(i)
    }
  }
</script>

<script>
  //判断一个数是否是回文数字
  function isPalindrow(n) {
    var m = n
    var revert = 0
    while (m > 0) {
      var digit = m % 10
      revert = revert * 10 + digit
      m = (m - digit) / 10
    }
    if (revert == n) {
      return true
    } else {
      return false
    }
  }
</script>

<script>
  //判断一个数是否是完全数(一个数等于因式之和)
  function isCompleteNumber(n) {
    var sum = 1
    for (var i = 2; i <= Math.sqrt(n); i++) {
      if (n % i == 0) {
        var j = n / i
        if (i == j) {
          sum += i
        } else {
          sum += i + j
        }
      }
    }
    return n == sum
  }
</script>

可选参数

  • 如果函数参数少写了一个实参,那么那个实参就式undefined类型,浏览器就自动补全另一个参数
<script>
  function a() {
    console.log(arguments[0], arguments[5])
  }
  a(1, 2, 3, 4, 5, 6, 7, 8, 9)
</script>

  • 通过arguments可以取出函数参数的值,arguments就看作一个数组即可
  • js还可以设置参数的默认值,这样在调用函数的时候可以使用默认参数
<script>
  function power(a, n = 2) {
    var result = 1
    for (var i = 1; i <= n; i++) {
      result *= a
    }
    return result
  }

  console.log(power(3))
</script>

闭包

  • JavaScript中一个函数,如果访问了外层作用域的变量,那么它是一个闭包;
  • 一直没有销毁的作用域我们就叫做闭包,在js中返回一个函数,函数内用到了外层函数的变量,所以内层函数在,外层函数的变量就在,这样作用域就不会被销毁,形成了闭包
<script>
    function makeAdder(count){
      return function(num){
        return count + num
      }
    }

    let add10  = makeAdder(10)
    console.log(add10(5));
</script>

  • 正常执行完毕之后,add10函数的内存就会被释放,但这个函数中内部有函数引用了外部函数的作用域,所以他就不会被释放掉

闭包导致的内存泄漏

  • 闭包导致的内存泄漏,就说引用链中的所有对象都是无法释放的
  • 如果我们想解决这个问题,我们将add10设置为null,就不会对这个函数对象有引用了,在GC的下一次检测中,它就会被销毁

属性优化

当形成闭包之后,使用外层作用域的不会被销毁,但是没有使用到的变量,就会被优化掉,注意
在这里插入图片描述

递归

  • 结束条件,在该条件中,不递归
  • 调用自己的时候认为自己已经被正确实现了,问题的更小规模可以直接调用自己求解
  • 调用自身的时候一定要传入更小规模的参数/或者是更接近非递归条件的参数
<script>
  //输入n个数并倒叙输出:输入1个数a;输入n-1个数并倒叙输出;输出a
  function inputAndReverseOutput(n){
    if(n == 0){
      return
    }
    var a = prompt()
    inputAndReverseOutput(n-1)
    console.log(a)
  }
</script>

<script>
  //斐波那契额数列
  function fibonacci(n) {
    if (n == 1 || n == 2) {
      return 1
    } else {
      return fibonacci(n - 1) + fibonacci(n - 2)
    }
  }
  var n = Number(prompt())
  for (var i = 1; i <= n; i++) {
    console.log(fibonacci(i))
  }
</script>

<script>
  //汉诺塔,将放置于start位的顶部的n个盘移动到end位
  function hanoi(n, start, end) {
    if (n == 1) {
      console.log(start, '->', end)
      return
    }
    var mid = 6 - start - end//计算出中转位的编号
    hanoi(n - 1, start, mid)//将摆放在起点位置顶部的n-1个盘移到中转位上
    console.log(start, '->', end)//将摆放在起点位置唯一的一个盘移到终点位上
    haooi(n - 1, mid, end)//将摆放在中转位顶部的n-1个盘移到终点位上
  }
</script>

———————————————— ————————
♥♥♥码字不易,大家的支持就是我坚持下去的动力♥♥♥
版权声明:本文为CSDN博主「亚太地区百大最帅面孔第101名」的原创文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李小浦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值