最近在看《冴羽的博客》,讲真,确实受益匪浅,已经看了javascript 深入系列和专题系列的大部分文章,可是现在才想起来做笔记。所以虽然很多以前面试被问得一脸懵逼的问题都被“一语惊醒梦中人”过,注意这里我说的是“过”。是的,这些知道点,当时看的时候跟着大佬的思维,确实当时感觉“哦~ 原来是这样”,但是,看了下篇把上篇的知识忘了还是让我感觉自己太挫了。
于是,决定写点笔记来加深一点印象吧!
  今天看到了“javascript专题之递归” (https://github.com/mqyqingfeng/Blog/issues/49) 这篇,所以就从这里开始吧!
在这里我再一次看到了尾调用和尾递归这俩个的关键字,距离前一次看到好像还是很多年前的事了,但是当时完全不明所以啊...,但是,今天,结合了之前的执行上下文执行上下文栈的知识,总算明白这到底是个啥了!
  尾调用,是指函数内部的最后一个动作是函数调用。该调用的返回值,直接返回给函数。
  尾递归,函数调用自身,称为递归。如果尾调用自身,就称为尾递归。
  至于为什么很多场景要提倡使用尾调用,为什么使用尾调用和尾递归会有更好的性能呢?,就涉及到了执行上下文栈 的知识。https://github.com/mqyqingfeng/Blog/issues/4:当执行一个函数的时候,就会创建一个执行上下文,并且压入执行上下文栈,当函数执行完毕的时候,就会将函数的执行上下文从栈中弹出。 所以我理解是:也正是因为如此执行上下文被弹出,从而释放了内存,所以性能就得到了提升吧!
  尾调用:
// 尾调用
function f(x) {
return g(x);
}

  注意:

// 非尾调用
function f(x) {
return g(x) + 1;
}
因为g(x)的返回值还需要跟1进行计算后,f(x)才会返回值。
两者仅仅是 + 1这一点点的区别,有什么不一样呢?答案就是执行上下文栈的变化不一样。
为了模拟执行上下文栈的行为,让我们定义执行上下文栈是一个数组:
ECStack = [];
尾调用的执行过程:
// 模拟的伪代码:
ECStack.push(<f> functionContext);
ECStack.pop();
ECStack.push(<g> functionContext);
ESStack.pop();
 
非尾调用的执行过程:

ECStack.push(<f> functionContext);
ECStack.push(<g> functionContext);
ECStack.pop();
ECStack.pop();
 
  由此可以看到尾调用和非尾调用都是需要调用f()函数和g()函数,但是,尾调用,当调用了f()之后,马上就释放了f()的执行上下文,执行g()时候,就只剩下g()的执行上下文了,而非尾调用是先把两个函数先后压入执行上下文栈,待最后一个函数执行完才把两个函数的执行上下文弹出(在没有执行完最后一个函数之前,前面的函数执行上下文一直占据着内存)。
  阶乘函数:

// 非尾调用写法:
function factorial(n) {
if (n == 1) return n;
return n * factorial(n - 1);
}
factorial(5) // --> 5 * 4 * 3 * 2 * 1 = 120 // 尾调用优化写法:
function factorial(n, res) {
if (n == 1) return res;
return factorial(n - 1, n * res)
}

javascript专题系列--尾调用和尾递归的更多相关文章

  1. JavaScript中的尾调用优化

    文章来源自:http://www.zhufengpeixun.com/qianduanjishuziliao/javaScriptzhuanti/2017-08-08/768.html JavaScr ...

  2. JavaScript 中的尾调用

    尾调用(Tail Call) 尾调用是函数式编程里比较重要的一个概念,它的意思是在函数的执行过程中,如果最后一个动作是一个函数的调用,即这个调用的返回值被当前函数直接返回,则称为尾调用,如下所示: f ...

  3. ES6 之 函数的扩展 尾调用以及尾递归

    函数参数的默认值 function log(x, y) { y = y || 'world' console.log(x + ' ' + y); } log('hello') // hello wor ...

  4. javascript专题系列--js乱序

    乱序的意思想必没有不知道:就是将数组打乱. 听到乱序一般都会想到js的随机函数Math.random(); var values = [1, 2, 3, 4, 5]; values.sort(func ...

  5. JavaScript 专题系列第六篇,讲解深浅拷贝的技巧和以及实现深浅拷贝的思路

    拷贝也是面试经典呐! 数组的浅拷贝 如果是数组,我们可以利用数组的一些方法比如:slice.concat 返回一个新数组的特性来实现拷贝. 比如:   var arr = ['old', 1, tru ...

  6. JavaScript函数尾调用与尾递归

    什么是函数尾调用和尾递归 函数尾调用与尾递归的应用 一.什么是函数的尾调用和尾递归 函数尾调用就是指函数的最后一步是调用另一个函数. //函数尾调用示例一 function foo(x){ retur ...

  7. Selenium3 + Python3自动化测试系列十——调用JavaScript代码

    调用JavaScript代码 一.调用JavaScript代码方法 Selenium在对浏览器操作时会有自动化代码中不稳定的部分,经常出错的部分,可以将这部分对网页元素进行操作的代码换成对应的Java ...

  8. ES6躬行记(15)——箭头函数和尾调用优化

    一.箭头函数 箭头函数(Arrow Function)是ES6提供的一个很实用的新功能,与普通函数相比,不但在语法上更为简洁,而且在使用时也有更多注意点,下面列出了其中的三点: (1)由于不能作为构造 ...

  9. js 调用栈机制与ES6尾调用优化介绍

    调用栈的英文名叫做Call Stack,大家或多或少是有听过的,但是对于js调用栈的工作方式以及如何在工作中利用这一特性,大部分人可能没有进行过更深入的研究,这块内容可以说对我们前端来说就是所谓的基础 ...

随机推荐

  1. 对象查询语言(OQL)的应用实例

    一.绪论 两个多星期前,我的导师布置了一道作业,就是利用对象查询语言(OQL)对常规的SQL需求进行求解.而对于我一个在面向对象数据库方面,经验可谓无足轻重的新手来说,确实难以下手.不用说,我肯定在拿 ...

  2. HTML+CSS基础 css的尺寸

    css的尺寸 width 宽   height高 Line-light   行高    行高是由三部分构成,上间距.文本高度.下间距. 且上下间距相等.所以文字居中 行高.一旦设置行高了,元素内部必须 ...

  3. 奥展项目笔记07--vue绑定下拉框和checkbox总结

    1.vue绑定下拉框 <div class="col-md-1 data"> <select class="form-control " v- ...

  4. React及Nextjs相关知识点小结

    React及Nextjs知识点小结 函数式组件和类组件区别是什么 1.函数式组件是用于创建无状态的组件,组件不会被实例化,无法访问this中的对象,无法访问生命周期方法,是无副作用的,相比于类组件函数 ...

  5. generator的本质是将异步的管理剥离

    generator的本质是将异步的管理剥离

  6. python随机选取目录下的若干个文件

    个人记录用. python模块random argparse shutil import argparse parser = argparse.ArgumentParser() parser.add_ ...

  7. kali渗透综合靶机(四)--node1靶机

    kali渗透综合靶机(四)--node1靶机 靶机下载地址::https://download.vulnhub.com/node/Node.ova 一.主机发现 1.netdiscover -i et ...

  8. C#, CSV,Generic, 泛型,导出

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  9. netcore sdk版本选择

    NetCore sdk并不是每个版本都支持VS2017工具,也不是每个版本的sdk版本号和Runtime版本号都一样,这就需要我们在创建某个版本的net core应用时注意: 使用不同版本的vs时需要 ...

  10. Python语言获取目录下所有文件

    #coding=utf-8# -*- coding: utf-8 -*-import osimport sysreload(sys) sys.setdefaultencoding('utf-8') d ...