递归函数是在一个函数通过名字调用自身的情况下构成的,如下所示

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

这是一个经典的递归阶乘函数。虽然这个函数表面看来没什么问题,但下面的代码却可能导致它出错

var a = f;
f = null;
a(3);//出错

以上代码先把f()函数保存在变量a 中,然后将f 变量设置为null,结果指向原始函数的引用只剩下一个。但在接下来调用a()时,由于必须执行f(),而f 已经不再是函数,所以就会导致错误。在这种情况下,使用arguments.callee 可以解决这个问题。我们知道,arguments.callee是一个指向正在执行的函数的指针,这样就可以实现递归调用了:

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

通过使用arguments.callee 代替函数名,可以确保无论怎样调用函数都不会出问题。因此,在编写递归函数时,使用arguments.callee 总比使用函数名更保险。但在严格模式下,不能通过脚本访问arguments.callee,访问这个属性会导致错误。不过,可以使用命名函数表达式来达成相同的结果。例如:

var g = (function f(num){
if(num<=1){
return 1;
} else {
return num*f(num-1);
}
});

以上代码创建了一个名为f()的命名函数表达式,然后将它赋值给变量g。即便把函数赋值给了另一个变量,函数的名字f 仍然有效,所以递归调用照样能正确完成。这种方式在严格模式和非严格模式下都行得通

S1 : 递归的更多相关文章

  1. LeetCode 全解(bug free 训练)

    1.Two Sum Given an array of integers, return indices of the two numbers such that they add up to a s ...

  2. leetcode: 树

    1. sum-root-to-leaf-numbers Given a binary tree containing digits from0-9only, each root-to-leaf pat ...

  3. .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]

    方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...

  4. LeetCode 笔记系列 19 Scramble String [合理使用递归]

    题目: Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty subs ...

  5. 递归神经网络(RNN)简介(转载)

    在此之前,我们已经学习了前馈网络的两种结构--多层感知器和卷积神经网络,这两种结构有一个特点,就是假设输入是一个独立的没有上下文联系的单位,比如输入是一张图片,网络识别是狗还是猫.但是对于一些有明显的 ...

  6. 模板与继承之艺术——奇特的递归模板模式(CRTP)

    一.什么是CRTP 奇特的模板递归模式(Curiously Recurring Template Pattern)即将派生类本身作为模板参数传递给基类. template<typename T& ...

  7. Instant Complexity(模拟,递归)

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1535   Accepted: 529 Description Analyz ...

  8. poj1664 (递归)

    放苹果 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 31295   Accepted: 19742 Description ...

  9. Day5 双层装饰器、字符串格式化、生成器、迭代器、递归

    双层装饰器实现用户登录和权限认证 #!/usr/bin/env python# -*- coding: utf-8 -*-# Author: WangHuafeng USER_INFO = {} de ...

随机推荐

  1. Redis基础知识之——自定义封装单实例和普通类Redis

    一.普通Redis实例化类: class MyRedis { private $redis; public function __construct($host = '121.41.88.209', ...

  2. ORACLE 查询日志

    SQL>select * from v$sql (#查看最近所作的操作) SQL>select * fromv $sqlarea(#查看最近所作的操作)

  3. mysql概要(十五)存储过程

    1.定义: 2.查看所有存储过程: show procedure status; 3.创建存储过程: create procedure 存储过程名字(参数) begin s1l语句; end$     ...

  4. Promise A 规范的一个简单的浏览器端实现

    简单的实现了一个promise 的规范,留着接下来模块使用.感觉还有很多能优化的地方,有时间看看源码,或者其他大神的代码 主要是Then 函数.回调有点绕人. !(function(win) { fu ...

  5. 【转】Github 上传代码

    版权声明:欢迎转载(^ω^)~不过转载请注明原文出处:http://blog.csdn.net/catglory ლ(╹◡╹ლ) 写在前面: 弄了两小时终于搞定了,把经验整理下,方便我以后上传代码XD ...

  6. Javascript设计模式之创建对象的灵活性

    传统的 /* Anim class */ var Anim = function () {}; Anim.prototype.start = function () { console.log(&qu ...

  7. hostapd源代码分析(二):hostapd的工作机制

    [转]hostapd源代码分析(二):hostapd的工作机制 原文链接:http://blog.csdn.net/qq_21949217/article/details/46004433 在我的上一 ...

  8. hdu 2063 过山车(二分图最佳匹配)

    经典的二分图最大匹配问题,因为匈牙利算法我还没有认真去看过,想先试试下网络流的做法,即对所有女生增加一个超级源,对所有男生增加一个超级汇,然后按照题意的匹配由女生向男生连一条边,跑一个最大流就是答案( ...

  9. windows下重新安装TCP/IP协议栈

    一.windows重装TCP/IP协议     前两天在windows下安装开发环境的时候,把系统的TCP/IP协议栈给搞跪了,导致系统无法ping localhost.无法在程序中创建socket等 ...

  10. 基于 php-redis 的redis操作

    基于 php-redis 的redis操作 林涛 发表于:2016-5-13 12:12 分类:PHP 标签:php,php-redis,redis 203次 redis的操作很多的,下面的例子都是基 ...