1、let 和 const
var 聲明的變量全局范圍內(nèi)都有效铜靶。循環(huán)內(nèi)return i 返回的最終i的值的引用
let 聲明的變量只在它所在的代碼塊有效
var a = []
for (var i = 0;i < 10; i++) {
console.log(i) // 1~10
a[i] = function () {
return i
}
}
console.log(i) // 10
console.log(a[6]()) // 10
console.log(window.i) // 10
2共螺、變量的結(jié)構(gòu)賦值
解構(gòu): ES6 允許按照一定模式宙址,從數(shù)組和對象中提取值厕鹃,對變量進(jìn)行賦值
數(shù)組的解構(gòu)
es5:
let a = 1;
let b = 2;
let c = 3;
es6:
let [a, b, c] = [1, 2, 3];
let [head, ...tail] = [1, 2, 3, 4]
head // 1
tail // [2, 3, 4]
// 如果解構(gòu)不成功,變量的值就等于undefined嬉愧。
let [foo] = []; // foo = undefined
let [bar, foo] = [1]; // foo = undefined
對象的解構(gòu)
let { foo, bar } = { foo: "aaa", bar: "bbb" }
foo // "aaa"
bar // "bbb"
3贩挣、字符串?dāng)U展
4、正則的擴(kuò)展
5没酣、數(shù)值的擴(kuò)展
6王财、函數(shù)的擴(kuò)展
參數(shù)默認(rèn)值
function (x = 1) {...}
與解構(gòu)賦值結(jié)合使用
function foo({x, y = 5}) {
console.log(x, y);
}
foo({}) // undefined 5
函數(shù)的length屬性
指定了默認(rèn)值以后,函數(shù)的length屬性裕便,將返回沒有指定默認(rèn)值的參數(shù)個數(shù)绒净。也就是說,指定了默認(rèn)值后偿衰,length屬性將失真挂疆。
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
如果設(shè)置了默認(rèn)值的參數(shù)不是尾參數(shù),那么length屬性也不再計入后面的參數(shù)了下翎。
(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1
應(yīng)用
可以通過設(shè)置參數(shù)的默認(rèn)值判斷一個這個函數(shù)被調(diào)用時是否有參數(shù)傳遞進(jìn)來
function err() {
throw new Error('Missing parameter');
}
function foo(arg = err()) {
return arg;
}
foo()
// Error: Missing parameter
rest參數(shù)
ES6 引入 rest 參數(shù)(形式為...變量名)缤言,用于獲取函數(shù)的多余參數(shù),這樣就不需要使用arguments對象了视事。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
嚴(yán)格模式
從 ES5 開始俐东,函數(shù)內(nèi)部可以設(shè)定為嚴(yán)格模式跌穗。ES2016 做了一點(diǎn)修改,規(guī)定只要函數(shù)參數(shù)使用了默認(rèn)值虏辫、解構(gòu)賦值蚌吸、或者擴(kuò)展運(yùn)算符,那么函數(shù)內(nèi)部就不能顯式設(shè)定為嚴(yán)格模式砌庄,否則會報錯羹唠。
name屬性
函數(shù)的name屬性奕枢,返回該函數(shù)的函數(shù)名,這個屬性早就被瀏覽器廣泛支持,但是直到 ES6肉迫,才將其寫入了標(biāo)準(zhǔn)
- Function構(gòu)造函數(shù)返回的函數(shù)實(shí)例验辞,name屬性的值為anonymous稿黄。
- 如果將一個匿名函數(shù)賦值給一個變量喊衫,ES5 的name屬性,會返回空字符串杆怕,而 ES6 的name屬性會返回實(shí)際的函數(shù)名族购。
- Function構(gòu)造函數(shù)返回的函數(shù)實(shí)例,name屬性的值為anonymous陵珍。
- bind返回的函數(shù)寝杖,name屬性值會加上bound前綴。
箭頭函數(shù)
ES6 允許使用“箭頭”(=>)定義函數(shù)互纯。
- 函數(shù)體內(nèi)的this對象瑟幕,就是定義時所在的對象,而不是使用時所在的對象留潦。
- 不可以當(dāng)作構(gòu)造函數(shù)只盹,也就是說,不可以使用new命令兔院,否則會拋出一個錯誤殖卑。
- 不可以使用arguments對象,該對象在函數(shù)體內(nèi)不存在坊萝。如果要用孵稽,可以用 rest 參數(shù)代替。
- 不可以使用yield命令十偶,因此箭頭函數(shù)不能用作 Generator 函數(shù)菩鲜。
::運(yùn)算符
箭頭函數(shù)可以綁定this對象,大大減少了顯式綁定this對象的寫法(call惦积、apply睦袖、bind)。但是荣刑,箭頭函數(shù)并不適用于所有場合馅笙,所以現(xiàn)在有一個提案,提出了“函數(shù)綁定”(function bind)運(yùn)算符厉亏,用來取代call董习、apply、bind調(diào)用爱只。
函數(shù)綁定運(yùn)算符是并排的兩個冒號(::)皿淋,雙冒號左邊是一個對象,右邊是一個函數(shù)。該運(yùn)算符會自動將左邊的對象窝趣,作為上下文環(huán)境(即this對象)疯暑,綁定到右邊的函數(shù)上面。箭頭函數(shù)可以綁定this
對象哑舒,大大減少了顯式綁定this
對象的寫法(call
妇拯、apply
、bind
)洗鸵。但是越锈,箭頭函數(shù)并不適用于所有場合,所以現(xiàn)在有一個提案膘滨,提出了“函數(shù)綁定”(function bind)運(yùn)算符甘凭,用來取代call
、apply
火邓、bind
調(diào)用丹弱。
函數(shù)綁定運(yùn)算符是并排的兩個冒號(::
),雙冒號左邊是一個對象铲咨,右邊是一個函數(shù)躲胳。該運(yùn)算符會自動將左邊的對象,作為上下文環(huán)境(即this
對象)鸣驱,綁定到右邊的函數(shù)上面泛鸟。
foo::bar;
// 等同于
bar.bind(foo);
foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);
const hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
return obj::hasOwnProperty(key);
}
尾調(diào)用優(yōu)化
尾調(diào)用(Tail Call)是函數(shù)式編程的一個重要概念,本身非常簡單踊东,一句話就能說清楚北滥,就是指某個函數(shù)的最后一步是調(diào)用另一個函數(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)用幀就可以了倾鲫。這就叫做“尾調(diào)用優(yōu)化”(Tail call optimization),即只保留內(nèi)層函數(shù)的調(diào)用幀腕够。如果所有函數(shù)都是尾調(diào)用级乍,那么完全可以做到每次執(zhí)行時舌劳,調(diào)用幀只有一項(xiàng)帚湘,這將大大節(jié)省內(nèi)存。這就是“尾調(diào)用優(yōu)化”的意義甚淡。
注意大诸,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會取代外層函數(shù)的調(diào)用幀贯卦,否則就無法進(jìn)行“尾調(diào)用優(yōu)化”资柔。所以閉包是不能進(jìn)行尾調(diào)用優(yōu)化的。