JavaScript arguments.callee作用及替换方案详解


Posted in Javascript onSeptember 02, 2020

一、arguments.callee的作用:返回正被执行的 Function 对象

arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文,这有利于匿名函数的递归或者保证函数的封装性。

请看下面这个非常经典的阶乘函数

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 是个很昂贵的操作,因为它是个很大的对象,每次递归调用时都需要重新创建。影响现代浏览器的性能,还会影响闭包。

不能用怎么办?

递归时用到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 被弃用了。怎么办,其实很简单,给内部函数一个名字即可(当函数被调用时,它的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]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
给Javascript数组插入一条记录的代码
Aug 30 Javascript
基于jquery完美拖拽,可返回拖动轨迹
Mar 29 Javascript
对jQuery的事件绑定的一些思考(补充)
Apr 20 Javascript
jQuery 关于伪类选择符的使用说明
Apr 24 Javascript
React.js入门实例教程之创建hello world 的5种方式
May 11 Javascript
深入理解JavaScript继承的多种方式和优缺点
May 12 Javascript
利用JS制作万年历的方法
Aug 16 Javascript
vue+springboot实现项目的CORS跨域请求
Sep 05 Javascript
Django模板继承 extend标签实例代码详解
May 16 Javascript
vue 实现tab切换保持数据状态
Jul 21 Javascript
ES6 解构赋值的原理及运用
May 25 Javascript
JavaScript Array.flat()函数用法解析
Sep 02 #Javascript
通过实例解析JavaScript常用排序算法
Sep 02 #Javascript
手把手教你实现 Promise的使用方法
Sep 02 #Javascript
如何基于jQuery实现五角星评分
Sep 02 #jQuery
在vscode 中设置 vue模板内容的方法
Sep 02 #Javascript
JavaScript array常用方法代码实例详解
Sep 02 #Javascript
Vue前端判断数据对象是否为空的实例
Sep 02 #Javascript
You might like
德生S2000收音机更换“钕铁硼”全频扬声器
2021/03/02 无线电
要会喝咖啡也要会知道咖啡豆
2021/03/03 咖啡文化
php记录代码执行时间(实现代码)
2013/07/05 PHP
php float不四舍五入截取浮点型字符串方法总结
2013/10/28 PHP
php用正则表达式匹配中文实例详解
2013/11/06 PHP
PHP批量获取网页中所有固定种子链接的方法
2016/11/18 PHP
php微信开发之图片回复功能
2018/06/14 PHP
javascript中with()方法的语法格式及使用
2014/08/04 Javascript
jQuery中hasClass()方法用法实例
2015/01/06 Javascript
jQuery性能优化技巧分析
2015/02/20 Javascript
JavaScript实现带标题的图片轮播特效
2015/05/20 Javascript
JavaScript对象学习小结
2015/09/02 Javascript
分享12个非常实用的JavaScript小技巧
2016/05/11 Javascript
JS实现含有中文字符串的友好截取功能分析
2017/03/13 Javascript
bootstrap daterangepicker双日历时间段选择控件详解
2017/06/15 Javascript
11行JS代码制作二维码生成功能
2018/03/09 Javascript
详解js跨域请求的两种方式,支持post请求
2018/05/05 Javascript
vue实现动态显示与隐藏底部导航的方法分析
2019/02/11 Javascript
详解nuxt 微信公众号支付遇到的问题与解决
2019/08/26 Javascript
微信小程序使用 vant Dialog组件的正确方式
2020/02/21 Javascript
[00:36]DOTA2勇士令状莱恩声望物品——冥晶之厄展示
2018/05/25 DOTA
利用soaplib搭建webservice详细步骤和实例代码
2013/11/20 Python
详解Python中open()函数指定文件打开方式的用法
2016/06/04 Python
PyCharm使用教程之搭建Python开发环境
2016/06/07 Python
详解Django项目中模板标签及模板的继承与引用(网站中快速布置广告)
2019/03/27 Python
对django后台admin下拉框进行过滤的实例
2019/07/26 Python
在PyCharm的 Terminal(终端)切换Python版本的方法
2019/08/02 Python
python 进程 进程池 进程间通信实现解析
2019/08/23 Python
Python 代码调试技巧示例代码
2020/08/11 Python
基于django和dropzone.js实现上传文件
2020/11/24 Python
python给list排序的简单方法
2020/12/10 Python
使用HTML5中的contentEditable来将多行文本自动增高
2016/03/01 HTML / CSS
拖鞋店创业计划书
2014/01/15 职场文书
理工类毕业自我鉴定
2014/02/20 职场文书
给校长的建议书500字
2014/05/15 职场文书
浅谈如何提高PHP代码质量之端到端集成测试
2021/05/28 PHP