Javascript学习笔记:3种递归函数中调用自身的写法

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

1 function sum(num){
2   if(num<=1){
3     return 1;
4   }else{
5     return num+sum(num-1);
6   }
7 }
8
9 console.log(sum(5));//15

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

 1 function sum(num){
 2   if(num<=1){
 3     return 1;
 4   }else{
 5     return num+sum(num-1);
 6   }
 7 }
 8 console.log(sum(5));//15
 9
10 var sumAnother=sum;
11 console.log(sumAnother(5));//15
12
13 sum=null;
14 console.log(sumAnother(5));//Uncaught TypeError: sum is not a function(…)

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

 1 function sum(num){
 2   if(num<=1){
 3     return 1;
 4   }else{
 5     return num+arguments.callee(num-1);
 6   }
 7 }
 8 console.log(sum(5));//15
 9
10 var sumAnother=sum;
11 console.log(sumAnother(5));//15
12
13 sum=null;
14 console.log(sumAnother(5));//15

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

 1 function sum(num){
 2   ‘use strict‘
 3
 4   if(num<=1){
 5     return 1;
 6   }else{
 7     return num+arguments.callee(num-1);
 8   }
 9 }
10 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的效果。

 1 var sum=(function f(num){
 2   ‘use strict‘
 3
 4   if(num<=1){
 5     return 1;
 6   }else{
 7     return num+f(num-1);
 8   }
 9 });
10
11 console.log(sum(5));//15
12
13 var sumAnother=sum;
14 console.log(sumAnother(5));//15
15
16 sum=null;
17 console.log(sumAnother(5));//15

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

时间: 2024-08-08 01:29:32

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

javascript学习笔记-2:jQuery中$(&quot;xx&quot;)返回值探究

最近在写一个jQuery插件的时候,需要用到一个条件: 一组img标签,每一个元素都需要被它前面的元素值src替换,如果是第一个(序列为0)则其值为最后一个元素值,如果是最后一个,那么其值为第一个元素值,以此形成一个闭环. 为此,我使用了三元运算符?:,其表达式为:var next=$(this).next()?$(this).next():imageItems.first(); 运行测试发现如下问题,当运行到数组最后一个元素时,其next是始终不会是这一组img标签的第一个,为此对$(this

javascript学习笔记(三) string对象中的正则表达式

1. search返回匹配到的位置(-1找不到) var str = 'html js' var pattern = /js/ str.search(pattern)    --------->5 2. Match str.match(pattern) --------['js'] /js/g -----> ["js", "js",,"js"] match vs exec match:非全局的情况下才会返回分组中匹配到的内容,全局匹配

JavaScript学习笔记——jquery中html()、text()、val()的区别

.html()用为读取和修改元素的HTML标签 .text()用来读取或修改元素的纯文本内容 .val()用来读取或修改表单元素的value值. 这三个方法功能上的对比 .html(),.text(),.val()三种方法都是用来读取选定元素的内容:只不过.html()是用来读取元素的HTML内容(包括其Html标签),.text()用来读取元素的纯文本内容,包括其后代元素,.val()是用来读取表单元素的"value"值.其中.和.text()方法不能使用在表单元素上,而.val()

c++学习笔记5,多重继承中派生类的构造函数与析构函数的调用顺序(二)

现在来测试一下在多重继承,虚继承,MI继承中虚继承中构造函数的调用情况. 先来测试一些普通的多重继承.其实这个是显而易见的. 测试代码: //测试多重继承中派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include <iostream> using namespace std; class base { public: base() { cout<<"base created!"<<endl; }

JavaScript学习笔记第一天——字符串连接的N种方法

Javascript 字符串的连接方法有多种,但效率却有很大区别. 1.逐个字符串相加 var arr = ['item 1', 'item 2', 'item 3', ...]; var list = ''; for (var i = 0, l = arr.length; i < l; i++) { list += '<li>' + arr[i] + '</li>'; } list = '<ul>' + list + '</ul>'; 这种最常见的,

javascript学习笔记---ECMAScript语法(引用类型)

引用类型通常叫做类(class). 本教程会讨论大量的 ECMAScript 预定义引用类型. 引用类型 引用类型通常叫做类(class),也就是说,遇到引用值,所处理的就是对象. 本教程会讨论大量的 ECMAScript 预定义引用类型. 从现在起,将重点讨论与已经讨论过的原始类型紧密相关的引用类型. 注意:从传统意义上来说,ECMAScript 并不真正具有类.事实上,除了说明不存在类,在 ECMA-262 中根本没有出现"类"这个词.ECMAScript 定义了"对象定

javascript学习笔记---ECMAScriptECMAScript 对象----定义类或对象

使用预定义对象只是面向对象语言的能力的一部分,它真正强大之处在于能够创建自己专用的类和对象. ECMAScript 拥有很多创建对象或类的方法. 原始的方式 因为对象的属性可以在对象创建后动态定义(后绑定),类似下面的代码: var oCar = new Object; oCar.color = "blue"; oCar.doors = 4; oCar.mpg = 25; oCar.showColor = function() { alert(this.color); };不过这里有一

JavaScript学习笔记【2】表达式和运算符、语句、对象

笔记来自<JavaScript权威指南(第六版)> 包含的内容: 表达式和运算符 语句 对象 表达式和运算符 数组直接量中的列表逗号之间的元素可以省略,这时省略的空位会填充值undefined.元素列表末尾可以留下单个逗号,这时并不会创建一个新的值为undefined元素. 属性访问表达式,.identifier的写法只适用于要访问的属性名称是合法的标识符,并且需要知道要访问的属性的名字.如果属性名称是一个保留字或者包含空格和标识符,或是一个数字(对于数组来说),则必须使用方括号的写法.当属性

JavaScript学习笔记【3】数组、函数、服务器端JavaScript概述

笔记来自<JavaScript权威指南(第六版)> 包含的内容: 数组 函数 服务器端JavaScript概述 数组 数组是动态的:根据需要它们会增长或缩减,并且在创建数组时无须声明一个固定的大小或在数组大小变化时无须重新分配空间. 数组可能是稀疏的:索引不一定要连续的,它们之间可以有空缺. 通常,数组的实现是经过优化的,用数字索引来访问数组元素一般来说比访问常规的对象属性要快很多. 数组继承自Array.prototype中的属性,它定义了一套丰富的数组操作方法. 如果省略数组直接量中的某个