ES6 部分知识点总结
1. const let
- const 值是固定的(常量) ,需要赋初始值,常量用大写,块级作用域.
- let 声明的变量具有块作用域的特征。
在同一个块级作用域,不能重复声明变量。
声明的变量不存在变量提升,换一种说法,就是 let 声明存在暂时性死区(TDZ)。
js里对象(引用数据类型)是地址,常量对象地址不能改变,里面的属性可以改变 - 变量提升:先把var定义的内容(赋值不提)提在最前面,let没有变量提升
[ 数组.filter 与forech相似,遍历 true留]
2. 箭头函数
()=>{}
2.1 不绑定this
在箭头函数出现之前,每个新定义的函数都有他自己的this值。(在构造函数的情况下是一个新对象,在严格模式 的函数调用中为 undefined,如果该函数被作为“对象方法”调用则为基础对象等)。
2.2 通过call、apply调用箭头函数
由于箭头函数没有自己的this指针,通过call()、apply()方法调用时,第一个参数会被忽略。(箭头函数中若用了 this,这个this指向包裹箭头函数的第一个普通函数的 this。)
2.3 不绑定arguments
头函数不能使用new操作符
3. rest参数
.function date(...args){} //数组
date('1','2','3')
扩展运算符
4. 迭代器
5.生成器
function one(){
setTimeout(()=>{
console.log(111);
iterator.next();
},1000)
}
function two(){
setTimeout(()=>{
console.log(222);
iterator.next()
},1000)
}
function three(){
setTimeout(()=>{
console.log(333);
iterator.next();
},1000)
}
function * gen(){
yield one();
yield two();
yield three();
}
let iterator = gen();
iterator.next();
6.promise
1. 语法
- 传递异步操作的消息
- 返回的 promise 对象内部属性:
state — 最初是 “pending”,然后在 resolve 被调用时变为 “fulfilled”,或者在 reject 被调用时变为 “rejected”。
result — 最初是 undefined,然后在 resolve(value) 被调用时变为 value,或者在 reject(error) 被调用时变为 error - Promise 对象的构造器(constructor)语法
传递给 new Promise 的函数是executor;executor 会自动运行并尝试执行一项工作。尝试结束后,如果成功则调用 resolve,如果出现 error 则调用 reject。 - 一个被 executor 完成的工作只能有一个结果或一个 error
- then,catch,finally
.catch(f) 与 promise.then(null, f) 一样
finally 处理程序将结果和 error 传递给下一个处理程序。
2.用法
// promise 读取文件const p = new Promise(function(resolve,reject){
fs.readFile('./promise.html',(err,data)=>{
if(err) reject(err);
resolve(data);
});
});
p.then(function(value){
console.log(value.toString());
}, function(reason){
console.log("失败")
});
//ajaxconst p2 = new Promise((resolve,reject)=>{
const xhr = new XMLHttpRequest();
xhr.open("GET","https://api.apiopen.top/");
xhr.send();
xhr.onreadstatechange = function(){
if(xhr.readyState=4){
if(xhr.status>=200 && xhr.status <300){
resolve(xhr.response);
}else{
reject(xhr.status);
}
}
}
});
p2.then(function(value){
console.log(value)
},function(reject){
console.log(reject)
})
7.set && map
Set
是一个特殊的类型集合 —— “值的集合”(没有键),它的每一个值只能出现一次。
new Set(iterable)
—— 创建一个set
,如果提供了一个 iterable 对象(通常是数组),将会从数组里面复制值到 set 中。set.add(value)
—— 添加一个值,返回set
本身set.delete(value)
—— 删除值,如果 value 在这个方法调用的时候存在则返回 true ,否则返回 false。set.has(value)
—— 如果 value 在set
中,返回 true,否则返回 false。set.clear()
—— 清空set
。set.size
—— 返回元素个数。- 我们可以使用
for..of
或forEach
来遍历Set
:
let set = new Set(["oranges", "apples", "bananas"]);
for (let value of set) alert(value);
// 与 forEach 相同:
set.forEach((value, valueAgain, set) => {
alert(value);
});
Map
是一个带键的数据项的集合,就像一个 Object 一样。 但是它们最大的差别是 Map 允许任何类型的键(key)。
它的方法和属性如下:
new Map()
—— 创建 map。map.set(key, value)
—— 根据键存储值。map.get(key)
—— 根据键来返回值,如果 map 中不存在对应的 key,则返回 undefined。map.has(key)
—— 如果 key 存在则返回 true,否则返回 false。map.delete(key)
—— 删除指定键的值。map.clear()
—— 清空 map。map.size
—— 返回当前元素个数。
Map 还可以使用对象作为键。
运行 forEach 函数
与普通对象 Object 的不同点:
- 任何键、对象都可以作为键。
- 有其他的便捷方法,如 size 属性。
let recipeMap = new Map([
['cucumber', 500],
['tomatoes', 350],
['onion', 50]
]);
// 遍历所有的键(vegetables)
for (let vegetable of recipeMap.keys()) {
alert(vegetable); // cucumber, tomatoes, onion
}
// 遍历所有的值(amounts)
for (let amount of recipeMap.values()) {
alert(amount); // 500, 350, 50
}
// 遍历所有的实体 [key, value]
for (let entry of recipeMap) { // 与 recipeMap.entries() 相同
alert(entry); // cucumber,500 (and so on)
}
// 对每个键值对 (key, value) 运行 forEach 函数
recipeMap.forEach( (value, key, map) => {
alert(`${key}: ${value}`); // cucumber: 500 etc
});
//一个已有的普通对象(plain object)来创建一个 Map:Object.entries()
let obj = {
name: "John",
age: 30
};
let map = new Map(Object.entries(obj));
//Object.fromEntries:从 Map 创建对象
let prices = Object.fromEntries([
['banana', 1],
['orange', 2],
['meat', 4]
]);
8.class
语法
- new 会自动调用
constructor()
方法,因此我们可以在constructor()
中初始化对象。 - 类字段重要的不同之处在于,它们会在每个独立对象中被设好,而不是设在
User.prototype
- Class 提供了
"super"
关键字:
- 执行
super.method(...)
来调用一个父类方法。 - 执行
super(...)
来调用一个父类 constructor(只能在我们的 constructor 中)。 - 继承类的 constructor 必须调用
super(...)
,并且 (!) 一定要在使用 this 之前调用。
受保护的属性通常以下划线 _ 作为前缀。
class MyClass {
prop = value; // 属性
constructor(...) { // 构造器
// ...
}
method(...) {} // method
get something(...) {} // getter 方法
set something(...) {} // setter 方法
[Symbol.iterator]() {} // 有计算名称(computed name)的方法(此处为 symbol)
// ...
}
//es5
function phone(price,brand){
this.price=price;
this.brand=brand;
}
phone.prototype.call = function(){
console.log("111");
}
let huawei = new phone(12222,'huawei');
huawei.call();
console.log(huawei);
//es6 class
class shouji{
constructor(price,brand){
this.price=price;
this.brand=brand;
}
call(){
consolle.log("2222");
}
}
let xiaomi = new shouji(12211,'xiaomi');
console.log(xiaomi);
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed = speed;
alert(`${this.name} runs with speed ${this.speed}.`);
}
stop() {
this.speed = 0;
alert(`${this.name} stands still.`);
}
}
class Rabbit extends Animal {
hide() {
alert(`${this.name} hides!`);
}
stop() {
super.stop(); // 调用父类的 stop
this.hide(); // 然后 hide
}
}
let rabbit = new Rabbit("White Rabbit");
rabbit.run(5); // White Rabbit 以速度 5 奔跑
rabbit.stop(); // White Rabbit 停止了。White rabbit hide 了!
静态属性和静态方法
我们可以把一个方法赋值给类的函数本身,而不是赋给它的 “prototype”。这样的方法被称为 静态的(static)。
class Person {
name;
age;
static stand(){
console.log("人类站起来了");
}
run() {
console.log(`${this.age}岁的${this.name}跑起来了`);
}
}
Person.stand();
(new Person('张三',32)).run();
(new Person('11',22)).run();
类继承 super()
//es5 构造函数继承
function Person(sex,age){
this.age=age;
this.sex=sex;
}
Person.prototype.call = function(){
console.log(1111);
}
function Chidren(sex,age,name,phone){
Person.call(this,sex,age);
this.name=name;
this.phone=phone;
}
//设置子集构造函数的原型
Chidren.prototype = new Person;
Chidren.prototype.constructor=Chidren;
//es6 类继承
class Person{
constructor(age,sex){
this.age=age;
this.sex=sex;
}
}
class Chidren extends Person{
constructor(age,sex,name,phone){
super(age,sex);
this.name=name;
this.phone=phone;
}
}
class User {
constructor(name) {
this.name = name;
}
get name() {
return this._name;
}
set name(value) {
if (value.length < 4) {
alert("Name is too short.");
return;
}
this._name = value;
}
}
let user = new User("John");
alert(user.name); // John
user = new User(""); // Name is too short.
9.对象方法扩展
- Object.is(a,b) 判断两个值是否完全相等
- Object.assign(a,b) 对象的合并
- Object.setPrototypeOf 设置原型对象
10.模块化
- export 关键字标记了可以从当前模块外部访问的变量和函数。
- import 关键字允许从其他模块导入功能。
- 如果同一个模块被导入到多个其他位置,那么它的代码仅会在第一次导入时执行,然后将导出(export)的内容提供给所有的导入(importer)。
在实际开发中,顶级模块代码主要用于初始化,内部数据结构的创建,并且如果我们希望某些东西可以重用 — 请导出它。
//index.html
<script type="module" src="hello.js"></script>
//user.js
export let user = "a";
//hello.js
import {user} from './user.js';
document.body.innerHTML = user; // a