let
1.作用域在代碼快中 外部無法獲取let聲明的變量
2.不存在變量提升 var聲明變量前 輸出變量undefined let聲明變量前輸出變量 直接報錯
3.let const 這個區塊聲明變量 從一開始就形成了封閉作用域 凡是在聲明之前使用這些變量 就會報錯
也就是說 在let命令聲明變量之前 該變量都是不可用的 語法上稱為‘暫時性死區’
4.typeof a a是不存在的變量 // undefined
如果 typeof在死區內 也就是 typeof b? let b = 1 typeof直接報錯
5.不允許重復聲明同一個變量 也不能在函數內部重新聲明 參數名和函數體內let的變量名 不能相同
ES6的塊級作用域
1.let實際上為js新增了塊級作用域?
2.{{{{{{作用域可以任意嵌套 let a = 1}} 外層作用域無法讀取內層作用域的變量? console.log(a) // 報錯}}}}}
外層作用域可以定義內層同名變量
不再需要立即執行函數表達式 (function(){}())
3.ES6函數聲明和let類似 允許塊級作用域聲明函數
函數調用也只會在當前自己的作用域內找聲明的函數調用
找不到就找外層的 不會找不相干的層
const命令
1.const只讀 常量不能改變
const必須賦值 只聲明會報錯
并且之后不能重復賦值 不可重復聲明
只在作用域內有效
ES6共有6種聲明方式
var let const import class function
頂層對象的屬性
瀏覽器環境中指的是window對象 node環境中指的是global對象
var function 聲明全局變量 等同于window.變量名
let const class不是
global 對象?
es5 頂層對象 瀏覽器中是window?
瀏覽器和web Worker 里 self也指向頂層對象 但是Node沒有self
Node 頂層對象是global 但其它環境都不支持
沒看懂
數組的解構賦值
按照一定模式從數組和對象中提取值 對變量進行賦值 被稱為結構
let [a,b,c] = [1,2,3]
上面代碼表示從數組中提取值 按照對應位置 對變量賦值
本質上屬于’模式匹配‘ 只要等號兩邊的模式相同 左邊的變量就會被賦予對應的值
let [foo, [[bar], baz]] = [1,[[2],3]] //一一對應
let [, , third] = ['foo','bar','baz'] //third baz
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefinedz // []
結構不成功 變量的值就是undefined
...z 沒有時為空數組? ...是數組
不完全解構
let [x, y] = [1, 2, 3];
x // 1y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1b // 2d // 4
按照結構賦值
let [x,y,z] = new Set(['a','b','c'])
x //a
set解構也可以使用數組解構賦值
解構賦值允許指定默認值
let [foo = true] = []
foo // true
let [x,y='b'] = ['a'] // x = 'a' y = 'b'
let [x, y = 'b'] = ['a', undefined];??// x='a', y='b'
賦值 === undefined默認才會生效
賦值null則默認不生效 =號左側被賦值null
有默認值的情況下 賦值的過程
先按照結構 = 右側向左側賦值 當右側!== undefined時賦值成功 否則是默認值 默認值如果是變量 未被聲明會報錯
function f() { console.log('aaa');}?
let [x = f()] = [1];
解構賦值過程
let x;if ([1][0] === undefined)
{ x = f();}
else { x = [1][0];}
對象的解構賦值
與數組的不同之處 數組的元素是按照次序排列的 變量取值由位置決定 而對象的屬性沒有次序 變量必須與屬性同名才能取到正確的值
對象賦值是先找到對應的屬性 對屬性值進行賦值?
對象也可以指定默認值? ===undefined 默認值生效
let {foo} = {bar: 'bar'} 解構失敗 foo//undefined
let {foo: {bar}} = {baz: 'baz'}; 屬性不存在 取子屬性會報錯
由于數組本質是特殊對象 因此可以對數組進行對象屬性的解構
let arr = [1,2,3,]
let {0:first, [arr.length-1]: last} = arr
first // 1
last //3
索引相當于是屬性名
字符串的結構賦值
字符串會被轉換成一個類似數組的對象
const [a,b,c,d,e] = 'hello'
類似數組的對象都有一個length屬性 因此還可以對這個屬性解構賦值
let {length: len} = 'hello'
len //5
數值和布爾值的解構賦值
數值和布爾值會轉為對象
let {toString: s} = 123
s === Number.prototype.toString // true
相當于 123變成了Number對象 s是toString 這個方法
let {toString: s} = true;
s === Boolean.prototype.toString // true
同上 被轉換成了Boolean對象 s為方法
解構賦值的規則是 只要等號右邊的值不是對象或數組就將其轉換為對象
undefined 和 null 無法轉為對象 所以對他們進行解構賦值 都會報錯
函數參數的結構賦值
function add([x,y]) {
return x + y
}
add([1,2]) // 3
圓括號的問題
建議不要再模式中放置圓括號
不能使用圓括號的情況
(1) 變量的聲明語句
let [(a)] = [1] 報錯
(2) 函數參數
函數參數也屬于變量聲明 因此不能帶有圓括號
(3)賦值語句的模式
({p: a}) = {p: 42} 報錯
圓括號不是很理解 奇奇怪怪
用途
(1)交換變量
let x = 1
let y = 2
[x,y ] = [y,x]
(2)從函數返回多個值
function example() {
?return [1,2,3];
}
let [a,b,c] = example()
function example() {
? ? return {
? ? foo: 1,
? ? bar: 2
}
}
let {foo, bart} = example()
(3)函數參數的定義
解構賦值可以方便的將一組參數與變量名對應起來
// 參數是一組有次序的值function f([x, y, z]) { ... }f([1, 2, 3]);
// 參數是一組無次序的值function f({x, y, z}) { ... }f({z: 3, y: 2, x: 1});
(4)提取json數據
解構賦值對提取json對象中的數據尤其有用
let jsonData = {
? ? id: 42,
? ? status:'OK',
? ? data: [867,5309]
}
let {id, status, data: number} = jsonData;
(5)函數參數的默認值
(6)遍歷Map結構
const map = new Map()
map.set('first','hello')
map.set('second','world')
字符串的拓展
for of 遍歷字符串
let str = 'abc'
for(let v of str) {
`? ? console.log(v)
}
// a
// b
// c
at()
‘abc’.at(0) // a?
瀏覽器支持度不高 建議還是使用charAt()
includes() 返回布爾 表示是否找到了參數字符串
startsWith() 返回布爾 表示參數字符串是否在原字符串頭部
endsWith() 返回布爾 表示參數字符串是否在原字符串尾部
第二個參數標識開始搜索的位置
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
上面代碼表示,使用第二個參數n時,endsWith的行為與其他兩個方法有所不同。它針對前n個字符,而其他兩個方法針對從第n個位置直到字符串結束。
repeat() 返回一個新字符串 標識將原字符串重復n次
‘x’.repeat(3) ‘xxx’
'hello'.repeat(2) 'hellohello'
'na'.repeat(0) ''
參數如果是小數點會被取整
‘na’.repeat(2.9) 'nana'
參數為負數或Infinity 會報錯
參數在0-1和 0到-1之間 以及 NaN等同于0
如果參數是字符串 會被轉換成數字
‘na’.repeat('na') '' //'na'轉換為字符串是NaN所以結果是‘’
'na'.repeat('3') // 'nanana'
padStart 常見用途 為數值補全指定位數?
下面代碼生成10位
‘1’.padStart(10,'0') // 0000000001
'12'.padStart(10,'0') // 0000000012
‘123456’.padStart(10, '0') //0000123456
另一個用途 提示字符串格式
‘12’.padStart(10, 'YYYY-MM-DD') // 'YYYY-MM-12'
'09-12'.padStart(10, 'YYYY-MM-DD') // YYYY-09-12
數組的擴展 擴展運算符
主要用于函數調用
擴展運算符的應用
復制數組
const a1 = [1,2]
const a2 = [...a1]
或
const [...a2] = a1
合并數組
[1,2].concat(more)
[1,2,...more]
[...arr1, ...arr2, ...arr3]
擴展運算符用于數組賦值 只能放在參數最后一位 否則會報錯
字符串轉換數組
[...'hello']
// ['h','e','l','l','o']
Map 和 Set 結構?
映射 和 集合 // 不是很懂
Array.from()
將類似數組的對象和可遍歷的對象(包括Map和Set)轉為數組
let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3};
Array.from(arrayLike) ['a', 'b', 'c']
NodeList對象[...document.querySelectorAll('div')]
直接得到一個NodeList集合
Array.from(NodeList) 轉換為真正的數組
可以將字符串轉換為數組
let str = 'sdfsdf35165'
Array.from(str)
// ['s', 'd', 'f'....]
Array.of() 返回參數組成的數組
Array.of() // []
Array.of(undefined) //[undefined]
Array.of(1) // [1]
find() 找到第一個符合條件的數組成員
參數為回調 第一個滿足回調返回true的成員 返回該成員
[1,4,-5,10].find(n => {n<0}) // -5
回調有三個參數 value 當前值 index 當前索引 arr 原數組 ↓
[1, 5, 10, 15].find(function(value, index, arr) { return value > 9; }) // 10
findIndex 與find類似 返回索引
這兩個方法 可以接受第二個參數 find(f,person) 回調中的this指向第二個參數
function f(v){ return v > this.age; } let person = {name: 'John', age: 20}; [10, 12, 26, 15].find(f, person); // 26
fill() 給定值填充一個數組
['a','b','c'].fill(7) // [7,7,7]
new Array(3).fill(7) // [7,7,7]
還可以接受第二第三個參數 起始位置和結束位置(包頭不包尾)?
[‘a’, 'b', 'c'].fill(7,1,2) // ['a', 7, 'c']
如果參數類型是對象 那么被賦值的是同一個內存地址的對象 而不是深拷貝的對象
let arr = new Array(3).fill({name: "Mike"});
arr[0].name = "Ben"; arr
// [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}] l
et arr = new Array(3).fill([]);
arr[0].push(5); arr // [[5], [5], [5]]
entries() keys() values()
遍歷數組 鍵值對遍歷 鍵遍歷 值遍歷
[1, 2, 3].includes(2) 返回布爾
數組的空位ES6方法會解析成undefined
Object.is()
類似于全等 ===
區別在于 全等 +0 === -0 // true
? ? ? ? ? ? ? ? Object.is(+0, -0) // false
? ? ? ? ? ? ? ? 全等 NaN === NaN // false
? ? ? ? ? ? ? ? Object.is(NaN, NaN) // true
對象的合并? Object.assign()?
第一個參數 目標對象 后面都是源對象
如果有同名屬性 后面的會覆蓋前面的
const target = { a: 1, b: 1 }; const source1 = { b: 2, c: 2 }; const source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3}
如果只有一個參數 會直接返回該參數
如果該參數不是對象則會轉成對象 然后返回
undefined和null做參數 會報錯
如果undefined和null不在第一個參數位置 則不會報錯
字符串做參數 會以數組的形式拷貝入對象 數值和布爾 沒效果
const v1 = 'abc';
const v2 = true;
const v3 = 10;
const obj = Object.assign({}, v1, v2, v3);
console.log(obj); // { "0": "a", "1": "b", "2": "c" }
Object.assign() 拷貝的屬性是有限的 只拷貝源對象自身屬性 不拷貝繼承屬性 不拷貝不可枚舉屬性
注意點
Object.assgin()實現的是淺拷貝 拷貝的是對象的引用
同名屬性會替換
數組視為對象
Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]
數組視為對象則是索引做鍵值做值的對象
所以4在0的位置 會覆蓋1 ,5覆蓋2
函數的處理
Object.assign()參數如果有函數 則是先運行只會拿到值再復制
常見用途
ES6的遍歷
for...in 遍歷對象自身和繼承的可枚舉屬性
Object.keys(obj) 返回一個數組 包含對象自身可枚舉屬性不含繼承的鍵名
Object.getOwnPropertyNames(obj)
返回一個數組 包含對象自身所有屬性 包含不可枚舉屬性的鍵名
ES6
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。