ホームページ > 記事 > ウェブフロントエンド > es2015はes6と同じですか?
es2015はes6です。 es の正式名称は「ECMAScript」で、ECMA-262 標準に従って実装されたユニバーサルスクリプト言語です。2015 年 6 月に正式にリリースされたバージョンは、正式には ECMAScript2015 (ES2015) と呼ばれます。ECMAScript の 6 番目のバージョンであるため、 es6 と呼ばれます。
このチュートリアルの動作環境: Windows 7 システム、ECMAScript バージョン 6、Dell G3 コンピューター。
「es」の概要
es の正式名は「ECMAScript」で、ECMA-262 標準に従って実装されたユニバーサル スクリプト言語です。 , ECMA-262規格 主に言語の構文、型、ステートメント、キーワード、予約語、演算子、オブジェクトなどを規定しています。 ES の後に数字が続く場合は、ECMAScript のバージョンが異なることを意味します。
es6 は ECMAScript6 (ECMAScript の 6 番目のバージョン) の略で、2015 年 6 月に正式にリリースされた JavaScript 言語の標準です。 ECMAScript 2015 (ES2015) と呼ばれます。その目標は、JavaScript 言語を使用して複雑な大規模アプリケーションを作成できるようにし、エンタープライズ レベルの開発言語になることです。
ECMAScript 6 は基本的に業界標準になっており、その人気は ES5 よりもはるかに速いです。主な理由は、最新のブラウザ、特に Chrome ブラウザと Firefox ブラウザはすでに ES6 のほとんどの機能をサポートしているためです。
それ以来、ECMA Script は重要な機能を追加するメジャー バージョン (ES6 と呼ばれます) を毎年リリースしてきました。
この記事では主にES2015~ES2019の主な特徴をまとめており、フロントエンド学習用の子供用シューズとして一般的に使用され、いくつかの特徴を理解されているはずです。
新しいデータ型とデータ構造
ES2015 でよく使用される環境のサポート
Chrome: バージョン 51 以降、ES6 の新機能の 97% をサポートできます。
iOS: バージョンから開始10.0 では、ES6 の新機能の 99% をサポートできます。
Node.js: バージョン 6.5 以降、ES6 の新機能の 97% をサポートできます。 (6.0 は 92% をサポート)
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)
const message = 'Error: foo is not defined.' console.log( // message.startsWith('Error') // message.endsWith('.') message.includes('foo') )
// 默认参数一定是在形参列表的最后 function foo (bar,enable = true) { console.log('foo invoked - enable: ') console.log(enable) } foo(false)
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)
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
アロー関数のポイントに###### Object.assign是不完全的深拷贝?它究竟拷贝了多少东西? Proxy的作用 对比Object.defineProperty https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect Set 没有重复元素的数组集合 常用的成员方法 常用来数组去重 Map 能使用复杂结构作为属性的对象集合 以前的对象存储对象属性时,会将复杂数据转换成字符串(toString()方法),如下: 使用Map可以存储复杂数据作为对象属性,常用的方法有如下: 一个全新的基础数据类型,每次创建都是独一无二的值 可以转换为字符串,通过description(ES2019提供的方法) 可以作为对象的属性名,可以避免同名冲突 使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中,而且不能使用点运算符 可以作为对象的私有成员,不能在外部直接访问(因为每次访问都不一样),只能通过内部this访问 注意:for…in、Obeject.keys、Json.stringify都无法在Symbol上使用 以前的 for…in 遍历键值对,forEach 存在局限性 可以用使用break终止遍历,forEach不能跳出循环 可以遍历Array数组、Set和Map对象 普通对象不能被直接 for…of 遍历,因为它没有Symbol.iterator属性 对象(Object)之所以没有默认部署 Iterator 接口,是因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定。 所有可以使用 for…of 的对象都需要具有Symbol.iterator属性 具有 Symbol.iterator 属性的数据结构 Array、Map、Set、String、TypedArray、函数的 arguments 对象、NodeList 对象 iterator 的遍历过程是这样的。 使对象能够使用 for…of 使对象能够使用 for…of,完整的代码 迭代器的另外一个主要用途:迭代器模式 数组的includes方法 指数运算符 Object.values —— 类似Object.keys,返回对象的值数组 Object.getOwnPropertyDescriptors —— 获取对象属性的完整信息,主要配合ES5的get、set使用 String.prototype.padStart / String.prototype.padEnd 来自于ES2017标准;async、await能够更方便的进行异步编程,且通常需要成对使用; 1、async、await相对于generate函数升级提升的地方: 2、async、await的返回值 1、async函数返回一个 Promise 对象。 3、await 后面的参数 4、错误处理方法 如果await后面的promise异步操作出错,那么等同于async函数返回的 Promise 对象被reject。最好把await命令放在try…catch代码块中 5、并发/循环异步请求的处理 (1)如果是串行执行异步请求,需要同步等待,会比较耗时; (2)并行执行——等待所有响应,再执行下一个步骤; (3)并行执行——不等待所有响应,回来一个回调一个; 6、async、await原理(利用generator实现async、await) async、await底层封装起来了看不见代码实现 6+1 种原始数据类型 + bigInt(下个版本) null undefined number string boolean Symbol(ES2015) BigInt(stage-4,下个版本出标准化) 【相关推荐:javascript视频教程、编程视频】
// 箭头函数与 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()
对象字面量
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,目标对象和返回值是一个对象
Object.is
0 == false // => true
0 === false // => false
+0 === -0 // => true
NaN === NaN // => false
Object.is(+0, -0) // => false
Object.is(NaN, NaN) // => true
Proxy 和 Object.defineProperty
对Object属性变化进行监听
参考笔记:https://gitee.com/ymcdhr/e-task/wikis/?sort_id=4053906Reflect(统一的操作Object对象方法)
const obj = {
foo: '123',
bar: '456'
}
const proxy = new Proxy(obj, {
get (target, property) {
console.log('watch logic~')
// Proxy中如果不写,默认调用了此方法
return Reflect.get(target, property)
}
})
// 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))
Promise
Class 类的基本语法
// 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()
Class 中的静态方法static
// 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()
Class 的继承
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、Map
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)
const obj = {}
obj[true] = 'value'
obj[123] = 'value'
obj[{ a: 1 }] = 'value'
console.log(Object.keys(obj))
//0: "123"
//1: "true"
//2: "[object Object]"
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)
})
Symbol
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
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"
let s = Symbol();
// 第一种写法
let a = {};
a[s] = 'Hello!';
// 第二种写法
let a = {
[s]: 'Hello!'
};
// 以上写法都得到同样结果
a[s] // "Hello!"
// 案例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()
使用:Object.getOwnPropertySymbols,替代Obeject.keys方法用于Symbolfor…of 统一遍历方法
// 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)
}
可迭代接口 iterator(主要给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)
}
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)
}
迭代器模式(设计模式之一)
ES2016 新增特性
// 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)
ES2017 新增特性
Object新增方法
Object.entries —— 以数组的形式返回对象中的键值对,结合for…of可以遍历objconst 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.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新增方法
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
]
新增Async/Await异步编程语法糖
2、async函数内部return语句返回的值,会成为then方法回调函数的参数。async function f() {
return 'hello world';
}
f().then(v => console.log(v))
// "hello world"
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);
});
}
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);
});
}
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);
}
// 可以不要在for里面await;也不要写成串行的回调;
// 是在for里面写异步方法的调用?例如:
let docs = [{}, {}, {}];
for (let doc of docs) {
db.post(doc).then((res)=>{});
}
可以利用iterator或者generator函数,进行封装实现;参考代码:(未完待续)ES2019 前定义的数据类型:8种
以上がes2015はes6と同じですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。