[TOC]
>[success] # 尾調用優化
~~~
'尾調用優化'使用場景,一般在'遞歸'時使用會有顯著效果,在'ES6'中對函數最有趣的改動或許就是一項
'引擎優化',它改變了'尾部調用'的系統。'尾調用'指的是調用函數的語句是'另一個函數的最后語句',有3點,
符合這'3'點就是達成了'尾調用優化'
1. 尾調用不能引用當前棧幀中的變量(意味著'該函數不能是閉包')
2. 進行尾調用的函數在'尾調用返回結果后不能做額外操作'
3. 尾調用的結果作為當前函數的返回值
~~~
~~~
function doSomething() {
return doSomethingElse() // 尾調用
}
~~~
<br/>
>[danger] ## 錯誤尾調用優化案例
1. 沒有return
~~~
"use strict"
function doSomething() {
doSomethingElse() // 未被優化:缺少 return
}
~~~
2. 在return時候還進行加法操作
~~~
"use strict"
function doSomething() {
return 1 + doSomethingElse() // 未被優化:在返回之后還要執行加法
}
~~~
3. 將函數調用的結果儲存在一個變量上,之后才返回了 結果
~~~
"use strict"
function doSomething() {
let result = doSomethingElse() // 未被優化:調用并不在尾部
return result
}
~~~
4. 閉包能夠訪問上層作用域的變量,會導致尾 調用優化被關閉
~~~
"use strict";
function doSomething() {
let num = 1,
func = () => num
return func() // 未被優化:此函數是閉包
}
~~~
<br/>
>[success] ## 如何控制尾調用優化
~~~
在實踐中,'尾調用優化在后臺進行',所以不必對此考慮太多,除非要盡力去優化一個函數。尾調用優化的主要用
例是在'遞歸函數'中,而且在其中的優化具有最大效果。考慮以下計算階乘的函數:
~~~
優化前:
~~~
// 階乘遞歸
function factorial(n) {
if (n <= 1) {
return 1
} else {
// 未被優化:在返回之后還要執行乘法
return n * factorial(n - 1)
}
}
~~~
優化后:
~~~
function factorial(n, p = 1) {
if (n <= 1) {
return 1 * p
} else {
let result = n * p
// 被優化
return factorial(n - 1, result)
}
}
~~~
- Javascript基礎篇
- Array數組
- 數組插入值
- filter()
- forEach()
- push()
- pop()
- unshift()
- shift()
- valueOf()
- 面向對象思想
- Javascript 面向對象編程(一):封裝
- Javascript面向對象編程(二):構造函數的繼承
- Javascript面向對象編程(三):非構造函數的繼承
- 解構
- 數組的解構賦值
- 對象的解構賦值
- 函數參數解構
- 字符串的解構賦值
- 數值和布爾值的解構賦值
- 圓括號問題
- 字符串.
- split()
- charAt()
- charCodeAt()
- concat()
- indexOf()
- lastIndexOf()
- match()
- replace()
- includes()
- 初識遞歸
- 渲染ul-li樹形結構
- 異步函數解決方案
- 1. callback回調函數
- 2. ES6 - Promise
- JavaScript高級程序設計(書)
- 在html中使用JavaScript
- script標簽的位置
- 延遲腳本
- 異步腳本
- <noscript>元素
- 基本概念
- 嚴格模式
- 變量詳解
- 數據類型
- typeof操作符
- undefined類型
- Null類型
- Boolean類型
- Number類型
- 深入了解ES6(書)
- var 、let 、 const
- 字符串與正則表達式
- 字符串
- 正則表達式
- 函數
- 函數形參默認值
- 使用不具名參數
- 函數構造器的增強能力
- 擴展運算符
- name屬性
- 明確函數的多重用途
- 塊級函數
- 箭頭函數
- 尾調用優化
- 擴展的對象功能
- 對象類別
- 對象字面量語法的擴展
- ES6對象新增方法
- 重復的對象屬性
- 自有屬性的枚舉順序
- 更強大的原型
- 解構:更方便的數據訪問
- 為什么要用解構?
- 對象解構
- 數組解構
- 混合解構
- 參數解構
- Symbol與Symbol屬性
- 創建Symbol
- Symbol的使用方法
- Symbol全局私有屬性
- Symbol與類型強制轉換
- Symbol屬性檢索
- Symbol的一些構造方法
- Set集合與Map集合
- Set集合
- Weak Set集合(弱引用Set集合)
- Map集合
- JS標準內置對象
- Object 構造函數及屬性
- Object 構造方法
- Symbol 內建對象類的函數及屬性
- Set 構造函數及屬性
- Weak Set 構造函數及屬性
- JS雜項
- 類數組對象
- Class類的理解和使用