摘要:如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時,調(diào)用幀只有一項,這將大大節(jié)省內(nèi)存。等同于等同于注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會取代外層函數(shù)的調(diào)用幀,否則就無法進(jìn)行尾調(diào)用優(yōu)化。
1. 函數(shù)參數(shù)的默認(rèn)值
在ES6之前是不能為函數(shù)的參數(shù)指定默認(rèn)值的,要想實現(xiàn)默認(rèn)值只能通過判斷賦值的方式來實現(xiàn),在ES6中允許函數(shù)為參數(shù)設(shè)置默認(rèn)值,主要是為了提高代碼的可閱讀性,有利于代碼的優(yōu)化。另外注意的是在參數(shù)賦值的時候,該參數(shù)不能重復(fù)使用,不能使用let const 進(jìn)行定義。
// ES6 之前實現(xiàn) function log(x, y) { y = y || "World"; if (typeof y === "undefined") { y = "World"; } console.log(x, y); } log("Hello") // Hello World log("Hello", "China") // Hello China log("Hello", "") // Hello World // ES6 中實現(xiàn) function log(x, y = "World") { console.log(x, y); } log("Hello") // Hello World log("Hello", "China") // Hello China log("Hello", "") // Hello function Point(x = 0, y = 0) { this.x = x; this.y = y; } const p = new Point(); p // { x: 0, y: 0 } function foo(x = 5,x) { let x = 1; // 報錯,不能同名參數(shù),不能對參數(shù)進(jìn)行l(wèi)et const 定義 const x = 2; }
如果函數(shù)在調(diào)用的時候沒有提供參數(shù),內(nèi)部變量就不會產(chǎn)生,就會產(chǎn)生錯誤,通過提供函數(shù)的默認(rèn)值可以解決這種問題,如下:
function foo({x, y = 5}) { console.log(x, y); } foo() // 報錯 foo({x:1}) // 1 5 foo({x:2,y:3) // 2 3 foo({}) // undefined 5 function foo ({x,y = 5} = {}){ console.log(x,y) } foo() // undefined 5 這樣就是如果沒有在調(diào)用的時候傳值 就默認(rèn)賦空對象。
如下例子:
function post(url, {b = "",type="get",h={}}){ console.log(type) } post("w.b.c",{}) // get post("w.b.c") // 報錯 // 改成這樣就可以了 function post(url, {b = "",type="get",h={}} = {}){ console.log(type) } post("w.b.c",{}) // get post("w.b.c") // get
下面例子的區(qū)別
// 寫法一 function m1({x = 0, y = 0} = {}) { return [x, y]; } // 寫法二 function m2({x, y} = { x: 0, y: 0 }) { return [x, y]; } 兩個都是有默認(rèn)值在調(diào)用的時候都傳值或者都不傳值的時候情況是一樣的。 但是如果傳空值,或者不傳值的情況會有差異如下: m1({}) // 因為本身有默認(rèn)值 所以為 [0,0] m2({}) // 默認(rèn)值為空 解構(gòu)賦值沒有傳值 所以 [undefined,undefined] // 其他情況同上 m1({x: 3}) // [3, 0] m2({x: 3}) // [3, undefined] m1({z: 3}) // [0, 0] m2({z: 3}) // [undefined, undefined]
如果定義了默認(rèn)值的參數(shù),應(yīng)該是函數(shù)的尾參數(shù)。而且這個參數(shù)是無法省略的,除非輸入undefined
函數(shù)參數(shù)指定了默認(rèn)值之后,函數(shù)的length屬性將會減去指定了默認(rèn)值的參數(shù)個數(shù)。因為該屬性認(rèn)為,指定了默認(rèn)值的參數(shù)將不包含在預(yù)期參數(shù)個數(shù)中。如下:
(function (a) {}).length // 1 (function (a = 5) {}).length // 0 (function (a, b, c = 5) {}).length // 2
如果函數(shù)中的參數(shù)設(shè)置了默認(rèn)值,那么函數(shù)在聲明初始化的時候,參數(shù)會形成一個多帶帶的作用域,初始化完成后這個作用域就會消失,這種情況只在參數(shù)設(shè)置了默認(rèn)值的情況下。如下:
var x = 1; function f(x, y = x) { console.log(y); } f(2) // 2 // 因為 設(shè)置了默認(rèn)值 所以在調(diào)用 f 的時候就形成了作用域,這時候因為將x賦值給y 傳入的x 為 2 所以y是2,如果這時候 調(diào)用的時候不傳值, 那么x將指向全局,所以y = 1
利用參數(shù)默認(rèn)值,可以指定某一個參數(shù)不得省略,如果省略就報錯,如下
function throwIfMissing() { throw new Error("Missing parameter"); } function foo(mustBeProvided = throwIfMissing()) { return mustBeProvided; } foo() // Error: Missing parameter foo(2) // 22. rest 參數(shù)
ES6 中 增加了 rest 參數(shù)(...變量名),用于獲取函數(shù)多余的參數(shù),rest參數(shù)搭配的變量是一個數(shù)組,該變量將多余的參數(shù)放入數(shù)組中。
function add(...values) { let sum = 0; for (var val of values) { sum += val; } return sum; } add(2, 5, 3) // 10 // 注意:rest 參數(shù)之后不能再有其他參數(shù),另外rest參數(shù)也不計算在 函數(shù)的length屬性中。3. 嚴(yán)格模式
ES6 中,如果函數(shù)參數(shù)使用了默認(rèn)值,解構(gòu)賦值,或者擴展運算符,那么函數(shù)內(nèi)部將不能顯式設(shè)定為嚴(yán)格模式,否則會報錯。因為函數(shù)執(zhí)行的時候 先執(zhí)行函數(shù)參數(shù),在執(zhí)行函數(shù)體,但是因為只有在函數(shù)體中才能知道參數(shù)是否以嚴(yán)格模式執(zhí)行,但是參數(shù)卻應(yīng)該先于函數(shù)執(zhí)行。有兩種方法可以規(guī)避:一、 設(shè)置全局嚴(yán)格模式,二、把函數(shù)包在一個無參數(shù)的立即執(zhí)行函數(shù)里面。4. name屬性
返回函數(shù)的函數(shù)名,如下:
function foo(){} foo.name // foo var f = function(){} // ES5 f.name // "" // ES6 f.name // f var f = function c(){} f.name // c5. 箭頭函數(shù)
ES6 允許使用 “箭頭” (=>)定義函數(shù)
var f = v => v; // 等同于 var f = function (v) { return v; }; var f = () => 5; // 等同于 var f = function () { return 5 }; var sum = (num1, num2) => num1 + num2; // 等同于 var sum = function(num1, num2) { return num1 + num2; }; // 如果箭頭函數(shù)后面的語句較多就要用大括號包裹起來 并return返回 var sum = (num1, num2) => { return num1 + num2; //rest 參數(shù)與箭頭函數(shù)結(jié)合的例子。 const numbers = (...nums) => nums; numbers(1, 2, 3, 4, 5) // [1,2,3,4,5] const headAndTail = (head, ...tail) => [head, tail]; headAndTail(1, 2, 3, 4, 5) // [1,[2,3,4,5]]
1. 函數(shù)體內(nèi)的this對象,就是在定義時所在的對象,而不是使用時所在的對象。 2. 不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用new命令,否則會拋出一個錯誤。 3. 不可以使用arguments對象,該對象在函數(shù)體內(nèi)不存在。如果要用,可以用 rest 參數(shù)代替。 4. 不可以使用yield命令,因此箭頭函數(shù)不能用作 Generator 函數(shù)。 5. 由于箭頭函數(shù)沒有自己的this,所以當(dāng)然也就不能用call()、apply()、bind()這些方法去改變this的指向。
1. 定義對象的方法,且該方法內(nèi)部包括this 2. 動態(tài)定義this 的場合,如點擊事件中this 的指向
箭頭函數(shù)內(nèi)部可以在嵌套使用箭頭函數(shù)。6. 尾調(diào)用優(yōu)化
函數(shù)式編程的一個重要概念,指某個函數(shù)的最后一步是調(diào)用另一個函數(shù)
function f(x){ return g(x); } // 一下都不屬于 // 情況一 function f(x){ let y = g(x); return y; } // 情況二 function f(x){ return g(x) + 1; } // 情況三 function f(x){ g(x); }
只保留內(nèi)層函數(shù)的調(diào)用幀。如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時,調(diào)用幀只有一項,這將大大節(jié)省內(nèi)存。這就是“尾調(diào)用優(yōu)化”的意義。
function f() { let m = 1; let n = 2; return g(m + n); } f(); // 等同于 function f() { return g(3); } f(); // 等同于 g(3);
注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會取代外層函數(shù)的調(diào)用幀,否則就無法進(jìn)行“尾調(diào)用優(yōu)化”。
函數(shù)調(diào)用自身,稱為遞歸。如果尾調(diào)用自身,就稱為尾遞歸。
在正常模式下,可以使用減少調(diào)用棧,采用循環(huán)換掉遞歸的方法歡迎關(guān)注 公眾號【小夭同學(xué)】
ES6入門系列
ES6入門之let、cont
ES6入門之變量的解構(gòu)賦值
ES6入門之字符串的擴展
ES6入門之正則的擴展
ES6入門之?dāng)?shù)值的擴展
Git教程
前端Git基礎(chǔ)教程
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/54944.html
摘要:循環(huán)遍歷對象自身的和繼承的可枚舉屬性不含屬性。返回一個數(shù)組,包含對象自身的所有屬性的鍵名。目前,只有對象方法的簡寫法可以讓引擎確認(rèn),定義的是對象的方法。showImg(https://user-gold-cdn.xitu.io/2019/5/21/16ada8456223b0e1); 1. 屬性的簡潔表示法 在ES6中 允許直接寫入變量和函數(shù),作為對象的屬性和方法,使得代碼的書寫更為簡潔。...
摘要:屬性的簡潔表示法在中允許直接寫入變量和函數(shù),作為對象的屬性和方法,使得代碼的書寫更為簡潔。循環(huán)遍歷對象自身的和繼承的可枚舉屬性不含屬性。返回一個數(shù)組,包含對象自身的所有屬性的鍵名。 showImg(https://segmentfault.com/img/remote/1460000019259004?w=1282&h=1920); 1. 屬性的簡潔表示法 在ES6中 允許直接寫入變量...
摘要:如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時,調(diào)用幀只有一項,這將大大節(jié)省內(nèi)存。等同于等同于注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會取代外層函數(shù)的調(diào)用幀,否則就無法進(jìn)行尾調(diào)用優(yōu)化。 showImg(https://segmentfault.com/img/bVbrTHp?w=1080&h=1920); 1. 函數(shù)參數(shù)的默認(rèn)值 1.1 用法 在ES6之前是不能為...
showImg(https://user-gold-cdn.xitu.io/2019/5/22/16adcec448a45d82); 1. Object.is() 用來解決在ES5中 兩種相等運算符的缺點。用來比較兩個值是否嚴(yán)格相等,行為和(===)基本一致。 在ES5中判斷兩個值是否相等,只能用(==)相等運算符和(===)嚴(yán)格相等運算符,但是這兩貨都有缺點,前者 兩邊的值都會轉(zhuǎn)換數(shù)據(jù)類型,...
閱讀 1178·2021-10-20 13:48
閱讀 2208·2021-09-30 09:47
閱讀 3112·2021-09-28 09:36
閱讀 2353·2019-08-30 15:56
閱讀 1207·2019-08-30 15:52
閱讀 2028·2019-08-30 10:48
閱讀 617·2019-08-29 15:04
閱讀 579·2019-08-29 12:54