您好,登錄后才能下訂單哦!
這篇文章主要介紹了es2015是不是es6的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇es2015是不是es6文章都會有所收獲,下面我們一起來看看吧。
es2015是es6。es全稱“ECMAScript”,是根據ECMA-262標準實現的通用腳本語言,而由2015年6月正式發布的版本,其正式名為ECMAScript2015(ES2015),因其是ECMAScript的第6個版本,因此可簡稱為es6。
“es”簡介
es全稱“ECMAScript”,是根據 ECMA-262 標準實現的通用腳本語言,ECMA-262 標準主要規定了這門語言的語法、類型、語句、關鍵字、保留字、操作符、對象等幾個部分。每次看到 ES 后面跟著數字,是 ECMAScript 的不同版本。
es6全稱ECMAScript6(ECMAScript的第6個版本),是于2015年6月正式發布的JavaScript語言的標準,正式名為ECMAScript 2015(ES2015)。它的目標是使得JavaScript語言可以用來編寫復雜的大型應用程序,成為企業級開發語言。
ECMAScript 6 目前基本成為業界標準,它的普及速度比 ES5 要快很多,主要原因是現代瀏覽器對 ES6 的支持相當迅速,尤其是 Chrome 和 Firefox 瀏覽器,已經支持 ES6 中絕大多數的特性。
在此后ECMA Script每年發布一個大版本新增加一些重要特性,我們稱之為ES6+。
本文主要總結了ES2015-ES2019的主要特性,一個學習前端的童鞋應該是常用且理解的一些特性。
解決原有語法的一些不足
對原有語法進行增強
全新的對象、全新的方法、全新的功能
Promise、Proxy、Object.assign等
全新的數據類型和數據結構
Symbol、Set、Map等
nodejs查詢
瀏覽器查詢
PC瀏覽器對ES2015的支持情況
Chrome:51 版起便可以支持 97% 的 ES6 新特性。
Firefox:53 版起便可以支持 97% 的 ES6 新特性。
Safari:10 版起便可以支持 99% 的 ES6 新特性。
Edge:Edge 15可以支持 96% 的 ES6 新特性。Edge 14 可以支持 93% 的 ES6 新特性。
IE:IE7 ~ 11 基本不支持 ES6
移動端瀏覽器對ES2015的支持情況
iOS:10.0 版起便可以支持 99% 的 ES6 新特性。
Android:基本不支持 ES6 新特性(5.1 僅支持 25%)
服務器對ES2015的支持情況,具體查看:https://node.green/
Node.js:6.5 版起便可以支持 97% 的 ES6 新特性。(6.0 支持 92%)
只有全局作用域、函數作用域,不存在嚴格的塊級作用域
存在變量提升
變量的聲明和定義可以分開進行
變量可以重復聲明
存在塊級作用域
不能變量提升
變量的聲明和定義可以分開進行
變量不能重復聲明
存在塊級作用域
不能變量提升
變量的聲明和定義必須在同一個語句中
變量不能重復聲明
不能修改聲明過的變量值(例如:可以修改對象的屬性值,不能修改對象地址)
最佳實踐:不用var,主用const,配合let
const [foo, bar, baz] = arr
console.log(foo, bar, baz)
const [, , baz] = arr
console.log(baz)
// 解構剩余的數組元素
// 只能在最后一個位置使用擴展運算符
const [foo, ...rest] = arr
console.log(rest)
// 解構時元素較少,按照順序取元素
const [foo] = arr
console.log(foo)
// 解構時設置默認值
const [foo, bar, baz = 123, more = 'default value'] = arr
console.log(bar, more)
const obj = { name: 'zce', age: 18 }
// 變量名重復時,可以重命名和設置默認值
const name = 'tom'
const { name: objName = 'jack' } = obj
console.log(objName)
支持換行符
支持嵌入變量、表達式
const name = 'tom'
// 可以通過 ${} 插入表達式,表達式的執行結果將會輸出到對應位置
const msg = `hey, ${name} --- ${1 + 2} ---- ${Math.random()}`
console.log(msg)
includes 包含字符串
startsWith 是否以某字符串開頭
endsWith 是否以某字符串結束
const message = 'Error: foo is not defined.'
console.log(
// message.startsWith('Error')
// message.endsWith('.')
message.includes('foo')
)
在function參數后面使用=設置默認值
只有當形參傳遞是undefined或者沒有傳遞值時,才會設置默認值(false也不會)
如果只有部分默認值,需要將設置默認值的代碼放到后面;否則無法正常使用
// 默認參數一定是在形參列表的最后
function foo (bar,enable = true) {
console.log('foo invoked - enable: ')
console.log(enable)
}
foo(false)
只能出現在形參的最后一位
只能使用一次
args是一個數組,區別于arguments是一個偽數組
function foo (first, ...args) {
console.log(args)
}
foo(1, 2, 3, 4)
const arr = ['foo', 'bar', 'baz']
// console.log(
// arr[0],
// arr[1],
// arr[2],
// )
// console.log.apply(console, arr)
console.log(...arr)
插件:Fira Code字體將箭頭畫的更好看
const arr = [1, 2, 3, 4, 5, 6, 7]
// arr.filter(function (item) {
// return item % 2
// })
// 常用場景,回調函數
arr.filter(i => i % 2)
箭頭函數的簡寫
function(value){return value} 等價于 value=>value
箭頭函數的this指向
普通函數的this指向調用它方法的對象
箭頭函數的this和它外面函數的this指向相同,即:箭頭函數不會改變this的指向
// 箭頭函數與 this
// 箭頭函數不會改變 this 指向
const person = {
name: 'tom',
// sayHi: function () {
// console.log(`hi, my name is ${this.name}`)//tom,this指向該函數調用者
// }
sayHi: () => {
console.log(`hi, my name is ${this.name}`) //undefined,this和sayHi()外面的函數this相同
},
sayHiAsync: function () {
// const _this = this
// setTimeout(function () {
// console.log(_this.name) //這里的this為window,所以需要使用_this
// }, 1000)
console.log(this)
setTimeout(() => {
// console.log(this.name) //這里的this指向sayHiAsync里的this,即person
console.log(this)
}, 1000)
}
}
person.sayHi()
person.sayHiAsync()
如果屬性名和值的變量名相同,可以省略一個變量
方法的簡寫:可以省略“:function”
計算屬性名:屬性名可以在[]里面使用任意表達式
const bar = '345'
const obj = {
foo: 123,
// bar: bar
// 屬性名與變量名相同,可以省略 : bar
bar,
// method1: function () {
// console.log('method111')
// }
// 方法可以省略 : function
method1 () {
console.log('method111')
// 這種方法就是普通的函數,this 指向obj。
console.log(this)
},
// Math.random(): 123 // 不允許,使用[]才行
// 通過 [] 讓表達式的結果作為屬性名
[bar]: 123
}
Object.assign是不完全的深拷貝?它究竟拷貝了多少東西?
獲取不到obj中的get、set信息
將源對象中的值賦值到目標對象
目標對象和返回值是同一個對象
如果目標對象中有相同名字的屬性,則覆蓋該屬性
可以傳入多個源對象,按照順序依次覆蓋目標對象
const source1 = {
a: 123,
b: 123
}
const source2 = {
b: 789,
d: 789
}
const target = {
a: 456,
c: 456
}
const result = Object.assign(target, source1, source2)
console.log(target)
console.log(result === target) //true,目標對象和返回值是一個對象
0 == false // => true
0 === false // => false
+0 === -0 // => true
NaN === NaN // => false
Object.is(+0, -0) // => false
Object.is(NaN, NaN) // => true
Proxy的作用
對Object屬性變化進行監聽
對比Object.defineProperty
Proxy屬性的方法中默認調用了Reflect中的方法,例如:
const obj = {
foo: '123',
bar: '456'
}
const proxy = new Proxy(obj, {
get (target, property) {
console.log('watch logic~')
// Proxy中如果不寫,默認調用了此方法
return Reflect.get(target, property)
}
})
Relect提供了統一的操作Object對象的方法,MDN上有完整的13中方法:
// console.log('name' in obj)
// console.log(delete obj['age'])
// console.log(Object.keys(obj))
console.log(Reflect.has(obj, 'name'))
console.log(Reflect.deleteProperty(obj, 'age'))
console.log(Reflect.ownKeys(obj))
// class 關鍵詞
// function Person (name) {
// this.name = name
// }
// Person.prototype.say = function () {
// console.log(`hi, my name is ${this.name}`)
// }
class Person {
// 構造函數
constructor (name) {
this.name = name
}
// 成員變量
age = 18
// 成員函數
say () {
console.log(`hi, my name is ${this.name}`)
}
}
const p = new Person('tom')
p.say()
聲明靜態方法:static關鍵字
調用靜態方法:Person.say
靜態方法的this指向為類
// static 方法
class Person {
constructor (name) {
this.name = name
}
say () {
console.log(`hi, my name is ${this.name}`)
}
static create (name) {
return new Person(name)
}
}
const tom = Person.create('tom')
tom.say()
使用extends繼承
注意super的使用,能夠訪問父類;通常用來執行父類構造函數。
class Person {
constructor (name) {
this.name = name
}
say () {
console.log(`hi, my name is ${this.name}`)
}
}
class Student extends Person {
constructor (name, number) {
super(name) // 調用父類構造函數,否則name就沒有賦值(重要)
this.number = number
}
hello () {
super.say() // 調用父類成員
console.log(`my school number is ${this.number}`)
}
}
const s = new Student('jack', '100')
s.hello()
Set 沒有重復元素的數組集合
常用的成員方法
s.add(item) 添加item,返回集合本身,可鏈式調用
s.size 獲取Set的長度
s.has(item)判斷是否存在某個item
s.delete(item)刪除某個item
s.clear()刪除全部
const s = new Set()
s.add(1).add(2).add(3).add(4).add(2)
// console.log(s)
// s.forEach(i => console.log(i)) //forEach、for...of 都可以用來遍歷Set
// for (let i of s) {
// console.log(i)
// }
// console.log(s.size)
// console.log(s.has(100))
// console.log(s.delete(3))
// console.log(s)
// s.clear()
// console.log(s)
常用來數組去重
// 應用場景:數組去重
const arr = [1, 2, 1, 3, 4, 1]
const result1 = Array.from(new Set(arr))
const result2 = [...new Set(arr)]
console.log(result1,result2)
Map 能使用復雜結構作為屬性的對象集合
以前的對象存儲對象屬性時,會將復雜數據轉換成字符串(toString()方法),如下:
const obj = {}
obj[true] = 'value'
obj[123] = 'value'
obj[{ a: 1 }] = 'value'
console.log(Object.keys(obj))
//0: "123"
//1: "true"
//2: "[object Object]"
使用Map可以存儲復雜數據作為對象屬性,常用的方法有如下:
const m = new Map()
const tom = { name: 'tom' }
m.set(tom, 90)
console.log(m)
console.log(m.get(tom))
// m.has()
// m.delete()
// m.clear()
// forEach可以遍歷Map中的item
m.forEach((value, key) => {
console.log(value, key)
})
一個全新的基礎數據類型,每次創建都是獨一無二的值
let s = Symbol();
typeof s
// "symbol"
let s1 = Symbol('foo');
let s2 = Symbol('foo');
s1 === s2 // false
// for方法是創建的一樣的值,參數會自動轉換成字符串
let s3 = Symbol.for('foo');
let s4 = Symbol.for('foo');
s3 === s4 // true
可以轉換為字符串,通過description(ES2019提供的方法)
let s1 = Symbol('foo');
let s2 = Symbol('foo');
s1 // Symbol(foo)
s2 // Symbol(foo)
s1 === s2 // false
s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(foo)"
s1.description // "foo" // ES2019提供的方法
可以作為對象的屬性名,可以避免同名沖突
const obj = {}
obj[Symbol()] = '123'
obj[Symbol()] = '456'
console.log(obj)
//Symbol(): "123"
//Symbol(): "456"
使用 Symbol 值定義屬性時,Symbol 值必須放在方括號之中,而且不能使用點運算符
let s = Symbol();
// 第一種寫法
let a = {};
a[s] = 'Hello!';
// 第二種寫法
let a = {
[s]: 'Hello!'
};
// 以上寫法都得到同樣結果
a[s] // "Hello!"
可以作為對象的私有成員,不能在外部直接訪問(因為每次訪問都不一樣),只能通過內部this訪問
// 案例2:Symbol 模擬實現私有成員
// a.js ======================================
const name = Symbol()
const person = {
[name]: 'zce',
say () {
console.log(this[name])
}
}
// 只對外暴露 person
// b.js =======================================
// 由于無法創建出一樣的 Symbol 值,
// 所以無法直接訪問到 person 中的「私有」成員
// person[Symbol()]
person.say()
注意:for…in、Obeject.keys、Json.stringify都無法在Symbol上使用
使用:Object.getOwnPropertySymbols,替代Obeject.keys方法用于Symbol
以前的 for…in 遍歷鍵值對,forEach 存在局限性
可以用使用break終止遍歷,forEach不能跳出循環
可以遍歷Array數組、Set和Map對象
普通對象不能被直接 for…of 遍歷,因為它沒有Symbol.iterator屬性
對象(Object)之所以沒有默認部署 Iterator 接口,是因為對象的哪個屬性先遍歷,哪個屬性后遍歷是不確定的,需要開發者手動指定。
所有可以使用 for…of 的對象都需要具有Symbol.iterator屬性
// for...of 循環
const arr = [100, 200, 300, 400]
// for...of 循環可以替代 數組對象的 forEach 方法 但可以使用break跳出循環
arr.forEach(item => {
console.log(item)
})
for (const item of arr) {
console.log(item)
if (item > 100) {
break
}
}
// forEach 無法跳出循環,必須使用 some 或者 every 方法
// arr.forEach() // 不能跳出循環
// arr.some()
// arr.every()
// 遍歷 Set 與遍歷數組相同
const s = new Set(['foo', 'bar'])
for (const item of s) {
console.log(item)
}
// 遍歷 Map 可以配合數組結構語法,直接獲取鍵值
const m = new Map()
m.set('foo', '123')
m.set('bar', '345')
for (const [key, value] of m) {
console.log(key, value)
}
// 普通對象不能被直接 for...of 遍歷
const obj = { foo: 123, bar: 456 }
for (const item of obj) {
console.log(item)
}
一些數據結構的原型對象 _ proto _ 中含有Symbol.iterator方法
iterator方法返回一個帶next()方法的指針對象
每次執行next()方法,它都會返回下一個數據
具有 Symbol.iterator 屬性的數據結構
Array、Map、Set、String、TypedArray、函數的 arguments 對象、NodeList 對象
iterator 的遍歷過程是這樣的。
(1)創建一個指針對象,指向當前數據結構的起始位置。也就是說,遍歷器對象本質上,就是一個指針對象。
(2)第一次調用指針對象的next方法,可以將指針指向數據結構的第一個成員。
(3)第二次調用指針對象的next方法,指針就指向數據結構的第二個成員。
(4)不斷調用指針對象的next方法,直到它指向數據結構的結束位置。
使對象能夠使用 for…of
const obj = {
// 使用計算屬性,用[]存表達式屬性名
// 1、Iterable,對象必須要有一個Symbol.iterator屬性
[Symbol.iterator]: function () {
return {
// 2、Iterator,返回的對象有一個next()方法
next: function () {
// 3、IterationResult,next()方法返回一個對象
return {
value: 'zce',
done: true
}
}
}
}
}
for (const item of obj) {
console.log('循環體', item)
}
使對象能夠使用 for…of,完整的代碼
迭代器模式(設計模式之一)const obj = {
store: ['foo', 'bar', 'baz'],
[Symbol.iterator]: function () {
let index = 0
const self = this
return {
next: function () {
const result = {
value: self.store[index],
done: index >= self.store.length
}
index++
return result
}
}
}
}
for (const item of obj) {
console.log('循環體', item)
}
迭代器的另外一個主要用途:迭代器模式
數組的includes方法
// Array.prototype.includes -----------------------------------
const arr = ['foo', 1, NaN, false]
// 找到返回元素下標
console.log(arr.indexOf('foo'))
// 找不到返回 -1
console.log(arr.indexOf('bar'))
// 無法找到數組中的 NaN
console.log(arr.indexOf(NaN))
// 直接返回是否存在指定元素
console.log(arr.includes('foo'))
// 能夠查找 NaN
console.log(arr.includes(NaN))
指數運算符
// 指數運算符 ---------------------------------------------------
console.log(Math.pow(2, 10))
console.log(2 ** 10)
Object.values —— 類似Object.keys,返回對象的值數組
Object.entries —— 以數組的形式返回對象中的鍵值對,結合for…of可以遍歷obj
const obj = {
foo: 'value1',
bar: 'value2'
}
// Object.values -----------------------------------------------------------
console.log(Object.values(obj))
// Object.entries ----------------------------------------------------------
console.log(Object.entries(obj))
// 比iterator 更簡單,直接先將obj轉換成數組,再使用 for...of
for (const [key, value] of Object.entries(obj)) {
console.log(key, value)
}
console.log(new Map(Object.entries(obj)))
Object.getOwnPropertyDescriptors —— 獲取對象屬性的完整信息,主要配合ES5的get、set使用
Object.assign 獲取不到set、get信息
const p1 = {
firstName: 'Lei',
lastName: 'Wang',
get fullName () {
return this.firstName + ' ' + this.lastName
}
}
// console.log(p1.fullName)
// const p2 = Object.assign({}, p1)
// p2.firstName = 'zce'
// console.log(p2)
const descriptors = Object.getOwnPropertyDescriptors(p1)
// console.log(descriptors)
const p2 = Object.defineProperties({}, descriptors)
p2.firstName = 'zce'
console.log(p2.fullName)
String.prototype.padStart / String.prototype.padEnd
const books = {
html: 5,
css: 16,
javascript: 128
}
// for (const [name, count] of Object.entries(books)) {
// console.log(name, count)
// }
for (const [name, count] of Object.entries(books)) {
console.log(`${name.padEnd(16, '-')}|${count.toString().padStart(3, '0')}`)
}
const arr = [
100,
200,
300,
400,
]
const arr = [
100,
200,
300
]
來自于ES2017標準;async、await能夠更方便的進行異步編程,且通常需要成對使用;
1、async、await相對于generate函數升級提升的地方:
(1)內置執行器
(2)更好的語義
(3)更好的擴展器
(4)返回值是promise
2、async、await的返回值
(1)async的返回值是promise對象;但是需要注意:
1、async函數返回一個 Promise 對象。
2、async函數內部return語句返回的值,會成為then方法回調函數的參數。
async function f() {
return 'hello world';
}
f().then(v => console.log(v))
// "hello world"
(2)await返回值根據后面的參數不同而不同,有兩種;
3、await 后面的參數
(1)await后面跟一個promise對象;=> 返回promise對象的結果;
(2)await后面跟一個值;=> 直接返回該值;
4、錯誤處理方法
如果await后面的promise異步操作出錯,那么等同于async函數返回的 Promise 對象被reject。最好把await命令放在try…catch代碼塊中
async function f() {
await new Promise(function (resolve, reject) {
throw new Error('出錯了');
});
}
f()
.then(v => console.log(v))
.catch(e => console.log(e))
async function myFunction() {
try {
await somethingThatReturnsAPromise();
} catch (err) {
console.log(err);
}
}
// 另一種寫法
async function myFunction() {
await somethingThatReturnsAPromise()
.catch(function (err) {
console.log(err);
});
}
5、并發/循環異步請求的處理
(1)如果是串行執行異步請求,需要同步等待,會比較耗時;
let foo = await getFoo();
let bar = await getBar();
// 1、循環里面的串行執行:
async function dbFuc(db) {
let docs = [{}, {}, {}];
for (let doc of docs) {
await db.post(doc);
}
}
// 2、錯誤的串行執行:?why?思考?forEach里面的async應該是異步同時執行的,沒有await?
function dbFuc(db) { //這里不需要 async
let docs = [{}, {}, {}];
// 可能得到錯誤結果
docs.forEach(async function (doc) {
await db.post(doc);
});
}
(2)并行執行——等待所有響應,再執行下一個步驟;
async function dbFuc(db) {
let docs = [{}, {}, {}];
let promises = docs.map((doc) => db.post(doc));
let results = await Promise.all(promises);
console.log(results);
}
// 或者使用下面的寫法
async function dbFuc(db) {
let docs = [{}, {}, {}];
let promises = docs.map((doc) => db.post(doc));
let results = [];
for (let promise of promises) {
results.push(await promise);
}
console.log(results);
}
(3)并行執行——不等待所有響應,回來一個回調一個;
// 可以不要在for里面await;也不要寫成串行的回調;
// 是在for里面寫異步方法的調用?例如:
let docs = [{}, {}, {}];
for (let doc of docs) {
db.post(doc).then((res)=>{});
}
6、async、await原理(利用generator實現async、await)
async、await底層封裝起來了看不見代碼實現
可以利用iterator或者generator函數,進行封裝實現;參考代碼:(未完待續)
6+1 種原始數據類型 + bigInt(下個版本)
null
undefined
number
string
boolean
Symbol(ES2015)
BigInt(stage-4,下個版本出標準化)
關于“es2015是不是es6”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“es2015是不是es6”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。