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 相关文章推荐
jQuery 打造动态渐变按钮 详细图文教程
Apr 25 Javascript
jquery插件validate验证的小例子
May 08 Javascript
jquery 追加tr和删除tr示例代码
Sep 12 Javascript
用unescape反编码得出汉字示例
Apr 24 Javascript
js打开windows上的可执行文件示例
May 27 Javascript
javascript常用代码段搜集
Dec 04 Javascript
基于JS如何实现类似QQ好友头像hover时显示资料卡的效果(推荐)
Jun 09 Javascript
Bootstrap前端开发案例二
Jun 17 Javascript
js事件驱动机制 浏览器兼容处理方法
Jul 23 Javascript
javascript之with的使用(阿里云、淘宝使用代码分析)
Oct 11 Javascript
小程序实现带年月选取效果的日历
Jun 27 Javascript
vue 检测用户上传图片宽高的方法
Feb 06 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
超神学院:天使彦公认最美的三个视角,网友:我的天使快下凡吧!
2020/03/02 国漫
用PHP生成静态HTML速度快类库
2007/03/18 PHP
php 遍历数据表数据并列表横向排列的代码
2009/09/05 PHP
用来解析.htpasswd文件的PHP类
2012/09/05 PHP
浅析php中jsonp的跨域实例
2013/06/21 PHP
php版微信小店调用api示例代码
2016/11/12 PHP
PHP实现json_decode不转义中文的方法
2017/05/20 PHP
阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)
2007/05/08 Javascript
!DOCTYPE声明对JavaScript的影响分析
2010/04/12 Javascript
AngularJs根据访问的页面动态加载Controller的解决方案
2015/02/04 Javascript
使用JavaScript开发IE浏览器本地插件实例
2015/02/18 Javascript
js验证框架之RealyEasy验证详解
2016/06/08 Javascript
javascript淘宝主图放大镜功能
2016/10/20 Javascript
jQuery特殊符号转义的实现
2016/11/30 Javascript
学习使用bootstrap的modal和carousel
2016/12/09 Javascript
ajax分页效果(bootstrap模态框)
2017/01/23 Javascript
jqGrid翻页时数据选中丢失问题的解决办法
2017/02/13 Javascript
vue router demo详解
2017/10/13 Javascript
妙用缓存调用链实现JS方法的重载
2018/04/30 Javascript
Vue.js@2.6.10更新内置错误处机制Fundebug同步支持相应错误监控
2019/05/13 Javascript
python实现2048小游戏
2015/03/30 Python
Django的models中on_delete参数详解
2019/07/16 Python
在Python中实现函数重载的示例代码
2019/12/12 Python
PyTorch的自适应池化Adaptive Pooling实例
2020/01/03 Python
python实现简单学生信息管理系统
2020/04/09 Python
Python监听剪切板实现方法代码实例
2020/11/11 Python
python中pdb模块实例用法
2021/01/15 Python
css3教程之倾斜页面
2014/01/27 HTML / CSS
html5 利用重力感应实现摇一摇换颜色可用来做抽奖等等
2014/05/07 HTML / CSS
跨域修改iframe页面内容详解
2019/10/31 HTML / CSS
台湾最大银发乐活百货:乐龄网
2018/05/21 全球购物
中学校庆方案
2014/03/17 职场文书
预备党员期盼十八届四中全会召开思想汇报
2014/10/17 职场文书
村干部任职承诺书
2015/01/21 职场文书
市直属机关2016年主题党日活动总结
2016/04/05 职场文书
基于Go Int转string几种方式性能测试
2021/04/28 Golang