JavaScript中arguments.callee属性的作用与替换方案

 更新时间:2022年06月24日 09:44:20   作者:小旭2021  
这篇文章介绍了JavaScript中arguments.callee属性的作用与替换方案,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

arguments.callee的作用

在函数内部,有两个特殊的对象:arguments 和 this。其中, arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数。 请看下面这个非常经典的阶乘函数

function factorial(num){   
   if (num <=1) {        
      return 1;    
   } else {        
   return num * factorial(num-1)    
   }
}

定义阶乘函数一般都要用到递归算法;如上面的代码所示,在函数有名字,而且名字以后也不会变 的情况下,这样定义没有问题。但问题是这个函数的执行与函数名 factorial 紧紧耦合在了一起。为 了消除这种紧密耦合的现象,可以像下面这样使用 arguments.callee

function factorial(num){   
   if (num <=1) {        
      return 1;    
   } else {        
   return num * arguments.callee(num-1);
   }
}

在这个重写后的 factorial()函数的函数体内,没有再引用函数名 factorial。这样,无论引用 函数时使用的是什么名字,都可以保证正常完成递归调用。例如

function factorial(num){
          if(num <= 1){
              return 1;
          }else{
              return num * arguments.callee(num-1);
          }
      }
      var trueFactorial = factorial;
      alert(trueFactorial(5));    //120   
 
 
      factorial = function() {
          return 0;
      }               
      alert(trueFactorial(5));// 120 如果没有使用arguments.callee,将返回0

在此,变量 trueFactorial 获得了 factorial 的值,实际上是在另一个位置上保存了一个函数 的指针。然后,我们又将一个简单地返回 0的函数赋值给 factorial 变量。如果像原来的 factorial() 那样不使用 arguments.callee,调用 trueFactorial()就会返回 0。可是,在解除了函数体内的代 码与函数名的耦合状态之后,trueFactorial()仍然能够正常地计算阶乘;至于 factorial(),它现 在只是一个返回 0的函数。

arguments.callee的替换方案

现在已经不推荐使用arguments.callee();

原因:访问 arguments 是个很昂贵的操作,因为它是个很大的对象,每次递归调用时都需要重新创建。影响现代浏览器的性能,还会影响闭包。

不能用怎么办?

像第三段中的例子,重写 factorial()方法导致trueFactorial()结果不在预期。是为了演示而做的。平时写代码应该避免。

递归时用到arguments.callee()是常见的事情,比如

一道面试题。接受参数n=5,不用for循环输出数组【1,2,3,4,5】

这用递归的思路,配合arguments.callee,代码如下

function show(n) {
    var arr = [];
    return (function () {
        arr.unshift(n);
        n--;
        if (n != 0) {
            arguments.callee();
        }
        return arr;
    })()
}
show(5)//[1,2,3,4,5]

现在arguments.callee 被弃用了。怎么办,其实很简单,给内部函数一个名字即可

function show(n) {
    var arr = [];
    return (function fn() {
        arr.unshift(n);
        n--;
        if (n != 0) {
            fn();
        }
        return arr;
 
    })()
}
show(5)//[1,2,3,4,5]

斐波那契递归算法替换

function factorial(num) {
      if (num <= 1) {
        return 1
      }
      var fac = 1
      return (function fn() {
        fac *= num
        num--
        if (num != 0) {
          fn()
        }
        return fac
      })()
    }
    factorial(5) // 120

到此这篇关于JavaScript中arguments.callee属性的作用与替换方案的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 纯JS实现本地图片预览的方法

    纯JS实现本地图片预览的方法

    这篇文章主要介绍了纯JS实现本地图片预览的方法,基于javascript插件实现本地图片预览功能,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • 关于使用js算总价的问题

    关于使用js算总价的问题

    下面小编就为大家带来一篇关于使用js算总价的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • JavaScript中防抖和节流的区别及适用场景

    JavaScript中防抖和节流的区别及适用场景

    这篇文章主要介绍了JavaScript中防抖和节流的区别及适用场景,文章通过围绕主题的相关资料展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • JavaScript中cookie工具函数封装的示例代码

    JavaScript中cookie工具函数封装的示例代码

    这篇文章给大家主要介绍了JavaScript中cookie工具函数的封装,文中给出了详细的实现步骤和示例代码,相信会对大家的理解很有帮助,有需要的朋友们下面来一起看看吧。
    2016-10-10
  • js实现车辆管理系统

    js实现车辆管理系统

    这篇文章主要为大家详细介绍了js实现车辆管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • JS和jQuery使用submit方法无法提交表单的原因分析及解决办法

    JS和jQuery使用submit方法无法提交表单的原因分析及解决办法

    这篇文章主要介绍了JS和jQuery使用submit方法无法提交表单的原因分析及解决办法的相关资料,需要的朋友可以参考下
    2016-05-05
  • javascript每日必学之条件分支

    javascript每日必学之条件分支

    javascript每日必学之条件分支,本文的主要内容就是介绍的逻辑条件分支,循环,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • js里面的变量范围分享

    js里面的变量范围分享

    今天写一个滑动自动加载的功能的时候,遇到了切换就发现加载完毕的情况,查看了下发现可能是js的全局变量和局部变量的问题,自己测试了下,果不其然,下面分享下
    2020-07-07
  • JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例

    JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例

    这篇文章主要介绍了JS实现鼠标拖拽盒子移动及右键点击盒子消失效果,涉及javascript事件响应及页面元素属性动态操作相关实现技巧,需要的朋友可以参考下
    2019-01-01
  • uni-app和web-view页面相互传参方法实例

    uni-app和web-view页面相互传参方法实例

    web-view是一个web浏览器组件,可以用来承载网页的容器,会自动铺满整个页面,下面这篇文章主要给大家介绍了关于uni-app和web-view页面相互传参的相关资料,需要的朋友可以参考下
    2023-06-06

最新评论