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面向对象之二 命名空间
Feb 08 Javascript
javascript作用域容易记错的两个地方分析
Jun 22 Javascript
node.js操作mongodb学习小结
Apr 25 Javascript
jQuery遍历DOM的父级元素、子级元素和同级元素的方法总结
Jul 07 Javascript
jquery attr()设置和获取属性值实例教程
Sep 25 Javascript
js实现上传文件添加和删除文件选择框
Oct 24 Javascript
基于JavaScript实现百度搜索框效果
Jun 28 Javascript
vue 虚拟dom的patch源码分析
Mar 01 Javascript
element-ui upload组件多文件上传的示例代码
Oct 17 Javascript
node和vue实现商城用户地址模块
Dec 05 Javascript
JS手写一个自定义Promise操作示例
Mar 16 Javascript
javascript使用正则表达式实现注册登入校验
Sep 23 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
php数组函数序列之asort() - 对数组的元素值进行升序排序,保持索引关系
2011/11/02 PHP
PHP时间戳与日期之间转换的实例介绍
2013/04/19 PHP
ThinkPHP的URL重写问题
2014/06/22 PHP
php socket实现的聊天室代码分享
2014/08/16 PHP
php基于curl重写file_get_contents函数实例
2016/11/08 PHP
PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】
2019/05/13 PHP
prototype与jquery下Ajax实现的差别
2009/09/13 Javascript
关于递归运算的顺序测试代码
2011/11/30 Javascript
jquery实现人性化的有选择性禁用鼠标右键
2014/06/30 Javascript
使用jquery获取url及url参数的简单实例
2016/06/14 Javascript
浅谈jQuery before和insertBefore的区别
2016/12/04 Javascript
vue bootstrap小例子一枚
2017/06/09 Javascript
浅析为什么a=&quot;abc&quot; 不等于 a=new String(&quot;abc&quot;)
2017/10/25 Javascript
jquery写出PC端轮播图实例
2018/01/26 jQuery
vue axios请求拦截实例代码
2018/03/29 Javascript
React diff算法的实现示例
2018/04/20 Javascript
vue.js路由mode配置之去掉url上默认的#方法
2019/11/01 Javascript
javascript实现一款好看的秒表计时器
2020/09/05 Javascript
Python删除指定目录下过期文件的2个脚本分享
2014/04/10 Python
Python的ORM框架SQLObject入门实例
2014/04/28 Python
python实现颜色空间转换程序(Tkinter)
2015/12/31 Python
Python数据库的连接实现方法与注意事项
2016/02/27 Python
django 2.0更新的10条注意事项总结
2018/01/05 Python
解决tensorflow1.x版本加载saver.restore目录报错的问题
2018/07/26 Python
Python 最大概率法进行汉语切分的方法
2018/12/14 Python
TensorFlow实现模型断点训练,checkpoint模型载入方式
2020/05/26 Python
HTML5: Web 标准最巨大的飞跃
2008/10/17 HTML / CSS
惠普加拿大在线商店:HP加拿大
2017/09/15 全球购物
华为慧通笔试题
2016/04/22 面试题
do you have any Best Practice for testing
2016/06/04 面试题
新农村建设标语
2014/06/24 职场文书
工作业绩不及格检讨书
2014/10/28 职场文书
2015年七年级班主任工作总结
2015/05/21 职场文书
2015年企业员工工作总结范文
2015/05/21 职场文书
如何让2019年上半年的工作总结更出色!
2019/07/01 职场文书
python中24小时制转换为12小时制的方法
2021/06/18 Python