①一般的通过名字调用自身

 function sum(num){
if(num<=1){
return 1;
}else{
return num+sum(num-1);
}
} console.log(sum(5));//

这种通过函数名字调用自身的方式存在一个问题:函数的名字是一个指向函数对象的指针,如果我们把函数的名字与函数对象本身的指向关系断开,这种方式运行时将出现错误。

 function sum(num){
if(num<=1){
return 1;
}else{
return num+sum(num-1);
}
}
console.log(sum(5));// var sumAnother=sum;
console.log(sumAnother(5));// sum=null;
console.log(sumAnother(5));//Uncaught TypeError: sum is not a function(…)

②通过arguments.callee调用函数自身

 function sum(num){
if(num<=1){
return 1;
}else{
return num+arguments.callee(num-1);
}
}
console.log(sum(5));// var sumAnother=sum;
console.log(sumAnother(5));// sum=null;
console.log(sumAnother(5));//

这种方式很好的解决了函数名指向变更时导致递归调用时找不到自身的问题。但是这种方式也不是很完美,因为在严格模式下是禁止使用arguments.callee的。

 function sum(num){
'use strict' if(num<=1){
return 1;
}else{
return num+arguments.callee(num-1);
}
}
console.log(sum(5));//Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them(…)

③通过函数命名表达式来实现arguments.callee的效果。

 var sum=(function f(num){
'use strict' if(num<=1){
return 1;
}else{
return num+f(num-1);
}
}); console.log(sum(5));// var sumAnother=sum;
console.log(sumAnother(5));// sum=null;
console.log(sumAnother(5));//

这种方式在严格模式先和非严格模式下都可以正常运行。

Javascript学习笔记:3种递归函数中调用自身的写法的更多相关文章

  1. 转载——JavaScript学习笔记:取数组中最大值和最小值

    转载自:http://www.w3cplus.com/javascript/calculate-the-max-min-value-from-an-array.html. 取数组中最大值 可以先把思路 ...

  2. JavaScript:学习笔记(1)——在HTML中使用JS

    在HTML中使用JavaScript <script>元素 1.直接在网页中嵌入JS代码 说明: 请不要在代码的任何地方出现</script>字符串 这是由于解析嵌入式代码的规 ...

  3. javascript学习笔记-2:jQuery中$("xx")返回值探究

    最近在写一个jQuery插件的时候,需要用到一个条件: 一组img标签,每一个元素都需要被它前面的元素值src替换,如果是第一个(序列为0)则其值为最后一个元素值,如果是最后一个,那么其值为第一个元素 ...

  4. javascript学习笔记(四) Number 数字类型

    数字格式化方法toFixed().toExponential().toPrecision(),三个方法都四舍五入 toFixed() 方法指定小数位个数  toExponential() 方法 用科学 ...

  5. JavaScript:学习笔记(7)——VAR、LET、CONST三种变量声明的区别

    JavaScript:学习笔记(7)——VAR.LET.CONST三种变量声明的区别 ES2015(ES6)带来了许多闪亮的新功能,自2017年以来,许多JavaScript开发人员已经熟悉并开始使用 ...

  6. Java程序猿的JavaScript学习笔记(3——this/call/apply)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  7. Java程序猿JavaScript学习笔记(4——关闭/getter/setter)

    计划和完成这个例子中,音符的顺序如下: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScr ...

  8. JavaScript:学习笔记(9)——Promise对象

    JavaScript:学习笔记(9)——Promise对象 引入Promise Primose是异步编程的一种解决方案,比传统的解决方案回调函数和事件更加合理和强大.如下面为基于回调函数的Ajax操作 ...

  9. JavaScript:学习笔记(5)——箭头函数=>以及实践

    JavaScript:学习笔记(5)——箭头函数=>以及实践 ES6标准新增了一种新的函数:Arrow Function(箭头函数).本文参考的链接如下: MDN箭头函数:https://dev ...

随机推荐

  1. 用Java实现网络爬虫

    myCrawler.java package WebCrawler; import java.io.File; import java.util.ArrayList; import java.util ...

  2. delphi 弹出选择目录窗口

    if not SelectDirectory( '请选择输出文件路径','/',directory) then begin Exit; end; 使用SelectDirectory函数注意要在use下 ...

  3. mysql slave to master

    1, 在maste A上面创建专门用于备份的用户Bshow master statusget log_file and log_pos 2,CHANGE MASTER TO MASTER_HOST=' ...

  4. Scala:没有continue,break怎么办?

    scala自身是没有continue,break这两个语法关键词的. 但是实际上我们还是很希望有这两个语法,那么我们是否可以自己实现呢? 从官网上搜索,我们可以找到一下关于break的类相关资料: B ...

  5. boost any库

    转: 原理 c++是一个强类型的语言,要实现一个万能类型可以考虑用void*来保存数据,然后用类型转换进行操作,如: class MyAny{ MyAny(void* input):content_( ...

  6. PAT复杂度_最大子列和问题、最大子列和变种

    01-复杂度1. 最大子列和问题 给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j ...

  7. js实现文件上传

    js function UpladFile() { var fileObj = document.getElementById("filetes").files[0]; // 获取 ...

  8. 2.2 C#的注释

    注释,是代码中的一些“说明文档”,注释注释本身不会参与程序代码的编译和运行,仅仅是为了方便程序员阅读. C#的注释分为:单行注释.多行注释.文档注释. 单行注释的符号是2条斜杠线(斜线的方向是左下到右 ...

  9. LINQ使用细节之.AsEnumerable()和.ToList()的区别

    先看看下面的代码,用了 .AsEnumerable(): 1 var query = (from a in db.Table2 where a = SomeCondition3 select a.So ...

  10. 关于firewalld防火墙的使用

    要想使用该防火墙,应该需要安装 networkmanager 并启动其服务.因为之前使用的是 netctl 提供的wifi-menu 来连接无线网络,导致安装networkmanager之后启动 Ne ...