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属性的作用与替换方案的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • js arguments,jcallee caller用法总结

    关键字:arguments,callee,callerarguments:表示传入函数的参数callee:表示函数和函数主体的语句caller:表示调用该函数的函数arguments 该对象代表正在执行的函数和调用它的函数的参数. caller 返回一个对函数的引用,该函数调用了当前函数.functionName.callerfunctionName 对象是所执行函数的名称. 说明对于函数来说,caller属性只有在函数执行时才有定义.如果函数是由顶层调用的,那么 caller包含的就是 nul

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

    一.arguments.callee的作用:返回正被执行的 Function 对象 arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文,这有利于匿名函数的递归或者保证函数的封装性. 请看下面这个非常经典的阶乘函数 function factorial(num){ if (num <=1) { return 1; } else { return num * factori

  • Javascript中arguments和arguments.callee的区别浅析

    通过一个例子来理解下arguments与arguments.callee的具体区别: 代码如下: 复制代码 代码如下: <script type="text/javascript">                 function check(args){                         var ac = args.length;              var ex = args.callee.length;              document

  • js arguments.callee的应用代码

    复制代码 代码如下: function f(x){ alert(x); return arguments.callee; } f(0)(1)(2)(3)(4)(5)(6)(7)(8)(9); 复制代码 代码如下: function f(){ var a=arguments,i,l=a.length; for(i=0; i<l;i++){ alert(a[i]); } return arguments.callee; } f(0)(1,2)(3,4,5)(6,7,8,9);

  • Javascript函数中的arguments.callee用法实例分析

    本文实例讲述了Javascript函数中的arguments.callee用法.分享给大话公大家参考,具体如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml&

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

    arguments.callee的作用 在函数内部,有两个特殊的对象:arguments 和 this.其中, arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数. 请看下面这个非常经典的阶乘函数 function factorial(num){ if (num <=1) { return 1; } else { return num * factorial(num-1) } } 定义阶乘函

  • javascript中arguments,callee,caller详解

    arguments是什么? arguments是函数调用时,创建的一个类似的数组但又不是数组的对象,并且它存储的是实际传递给函数的参数,并不局限于函数声明的参数列表哦. 尼玛,什么意思? 写个demo看看,代码见下 <!DOCTYPE html> <head> <title>arguments</title> <meta http-equiv="Content-Type" content="text/html; chars

  • JavaScript中arguments的使用方法详解

    前言 js这是一门弱语言,不像其他语言如c,java等,有严格的规范, 所以现在也流传着一种说法,js本来就不是一种语言: 说回arguments,它是js中函数内置的一个对象,而执行函数方法的实参中值都存储在arguments中: 要想获取到这些实参,就需要像数组一样,用下标/索引来定位到每个值上面,但是又不能说它是一个数组,因为它里面还有其他的属性,如callee; 并且不能对它使用shift.push.join等方法.而没有传递值的命名参数将会被自动赋予undefined: 如下图: (如

  • 详解JavaScript中Arguments对象用途

    目录 前言 Arguments 的基本概念 Arguments 的作用 获取实参和形参的个数 修改实参值 改变实参的个数 检测参数合法性 函数的参数个数不确定时,用于访问调用函数的实参值 遍历或访问实参的值 总结 在实际开发中,Arguments 对象非常有用.灵活使用 Arguments 对象,可以提升使用函数的灵活性,增强函数在抽象编程中的适应能力和纠错能力. JavaScript 中 Arguments 对象的用途总结. 前言 相信我们很多人在代码开发的过程中都使用到过一个特殊的对象 --

  • JavaScript中arguments和this对象用法分析

    本文实例讲述了JavaScript中arguments和this对象用法.分享给大家供大家参考,具体如下: 在函数内部有两个特殊的对象 : arguments和this. 1.arguments对象 js函数不介意定义多少参数,也不在乎传递进来多少参数,也就是说,即使定义的函数只接收2个参数,在调用时候也未必传递2个参数,因为js的函数参数在内部使用一个数组表示的,在函数体内可以通过arguments对象访问此参数数组.因此,js函数可以不显式地使用命名参数. 当函数被调用时,传入的参数将保存在

  • JavaScript中arguments的使用方法

    目录 一.arguments的使用 二.arguments.callee的使用 一.arguments的使用 当我们不确定有多少个参数传递的时候,可以用 arguments 来获取.在 JavaScript 中,arguments 实际上它是当前函数的一个内置对象.所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有实参. arguments展示形式是一个伪数组,因此可以进行遍历.伪数组具有以下特点: 具有 length 属性 按索引方式储存数据 不具有数组

  • JavaScript中闭包的写法和作用详解

    1.什么是闭包 闭包是有权访问另一个函数作用域的变量的函数. 简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内.而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数和声明的其他内部函数.当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包. 2.变量的作用域 要理解闭包,首先要理解变量的作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变

  • JavaScript 中 avalon绑定属性总结

    avalon是前端MVVM框架,将所有前端代码彻底分成两部分,视图的处理通过绑定实现(angular有个更炫酷的名词叫指令),业务逻辑则集中在一个个叫VM的对象中处理.我们只要操作VM的数据,它就自然而然地神奇地同步到视图. $model(所有非$属性),$event(事件对象) 1.作用域圈定 ms-controller:按着就近原则自下而上扫描DOM树 ms-important:仅扫描本节点及之下作为扫描区 ms-skip:使绑定失效 2.ms-duplex双向绑定属性:除了绑定(VM同步数

  • Javascript中arguments用法实例分析

    本文实例讲述了Javascript中arguments用法.分享给大家供大家参考.具体分析如下: 先来看如下示例: function add(n1,n2){ return n1+n2; } function add(n1,n2,n3) { return n1+n2+n3; } alert(add(1,2)); //NaN,js中调用方法采用就近原则: //而由于该方法没有传入n3,所以结果是NaN js中没有方法重载,怎么解决上面这个问题? //arguments function f1(){

  • JavaScript中的全局属性与方法深入解析

    今天来补充JavaScript中的最后一部分内容,JavaScript中的全局属性和方法(函数). 1.全局属性 // 属性 // Infinity 代表正的无穷大的数值. // 在Javascript中,超出 1.7976931348623157E+103088 的数值即为Infinity,小于 -1.7976931348623157E+103088 的数值为无穷小. var num1 = 1.7976931348623157E+103088; var num2 = -1.7976931348

随机推荐