在读 《深入理解ES6》一书中,看到有关函数的 “尾调用优化” 章节,特此记录一下

尾调用 指的是 函数作为另一个函数的最后一条语句被调用:

function foo () {
return bar();
}

书中说 在 ES5 的时候,尾调用的实现与其他函数调用类型,创建一个新的帧栈,然后将它推入调用栈表示调用,也就是说在循环调用中,每个未执行完的帧栈都保存在内存中,当调用栈变的过大会造成性能问题.

ES6 的优化

严格模式下,缩减了尾调用栈的大小;非严格模式不受影响,如果满足以下条件,尾调用不再创建新的帧栈,而是服用当前帧栈.

  1. 尾调用不访问当前帧栈的变量(非闭包)

  2. 在函数内部,尾调用是最后一条语句

  3. 尾调用的值作为结果返回

看如下例子:

// 可以优化

"use strict";
function foo() {
return bar();
}
// 无法优化 -> 函数调用没有作为值返回;

function foo() {
bar();
}
// 无法优化 -> 此处 函数并没有直接被返回,而是执行了一步操作
"use strict"; function foo() {
return 1 + bar();
}
// 无法优化 -> 调用不在尾部

function foo() {
var result = bar();
return result;
}
// 无法优化,闭包!

"use strict";

function foo() {
var num = 1,
getNum = () => num;
return getNum();
}

因为尾调用优化是执行在JS 引擎上的优化,在我们实际的开发中的应用场景是什么呢?

场景1: 获取一个固定格式的日期

function getDate() {
return createDateTime(true);
} function getTime() {
return createDateTime(false);
} function createDateTime(date) {
// ...
return date ? 'YY-MM-DD':'YY-MM-DD hh:mm:ss'
}

场景2:递归

function factorial(n,p=1) {
if(n <= 1) {
return n*p;
}else {
let result = n * p;
return factorial(n-1,result);
}
}

ECMA Script6 中的 尾调用优化的更多相关文章

  1. JavaScript中的尾调用优化

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

  2. 前端项目中常用es6知识总结 -- 箭头函数及this指向、尾调用优化

    项目开发中一些常用的es6知识,主要是为以后分享小程序开发.node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫. 项目开发常用es6介绍 1.块级作用域 let const 2. ...

  3. JavaScript 中的尾调用

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

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

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

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

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

  6. ES6学习笔记 -- 尾调用优化

    什么是尾调用? 尾调用(Tail Call)是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数. function f(x) { return g(x) } 如上,函数 f 的最后一 ...

  7. PHP、Lua中的 尾调用

    在程序设计中,递归(Recursion)是一个很常见的概念,合理使用递归,可以提升代码的可读性,但同时也可能会带来一些问题. 下面以阶乘(Factorial)为例来说明一下递归的用法,实现语言是PHP ...

  8. iOS 的尾调用优化原理

    背景: 今天聊代码规范的问题的时候说了一下尾调用的问题. 一:概念: 什么是尾调用? 尾调用(Tail Call):某个函数的最后一步仅仅只是调用了一个函数(可以是自身,可以是另一个函数). 注意 “ ...

  9. JS的递归与TCO尾调用优化

    转自:https://segmentfault.com/a/1190000004018047 这两天搜了下JS递归的相关文章, 觉得这篇文章很不错, 就顺手翻译了下,也算给自己做个笔记,题目是我自己加 ...

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

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

随机推荐

  1. CvT:微软提出结合CNN的ViT架构 | 2021 arxiv

    CvT将Transformer与CNN在图像识别任务中的优势相结合,从CNN中借鉴了多阶段的层级结构设计,同时引入了Convolutional Token Embedding和Convolutiona ...

  2. AT_agc019_b 题解

    洛谷链接&Atcoder 链接. 题目简述 给定一个字符串 \(A\),可以选择区间 \([i,j]\) 翻转一次,求能得到多少本质不同的字符串.(\(A\) 的长度不超过 \(2 \time ...

  3. Tomcat 线程池学习总结

    前提 Tomcat 10.1.x Tomcat线程池介绍 Tomcat线程池,源于JAVA JDK自带线程池.由于JAVA JDK线程池策略,比较适合处理 CPU 密集型任务,但是对于 I/O 密集型 ...

  4. Jenkins 添加Linux固定代理节点

    实践环境 Jenkins 2.304 jdk-8u131-linux-x64.rpm centos-release-7-9.2009.1.el7.centos.x86_64 操作步骤 安装JDK 在预 ...

  5. 如何立刻读取在MySQL中自动生成的主键

    在写一个接口时,我们需要对两个表分别动刀,但是我们需要前一个表的主键作为下一个表的功能外键, 如果使用mybatisplus,insert完成之后便可以直接在对象中取出这个id值 如果使用mybati ...

  6. JWT浅了解

    JWT通过数字签名的方式(让我想起了软考),以json对象为载体,在不同的服务终端之间安全传输信息 是一种授权认证 生成token的原理:通过header的加密方式,对payload进行加密.然后把h ...

  7. pytorch-a2c-ppo-acktr-gail 算法代码

    地址: https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail

  8. 循环神经网络 —— LSTM 图片

  9. NVIDIA Omniverse Audio2Face的安装

    下载 NVIDIA Omniverse 并运行安装程序 - 安装后,打开 Omniverse Launcher - 在"Apps"(应用)部分中找到 Omniverse Audio ...

  10. 【转载】 python鸭子类型与protocol

    版权声明:本文为CSDN博主「yuanzhoulvpi」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/yuan ...