let
- 用來(lái)聲明變量梁丘,只在聲明塊內(nèi)有效
- 不存在變量提升
function add(){
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 1;
console.log(a); // => 1
if(a===1){
let b = 2;
console.log(b); // => 2
}
console.log(b); // ReferenceError: b is not defined
}
add()
- 暫時(shí)性死區(qū)(簡(jiǎn)稱(chēng)TDZ)
只要塊級(jí)作用域內(nèi)存在let
命令伤靠,它所聲明的變量就“綁定”這個(gè)區(qū)域范咨,不再受外部影響。
在代碼塊內(nèi)师抄,使用let
命令之前漓柑,該變量都是不可用的,這在語(yǔ)法上,稱(chēng)為“暫時(shí)性死區(qū)”
var tmp = 123;
if (true) {
console.log(tmp); // ReferenceError: Cannot access 'tmp' before initialization
let tmp;
}
ES6 明確規(guī)定辆布,如果區(qū)塊中存在let
和const
命令瞬矩,這個(gè)區(qū)塊對(duì)這些命令聲明的變量,從一開(kāi)始就形成了封閉作用域锋玲,凡是在聲明之前就使用這些變量景用,就會(huì)報(bào)錯(cuò)。
- 比較隱蔽的“死區(qū)”
function bar(x = y, y = 2) {
return [x, y];
}
bar(); // 報(bào)錯(cuò)
參數(shù)x
默認(rèn)值等于另一個(gè)參數(shù)y
惭蹂,而此時(shí)y
還沒(méi)有聲明伞插,屬于“死區(qū)”。
- 不允許重復(fù)聲明
let
不允許在相同作用域內(nèi)盾碗,重復(fù)聲明同一個(gè)變量
// 報(bào)錯(cuò)
function func() {
let a = 10;
var a = 1;
}
// 報(bào)錯(cuò)
function func() {
let a = 10;
let a = 1;
}
// 不能在函數(shù)內(nèi)部重新聲明參數(shù)媚污。
function func(arg) {
let arg;
}
func() // 報(bào)錯(cuò)
function func(arg) {
{
let arg;
}
}
func() // 不報(bào)錯(cuò)
ES6 的塊級(jí)作用域
如下代碼如果使用var
定義變量,會(huì)輸出10廷雅,但是塊級(jí)作用域外層代碼塊不受內(nèi)存代碼塊影響
function f () {
let n = 5;
if ( true ) {
let n = 10;
}
console.log(n); // 5
}
const
-
const
聲明一個(gè)只讀的常量耗美,一旦聲明,常量的值就不能改變航缀。 -
const
一旦聲明變量商架,就必須立即初始化,不能留到以后賦值芥玉。 -
const
只聲明不賦值會(huì)報(bào)錯(cuò)蛇摸。 -
const
的作用域與let
相同,只在聲明所在的塊級(jí)作用域內(nèi)有效灿巧。 -
const
聲明不提升赶袄。 -
const
存在暫時(shí)性死區(qū),只能在聲明的位置后面使用抠藕。 -
const
不可重復(fù)聲明弃鸦。
頂層對(duì)象的屬性
頂層對(duì)象在瀏覽器環(huán)境指的是window
對(duì)象,在Node
指的是global
對(duì)象幢痘。
-
ES5
中,頂層對(duì)象的屬性與全局變量是等價(jià)的家破。
window.a = 1;
a ; // => 1
a = 2;
window.a; // => 2
上邊代碼中颜说,頂層對(duì)的屬性賦值與全局變量的賦值,是同一件事汰聋。
-
ES6
規(guī)定门粪,let
、const
烹困、class
聲明的全局變量玄妈,不屬于頂層對(duì)象的屬性。
let b = 1;
window.b; // undefined
數(shù)組的解構(gòu)賦值
- ES6允許按照一定模式,從數(shù)組和對(duì)象中提取值拟蜻,對(duì)變量進(jìn)行賦值绎签,這被稱(chēng)為解構(gòu)
let a = 1;
let b = 2;
let c = 3;
// ES6 允許寫(xiě)成下面這樣
let [a,b,c] = [1,2,3];
- 這種寫(xiě)法屬于“模式匹配”,只要等號(hào)兩邊的模式相同酝锅,左邊的變量就會(huì)被賦對(duì)應(yīng)的值诡必。
let [x,,y] = [1,2,3];
x // => 1,
y // => 3
let [x,...y] = [1,2,3,4];
x; // => 1
y; // => [2,3,4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
- 如果解構(gòu)不成功,變量的值就等于
undefined
let [a] = [];
let [b,a] = [1];
// a 的值都是undefined
如果等號(hào)右邊不是數(shù)組搔扁,那么將會(huì)報(bào)錯(cuò)爸舒。
解構(gòu)賦值允許指定默認(rèn)值
let [a = 1] = [];
a; // => 1
- ES6內(nèi)部使用嚴(yán)格相等運(yùn)算符(
===
),判斷一個(gè)位置是否有值稿蹲,所以只有當(dāng)數(shù)組成員嚴(yán)格等于undefined
扭勉,默認(rèn)值才生效。
let [a = 1] = [undefined];
a; // => 1
let [b = 1] = [null];
b; // => null 因?yàn)閚ull不嚴(yán)格等于undefined
- 如果默認(rèn)值是一個(gè)表達(dá)式苛聘,那么這個(gè)表達(dá)式是惰性求值的涂炎,只有在用到的時(shí)候,才會(huì)求值
function f(){
console.log('aaaa');
}
let [a = f()] = [1];
a; // => 1 因?yàn)閍能取到值焰盗,所以f根本不會(huì)執(zhí)行
對(duì)象的解構(gòu)賦值
對(duì)象的解構(gòu)與數(shù)組不同璧尸,數(shù)組的元素是按次序排列的,變量的取值由它的位置決定熬拒,而對(duì)象的屬性沒(méi)有次序爷光,變量必須與屬性同名,才能取到正確的值澎粟。
let { b , a } = { a:1 , b:2 };
a; // => 1
b; // => 2
let { c } = { a:1 , b:2 };
c; // => undefined 解構(gòu)失敗蛀序,變量的值等于undefined
- 如果變量名與屬性名不一致
let obj = {first:"hello",last:"world"};
let {first:h,last:w} = obj;
h; // => 'hello'
w: // => 'world'
- 對(duì)象的解構(gòu)賦值可以取到繼承的屬性
let o1 = {
x: 1
};
let o2 = Object.create(o1);
o2.y = 2;
const { x , y } = o2;
x; // => 1
y; // => 2
- 對(duì)象的解構(gòu)也可以指定默認(rèn)值
let { x = 1 } = {};
x; // => 1
let { x: y = 2 } = {};
y; // => 2
- 默認(rèn)值生效條件是,對(duì)象的屬性值嚴(yán)格等于
undefined
活烙。
let { x:1 } = { x:undefined };
x; // => 1
let { y:2 } = { y:null };
y; // null
字符串的解構(gòu)賦值
字符串也可以解構(gòu)賦值徐裸,這是因?yàn)樽址畷?huì)被轉(zhuǎn)成一個(gè)類(lèi)似數(shù)組的對(duì)象。
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
//類(lèi)似數(shù)組的對(duì)象都有一個(gè)length屬性啸盏,因此還可以對(duì)這個(gè)屬性解構(gòu)賦值
let {length : len} = 'hello';
len // 5
模板字符串
const value = 'o';
let str = `hell${value} world`;
includes()重贺、startsWith()、endsWith()
三個(gè)方法都是用來(lái)確定一個(gè)字符串是否包含在另一個(gè)字符串中
-
includes()
返回布爾值回懦,表示是否找到了參數(shù)字符串 -
startsWith()
返回布爾值气笙,表示參數(shù)字符串是否在原字符串的頭部 -
endsWith()
返回布爾值,表示參數(shù)字符串是否在原字符串的尾部
let str = 'hello world!';
str.includes('el'); // => true
str.startsWith('he');// => true
str.startsWith('e'); // => false
str.endsWith('d!'); // => true
str.endsWith('d'); // => false
- 第二個(gè)參數(shù)表示開(kāi)始搜索的位置
-
endsWith
使用第二個(gè)參數(shù)時(shí)怯晕,表示的是前n
個(gè)字符潜圃。
str.includes('lo',4); // => false
str.startsWith('lo',3); // => true 相當(dāng)于指定開(kāi)始位置
str.endsWith('hel',3); // => true 表示前三個(gè)字符是存在的
實(shí)例方法:repeat()
-
repeat()
方法返回一個(gè)新字符串,表示將原字符串重復(fù)n
次舟茶。
'x'.repeat(3); // => 'xxx'
'x'.repeat(0); // => ''
- 參數(shù)如果是小數(shù)會(huì)向下取整
'x'.repeat(2.9); // => 'xx'
- 參數(shù)如果是負(fù)數(shù)或者
Infinity
谭期,會(huì)報(bào)錯(cuò)堵第,但是0 ~ -1
之間的小數(shù)等同于0
, -
NaN
等同于0
'x'.repeat(-1); // 報(bào)錯(cuò)
'x'.repeat(-0.2); // => '' 參數(shù)認(rèn)為是0
'x'.repeat(NaN); // => ''
- 參數(shù)如果是字符串先轉(zhuǎn)成數(shù)字
'x'.repeat('aaa'); // => ''
'x'.repeat('3'); => 'xxx'
如上:'aaa'
轉(zhuǎn)成數(shù)字是NaN
,NaN
等同于0隧出,所以輸出空字符串
實(shí)例方法:padStart()踏志、padEnd()
字符串補(bǔ)全功能,如果某個(gè)字符串不夠指定長(zhǎng)度鸳劳,會(huì)在頭部或尾部補(bǔ)全狰贯。
'x'.padStart(5, 'ab') // 'ababx'
'x'.padEnd(5, 'ab') // 'xabab'
'1'.padStart(4, 'lx') // 'lxl1'
- 如果原字符串的長(zhǎng)度,等于或大于最大長(zhǎng)度赏廓,則字符串補(bǔ)全不生效涵紊,返回原字符串。
- 如果省略第二個(gè)參數(shù)幔摸,默認(rèn)使用空格補(bǔ)全長(zhǎng)度摸柄。
實(shí)例方法:trimStart()、trimEnd()
ES2019
對(duì)字符串實(shí)例新增了trimStart()
既忆、trimEnd()
這兩方法驱负。
-
trimStart()
:消除字符串頭部的空格 -
trimEnd()
:消除字符串頭部的空格 - 它們都返回新字符串,不會(huì)修改原始字符串
- 除了空格鍵患雇,這兩個(gè)方法對(duì)字符串頭部(或尾部)的 tab 鍵跃脊、換行符等不可見(jiàn)的空白符號(hào)也有效。
const a = ' ab ';
s.trim(); // => "ab"
s.trimStart(); // => "ab "
s.trimEnd(); // => " ab"