摘要:返回空字符串,返回將一個具名函數(shù)賦值給一個變量,則和的屬性都返回這個具名函數(shù)原本的名字。不可以使用對象,該對象在函數(shù)體內(nèi)不存在。等到運(yùn)行結(jié)束,將結(jié)果返回到,的調(diào)用幀才會消失。
1 函數(shù)參數(shù)的默認(rèn)值
ES6允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值,即直接寫在參數(shù)定義的后面:
function log(x = "message.",y = "duration infomation.") { console.log(x, y); } log(); //message. duration infomation. log("hello world.", "connecting."); //hello world. connecting.
參數(shù)變量是默認(rèn)聲明的,所以不能用let和const再次聲明
function add(x = 0, y = 0) { let x; //報(bào)錯 const y; //報(bào)錯 console.log(x + y); } add();
與結(jié)構(gòu)賦值默認(rèn)值結(jié)合使用
function add({x = 0, y = 0}) { console.log(x + y); } add({}); //0 add({y: 1}); //1 //當(dāng)add()時,則會報(bào)錯 add(); //報(bào)錯 //如何才能在add()時不報(bào)錯呢? //這就需要用到雙重默認(rèn)值,即默認(rèn)為函數(shù)傳入一個對象 function add({x = 0, y = 0} = {}) { console.log(x + y); } add({}); //0 add({y: 1}); //1 add(); //0
如下:
function add({name = "your name here", age = "your age here"} = {}) { console.log(`${name}, ${age}`); } add(); //your name here, your age here add({name: "Oliver"}); //Oliver, your age here add({name: "Troy", age: 18}); //Troy, 18
函數(shù)的length屬性
指定了默認(rèn)值以后,函數(shù)的length屬性,將返回沒有指定默認(rèn)值的參數(shù)個數(shù)。
function add(x,y = 0) { console.log(x + y); } console.log(add.length); //1 函數(shù)預(yù)期傳入1個參數(shù),因?yàn)橛幸粋€參數(shù)已經(jīng)有默認(rèn)值了
作用域
如果參數(shù)默認(rèn)值是一個變量,則該變量所處的作用域,與其他變量的作用域規(guī)則是一樣的,即先是當(dāng)前函數(shù)的作用域,然后才是全局作用域。
var x = 10; function log(x, y = x) { //x已經(jīng)在內(nèi)部生成,使用的將是內(nèi)部的x console.log(y); } log(2); //2 var x = 10; function log(y = x) { //x不存在,使用的將是外部的x console.log(y); } log(); //10
實(shí)際應(yīng)用
省略參數(shù)拋出錯誤:
function throwIfMissing() { throw new Error("Missing parameter."); } function foo(x = throwIfMissing()) { return x; } console.log(foo(10)); //10 console.log(foo()); //Uncaught Error: Missing parameter.2 rest參數(shù)
rest參數(shù)(形式為“...變量名”),用于獲取函數(shù)的多余參數(shù),這樣就不需要使用arguments對象了
function foo(...values) { let sum = 0; for(let val of values) sum += val; console.log(sum); } foo(1,2,3);
注意,rest參數(shù)之后不能再有其他參數(shù)(即只能是最后一個參數(shù)),否則會報(bào)錯。
function foo(x, ...values) { let sum = 0; for(let val of values) sum += val; console.log(x, sum); } foo(1,2,3); //x是1,sum是2+3 function foo(x, ...values, y) { let sum = 0; for(let val of values) sum += val; console.log(x, sum); } foo(1,2,3); //Rest parameter must be last formal parameter3 擴(kuò)展運(yùn)算符
擴(kuò)展運(yùn)算符(spread)是三個點(diǎn)(...)。它好比rest參數(shù)的逆運(yùn)算,將一個數(shù)組轉(zhuǎn)為用逗號分隔的參數(shù)序列。
let a = [1,2,3,4,5,6,7]; console.log(...a); //1 2 3 4 5 6 7 a.push(...a); console.log(a); //[1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7]
該運(yùn)算符主要用于函數(shù)的調(diào)用
let a = [1,2,3,4,5,6,7]; function add(...args) { let sum = 0; for (let val of args) console.log(sum += val); console.log(`done. final sum: ${sum}`); } add(...a); //依次傳入a數(shù)列中的值 //1 //3 //6 //10 //15 //21 //28 //done. final sum: 28
替代數(shù)組的apply方法
擴(kuò)展運(yùn)算符可以展開數(shù)組,所以不再需要apply方法
//ES5 let a = [1,2,3,4,5,6,7]; console.log(Math.max.apply(null,a)); //7 //ES6 console.log(Math.max(...a)); //7
又比如push函數(shù)
let a = []; let num = [1,2,3,4,5,6,7]; a.push(...num); console.log(a.toString()); //1,2,3,4,5,6
擴(kuò)展運(yùn)算符的應(yīng)用
合并數(shù)組
let a = []; let a1 = [1,2,3]; let a2 = [4,5]; let a3 = [6,7,8,9,10]; a = [...a1, ...a2, ...a3]; console.log(a.toString()); //1,2,3,4,5,6,7,8,9,10
與解構(gòu)賦值結(jié)合
let [...rest] = [1,2,3,4,5,6]; console.log(rest); //[1,2,3,4,5,6]
函數(shù)的返回值
var dateFields = readDateFields(database); var d = new Date(...dateFields);
字符串
console.log([..."hello"]); //["h", "e", "l", "l", "o"]
擴(kuò)展運(yùn)算符能夠識別32位Unicode字符
可以正確返回字符串長度:
console.log([..."hello"]); //["h", "e", "l", "l", "o"] function len(...args) { for (let val of args) console.log([...val].length); } len("hello", "another one 哈哈"); //14
類似數(shù)組的對象
var nodeList = document.getElementsByTagName("p"); var array = [...nodeList];
含有Iterator接口對象
只要具有Iterator接口的對象,都可以使用擴(kuò)展運(yùn)算符
Map,Set,Generator等
4 name屬性函數(shù)的name屬性,返回該函數(shù)的函數(shù)名。
如果將一個匿名函數(shù)賦值給一個變量,ES5的name屬性,會返回空字符串,而ES6的name屬性會返回實(shí)際的函數(shù)名。
var x = function() {}; console.log(x.name); //"" ES5返回空字符串,ES6返回x
將一個具名函數(shù)賦值給一個變量,則ES5和ES6的name屬性都返回這個具名函數(shù)原本的名字。
var x = function y() {}; console.log(x.name); //"y"
Function構(gòu)造函數(shù)返回的函數(shù)實(shí)例,name屬性的值為“anonymous”。
console.log((new Function).name); //anonymous
bind返回的函數(shù),name屬性值會加上“bound ”前綴。
function foo() {}; foo.bind({}).name // "bound foo" (function(){}).bind({}).name // "bound "5 箭頭函數(shù)
ES6允許使用“箭頭”(=>)定義函數(shù)。
let add = (x,y) => x + y; console.log(add(1,2)); //3 function add(x,y) { return x + y; } console.log(add(1,2)); //3
如果箭頭函數(shù)的代碼塊部分多于一條語句,就要使用大括號將它們括起來,并且使用return語句返回。
let add = (x, y) => { console.log("done"); return x + y; }; console.log(add(1, 2)); //3
如果箭頭函數(shù)直接返回一個對象,必須在對象外面加上括號。
let add = (x, y) => ({ result: x + y }); console.log(add(1, 2).result); //3
箭頭函數(shù)可以與變量解構(gòu)結(jié)合使用。
let add = ({ name, age }) => ({ result: `${name},${age}` }); console.log(add({ name: "Oliver", age: 18 }).result); //Oliver,18
箭頭函數(shù)的一個用處是簡化回調(diào)函數(shù)
var arr = [1, 2, 3, 4, 5]; arr.map(function(item, index, array) { console.log(item); }); arr.map((item, index, array) => { console.log(item); }); //上面兩種函數(shù)寫法功能相同,下面的明顯較為簡潔
使用注意點(diǎn)
函數(shù)體內(nèi)的this對象,就是定義時所在的對象,而不是使用時所在的對象。
不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用new命令,否則會拋出一個錯誤。
不可以使用arguments對象,該對象在函數(shù)體內(nèi)不存在。如果要用,可以用Rest參數(shù)代替。
不可以使用yield命令,因此箭頭函數(shù)不能用作Generator函數(shù)。
6 ES7函數(shù)綁定ES7中函數(shù)綁定運(yùn)算符(::)作用是代替call、apply、bind調(diào)用。
7 尾調(diào)用優(yōu)化尾調(diào)用
尾調(diào)用(Tail Call)就是指某個函數(shù)的最后一步是調(diào)用另一個函數(shù):
function g() { console.log("done."); } function j() { console.log("almost done."); } function log(x) { if (x > 0) { return g(); } return j(); } log(10); //done. log(0); //almost done.
g()和j()的調(diào)用都屬于尾調(diào)用,因?yàn)槎际呛瘮?shù)的最后一步
尾調(diào)用優(yōu)化
函數(shù)調(diào)用會在內(nèi)存形成一個“調(diào)用記錄”,又稱“調(diào)用幀”(call frame),保存調(diào)用位置和內(nèi)部變量等信息。如果在函數(shù)A的內(nèi)部調(diào)用函數(shù)B,那么在A的調(diào)用幀上方,還會形成一個B的調(diào)用幀。等到B運(yùn)行結(jié)束,將結(jié)果返回到A,B的調(diào)用幀才會消失。如果函數(shù)B內(nèi)部還調(diào)用函數(shù)C,那就還有一個C的調(diào)用幀,以此類推。所有的調(diào)用幀,就形成一個“調(diào)用棧”(call stack)。
尾調(diào)用由于是函數(shù)的最后一步操作,所以不需要保留外層函數(shù)的調(diào)用幀,因?yàn)檎{(diào)用位置、內(nèi)部變量等信息都不會再用到了,只要直接用內(nèi)層函數(shù)的調(diào)用幀,取代外層函數(shù)的調(diào)用幀就可以了。
注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會取代外層函數(shù)的調(diào)用幀,否則就無法進(jìn)行“尾調(diào)用優(yōu)化”。
function addOne(a) { var one = 1; function inner(b) { return b + one; } return inner(a); }
尾遞歸
遞歸非常耗費(fèi)內(nèi)存,因?yàn)樾枰瑫r保存成千上百個調(diào)用幀,很容易發(fā)生“棧溢出”錯誤。但對于尾遞歸來說,由于只存在一個調(diào)用幀,所以永遠(yuǎn)不會發(fā)生“棧溢出”錯誤。
所以確保最后只調(diào)用自身就可以了,做法是將所有參數(shù)傳入要調(diào)用的函數(shù)中去:
// function log(n) { // if (n === 1) { // return 1 // }; // return n * log(n - 1); // } // console.log(log(5)); //120 function log(n, total) { if (n === 1) { return total }; return log(n - 1, n * total); } console.log(log(5, 1)); //1208 ES7函數(shù)參數(shù)的尾逗號
ES7提案允許函數(shù)的最后一個參數(shù)有尾逗號。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79157.html
摘要:否則調(diào)用時依然需要傳參報(bào)錯注意這里不能用觸發(fā)默認(rèn)值這里我們還需要單獨(dú)討論一下默認(rèn)參數(shù)對的影響很明顯,默認(rèn)參數(shù)并不能加到中。關(guān)于作用域集中在函數(shù)擴(kuò)展的最后討論。那如果函數(shù)的默認(rèn)參數(shù)是函數(shù)呢?zé)X的要來了如果基礎(chǔ)好那就根本談不上不燒腦。 參數(shù)默認(rèn)值 ES5中設(shè)置默認(rèn)值非常不方便, 我們這樣寫: function fun(a){ a = a || 2; console.log(a); ...
摘要:基本用法所聲明的變量,只在命令所在的代碼塊內(nèi)有效。在循環(huán)中適合使用不存在變量提升不像那樣會發(fā)生變量提升現(xiàn)象暫時性死區(qū)只要塊級作用域內(nèi)存在命令,它所聲明的變量就綁定這個區(qū)域,不再受外部的影響。塊級作用域?qū)嶋H上為新增了塊級作用域。 1 let 基本用法 所聲明的變量,只在let命令所在的代碼塊內(nèi)有效。 { let b = 100; console.log(b); //100...
摘要:第二個參數(shù)指定修飾符,如果存在則使用指定的修飾符。屬性表示是否設(shè)置了修飾符屬性的屬性返回正則表達(dá)式的正文的屬性返回正則表達(dá)式的修飾符字符串必須轉(zhuǎn)義,才能作為正則模式。 1 RegExp構(gòu)造函數(shù) ES6 允許RegExp構(gòu)造函數(shù)接受正則表達(dá)式作為參數(shù)。第二個參數(shù)指定修飾符,如果存在則使用指定的修飾符。 var regexp = new RegExp(/xyz/i, ig); consol...
摘要:二進(jìn)制和八進(jìn)制表示法提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫法,分別用前綴或和或表示。用來檢查是否為有窮以及是否為這兩個新方法只對數(shù)值有效,非數(shù)值一律返回。引入了和這兩個常量,用來表示這個范圍的上下限。因?yàn)橛芯认拗疲^的次方的值無法精確表示。 1 二進(jìn)制和八進(jìn)制表示法 ES6提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫法,分別用前綴0b(或0B)和0o(或0O)表示。 console.log(0b10...
摘要:數(shù)組的解構(gòu)賦值允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行賦值,這被稱為解構(gòu)。如果變量名與屬性名不一致,必須寫成下面這樣。 1 數(shù)組的解構(gòu)賦值 ES6允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行賦值,這被稱為解構(gòu)(Destructuring)。 基本用法 { var [a,[b,c],d,,...f] = [1,[2,3],4,5,6,7]; console...
閱讀 3463·2021-11-25 09:43
閱讀 1062·2021-11-15 11:36
閱讀 3313·2021-11-11 16:54
閱讀 3974·2021-09-27 13:35
閱讀 4364·2021-09-10 11:23
閱讀 5675·2021-09-07 10:22
閱讀 3032·2021-09-04 16:40
閱讀 769·2021-08-03 14:03