javascript --- 递归的简单理解
递归函数大家都应该比较熟吧?那么,如何在JavaScript中书写一个完美的递归函数呢?且听我娓娓道来。
递归函数
写的时候,查了一下维基百科对递归函数的定义,恕我愚钝,简直太深奥了!所以,我还是简单的说说我对递归函数的理解吧。递归函数,说白了就是在函数内部引用函数自身,最终到给定的递归结束条件时回溯。当然,你也可以不给定结束条件,死了别挂我~(╯﹏╰)~。
简单说就是有两个条件:
1. 在函数内部引用自身。
2. 每个递归函数里必定有一个终止条件。
来个小李子:
function test(num){ if(num <= 1){ return 1; }else{ return num * test(num-1); } } var a = test; console.log(a(6));
好了,不错,一个堪称经典的递归求阶乘的函数诞生了。事情肯定不会这么顺利,一定是个圈套。我们来如下调用以下看看会怎么样?
var a = test; test = null; console.log(a(6)); // Uncaught TypeError: test is not a function
居然报错了
回过头去看看我们是如何调用的。发现问题了吧!我们把test赋给了a,然后把test给回收掉了。为什么会出错呢?因为像function这种赋值其实是引用传递,只是把指向函数的指针(这里说地址也行)赋给a了。但我们把test赋值为null的时候,函数都已经被回收了,拿什么来执行?知道问题所在了,我决定换种方式来定义:
function test(num){ if(num <= 1){ return 1; }else{ return num * arguments.callee(--num); } }
然后测试一下:
var test = fun; fun = null; console.log(test(7));
用arguments.callee可解决问题,这是一个指向正在执行的函数的指针,arguments.callee返回正在被执行的对现象。
但是在某一天,当我实际码代码的时候,问题又出现了。什么问题呢?我们来看一下:
Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
╮(╯▽╰)╭哎!可怜啊!因为我使用了"use strict"!严格模式下是不允许的。。。
好吧!继续想办法!既然不能使用arguments.callee(),那还是想想其他的方式吧。
var fun = (function f(num){ if(num <= 1){ return 1; } else{ return num * f(--num); } });
然后我测试了以下,神奇的通过了,暂时没有发现任何问题!
为什么呢?因为我们使用了“()”,巧妙地使用命名函数表达式来达到了同样的效果。
<( ̄︶ ̄)><( ̄︶ ̄)><( ̄︶ ̄)><( ̄︶ ̄)><( ̄︶ ̄)><( ̄︶ ̄)><( ̄︶ ̄)>
javascript --- 递归的简单理解的更多相关文章
- JavaScript Decorators 的简单理解
Decorators,装饰器的意思, 所谓装饰就是对一个物件进行美化,让它变得更漂亮.最直观的例子就是房屋装修.你买了一套房子,但是毛坯房,你肯定不想住,那就对它装饰一下,床,桌子,电视,冰箱等一通买 ...
- javascript 闭包最简单理解
首先说3点与闭包有关系的东西. 一.变量的作用域 变量的作用域不难理解. 1.函数内部可以访问函数外部的变量,而函数外部不能访问函数内部的变量. 2.如果在函数内定义变量的时候,不加var,那么是全局 ...
- JavaScript设计模式的简单理解
设计模式可以理解为一系列的代码框架,我觉得主要涉及封装的概念.把实现某一功能的代码段封装在函数中,可以方便调用,同时利于代码的复用,提高了代码的可维护性.下面简单介绍一下几种设计模式的个人感受. 1. ...
- javascript笔记—— call 简单理解
call 方法 请参阅 应用于:Function 对象 要求 版本 5.5 调用一个对象的一个方法,以另一个对象替换当前对象. call([thisObj[,arg1[, arg2[, [,.argN ...
- 简单理解JavaScript闭包
很多关于JS的书籍例如<JavaScript权威指南>或者<高程>都把闭包解释的晦涩难懂,萌新们是怎么也看不懂啊!不过别怕,今天我就用很简单的方式给大家讲解下到底什么是闭包.这 ...
- javascript编写一个简单的编译器(理解抽象语法树AST)
javascript编写一个简单的编译器(理解抽象语法树AST) 编译器 是一种接收一段代码,然后把它转成一些其他一种机制.我们现在来做一个在一张纸上画出一条线,那么我们画出一条线需要定义的条件如下: ...
- Javascript的堆和栈的简单理解
<!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...
- 简单理解JavaScript原型链
简单理解原型链 什么是原型 ? 我是这样理解的:每一个JavaScript对象在创建的时候就会与之关联另外一个特殊的对象,这个对象就是我们常说的原型对象,每一个对象都会从原型"继承" ...
- Javascript闭包简单理解
提到闭包,想必大家都早有耳闻,下面说下我的简单理解.平时写代码.第三方框架和组件都或多或少用到了闭包.所以,了解闭包是非常必要的.呵呵... 一.什么是闭包简而言之,就是能够读取其他函数内部变量的函数 ...
随机推荐
- Linux学习-Shell的变量功能
什么是变量? 简单的说,就是让某一个特定字串代表不固定的内容. 变量的可变性与方便性 举例来说,我们每个帐号的邮件信箱默认是以 MAIL 这个变量来进行存取的, 当 dmtsai 这个 使用者登陆时, ...
- InnoDB Redo Flush及脏页刷新机制深入分析
概要: 我们知道InnoDB采用Write Ahead Log策略来防止宕机数据丢失,即事务提交时,先写重做日志,再修改内存数据页,这样就产生了脏页.既然有重做日志保证数据持久性,查询时也可以直接从缓 ...
- CodeForces 14D 树的直径 Two Paths
给出一棵树,找出两条不相交即没有公共点的路径,使得两个路径的长度的乘积最大. 思路:枚举树中的边,将该边去掉,分成两棵树,分别求出这两棵树的直径,乘起来维护一个最大值即可. #include < ...
- 《小团团团队》第九次团队作业:Beta冲刺与验收准备
项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 实验十三 团队作业9:Beta冲刺与团队项目验收 团队名称 小团团团队 作业学习目标 (1)掌握软件黑盒测试技术:(2)学 ...
- dedecms 标签
article文章页标签 文档工具:http://tools.dedecms.com/dedetag_maker/article.html {dede:field.title/} 文章标题 {dede ...
- TensorFlow——小练习:counter
下面的例子演示了如何使用变量实现一个 简单的计数器(counter) # _*_coding:utf-8_*_ import tensorflow as tf import numpy as np # ...
- ACM程序设计选修课——1065: Operations on Grids(暴力字符串)
1065: Operations on Grids Time Limit: 3 Sec Memory Limit: 128 MB Submit: 17 Solved: 4 [Submit][Sta ...
- C#函数多返回值的方法
C#以前都是不支持多返回值,当需要返回多个值的时候,就会感觉比较麻烦,通常的做法有 1.采用ref,out 关键字返回 2.定义类或者结构体 返回对象 C# 6.0出来了新的语法 Tuple 支付返回 ...
- LFYZOJ 104 Counting Swaps
题解 #include <iostream> #include <cstdio> #include <algorithm> #include <cmath&g ...
- 如果你的css文件这么分类,可维护性大大增强!--摘抄
按照css的性质和用途,我们可以将css文件分成: 公共型样式 特殊型样式 皮肤型样式 并以此为顺序引用. 那么他们分别是什么呢? 公共型样式是最为重要的部分,对于比较小的项目,我们只引入一个css, ...