李炎恢ECMAScript6 / ES6+(二)

news2024/11/24 2:43:18

16.Set 数据集合

学习要点:
1.Set 数据集合
本节课我们来开始学习 ES6 新增的 Set 数据集合的用法;

一.Set 数据集合

1.ES6 之前只有数组一种数据结构,而现在提供了 Set 和 Map 两种集合;

严格来说,对象不算是一种数据结构

先来打印看看它是什么

let set = new Set();
console.log(set);

在这里插入图片描述

2.Set 集合是一种无重复元素的列表,使用 new Set()方法创建 Set 集合

//创建一个 Set 集合
let set = new Set();
set.add(1);

set.add(2);//这两个合并成一个了
set.add(2);

set.add('2');
set.add('c');
console.log(set); //Set {1,2,'2','c'}
console.log(set.size); //长度 4

在这里插入图片描述

3.我们也可以通过构造函数传递参数的方式进行初始化集合,比如接受一个数组

//通过构造参数初始化集合
let set = new Set([1, 2, 2, 3, 3, 4, 5]);
console.log(set); //Set {1, 2, 3, 4, 5}

在这里插入图片描述

4.使用 has()方法查找是否存在指定元素,注意 2 和’2’是两个元素,不会隐式转换

let set = new Set([1, 2, 2, 3, 3, 4, 5]);
console.log(set.has(2)); //true
console.log(set.has('2')); //false

在这里插入图片描述

5.还可以使用 delete()删除指定元素、clear()清空元素

let set = new Set([1, 2, 2, 3, 3, 4, 5]);
console.log(set); //{ 1, 2, 3, 4, 5 }
console.log(set.delete(2)); //true
console.log(set); //{ 1, 3, 4, 5 }
console.log(set.clear());//undefined
console.log(set);//{}

在这里插入图片描述

6.我们可以使用…语法,将 Set 集合转换为数组

let set = new Set([1, 2, 2, 3, 3, 4, 5]);
let array = [...set];
console.log(array);

在这里插入图片描述

7.我们可以使用 for 或者 forEach 来遍历 Set 集合

let set = new Set([1, 2, 2, 3, 3, 4, 5]);
for (let i of set){
    console.log(i);
}

在这里插入图片描述

let set = new Set([1, 2, 2, 3, 3, 4, 5]);
//forEach 变量
//在 Set 集合中 key 和 value 都是值
//s 表示 set 集合本身
set.forEach(function (key, value, s) {
    console.log(value);
});

在这里插入图片描述

8.Set 集合还提供针对对象的 Weak Set 集合,添加非对象类型会报错

let ws = new WeakSet([1,2,3])

在这里插入图片描述

9.Weak Set 集合支持 add()、has()和 delete()方法

10.Weak Set 不支持遍历,内部隐藏(无法查看内容),不支持 foreach 和 size;

11.对于应用场景来说,存放对象的弱引用,不用担心对象被回收后引发的问题;

//强引用
let set = new Set(),
    obj = {1:1};
set.add(obj);
console.log(set); //引用存在
//移出引用
obj = null;
console.log(set); //引用依然存在

在这里插入图片描述

//弱引用
let ws = new WeakSet(),
    obj = {1:1};
ws.add(obj);
console.log(ws.has(obj)); //引用存在,因为弱引用它是无法查看内部的情况的,只能通过这个方式查看是否存在
//移出引用
obj = null;
console.log(ws.has(obj)); //随着销毁而释放

在这里插入图片描述

17.Map 数据集合

学习要点:
1.Map 数据集合
本节课我们来开始学习 ES6 新增的 Map 数据集合的用法;

一.Map 数据集合

1.ES6 提供了 Map 数据集合,是一种以键值对存储的有序列表;

let map = new Map();
console.log(map);

在这里插入图片描述

//创建 Map 集合
let map = new Map();
map.set('name', 'Mr.Lee'); //.set 添加,支持.set(...).set(...)
map.set('age', 100);
console.log(map);
console.log(map.get('name')); //.get 获取

在这里插入图片描述

2.我们也可以通过构造函数传递参数的方式进行初始化集合,比如接受一个数组

//通过构造参数初始化集合
let map = new Map([
    ['name', 'Mr.Lee'],
    ['age', 100]
]);
console.log(map);

在这里插入图片描述

3.使用 has()检测、delete()删除、clear()清空等对 Map 集合的操作

let map = new Map([
    ['name', 'Mr.Lee'],
    ['age', 100]
]);
console.log(map.has('name')); //true
console.log(map.size); //2
map.delete('name'); //删除
map.clear(); //清空

在这里插入图片描述

4.我们可以使用 forEach 来遍历 Map 集合,至于 for 遍历,下个章节说

let map = new Map([
    ['name', 'Mr.Lee'],
    ['age', 100]
]);

map.forEach((value, key, m) => {
    console.log(key + '-' + value);
    console.log(m);
});

在这里插入图片描述

5.Map 集合还提供针对对象的 Weak map 集合,添加非对象类型会报错

let wm = new WeakMap();

wm.set('1');

console.log(wm);

在这里插入图片描述

6.Weak Map 不支持遍历,内部隐藏(无法查看内容),不支持 foreach 和 size;

let wm = new WeakMap(),
    obj = {};
wm.set(obj);

console.log(wm);

在这里插入图片描述

7.对于应用场景来说,存放对象的弱引用,不用担心对象被回收后引发的问题

和weak set一样

18.迭代器和生成器

学习要点:
1.迭代器和生成器
2.默认迭代接口
本节课我们来开始学习 ES6 新增的迭代器和生成器的用法。

一.迭代器和生成器

1.迭代器(Iterator),用于给数据结构提供统一的访问遍历的机制

2.ES6 之前的迭代器比较麻烦,而现在引入了生成器对象,让迭代器更加容易

3.首先创建一个生成器方法,方法名前面加上*号,迭代的内容之前使用 yield;

//生成器
function *cit() {
yield 1;
yield 2;
yield 3;
}

PS:1,2,3 是我们要遍历的值;下面我们要创建迭代器;

4.迭代器对象的.next()方法,类似指针,每次执行将下移一行;

//迭代器
let it = cit();
//每执行一次.next()将下移一行
console.log(it.next()); //1, false
console.log(it.next()); //2, false
console.log(it.next()); //3, false
console.log(it.next()); //undefined, true

在这里插入图片描述

PS:属性 value 得到值,没有返回 undefined,当没有值了,done 则返回 true;

5.生成器结合循环语句,并且进行传递数组进行迭代

function *cit(items) {
    for (let i = 0 ; items.length; i++) {
        yield items[i]
    }
}
let it = cit([1,2,3,4,5]);
console.log(it.next().value);
console.log(it.next().value);
console.log(it.next().value);
console.log(it.next().value);
console.log(it.next().value);
console.log(it.next().value);

在这里插入图片描述

PS:如果作为匿名函数使用:let cit = function *(items);

二.默认迭代接口

1.很多数据结构类型拥有默认迭代接口,比如:Array、Map、Set 等等

2.对于原生就支持迭代器的数据结构,我们不用自己编写生成器迭代器

3.对于 Array 数组类型,它提供了有关三个方法:keys()、values()和 entries()

let items = [1, 2, 3, 4, 5];
console.log(items.keys()); //key, Object [Array Iterator]
console.log(items.values()); //value, Object [Array Iterator]
console.log(items.entries());//key+value, Object [Array Iterator]

4.最简单的迭代方式,就是使用 for…of 迭代语句去遍历即可

let items = [1, 2, 3, 4, 5];
//for..of 遍历得到 value 值
for (let i of items.values()) {
    console.log(i);
}

在这里插入图片描述

5.虽然 for…of 特别方便,不过你想要用.next()语法也是支持的

let items = [1, 2, 3, 4, 5];

let values = items.values();
console.log(values.next());

在这里插入图片描述

PS:下节课,我们把其它几种数据类型的默认迭代都演示一遍;

19.异步 Promise

学习要点:
1.Promise 介绍
2.实例测试
本节课我们来开始学习 ES6 新增的 Promise 异步通信方案的功能。

一.Promise 介绍

1.Promise:即异步通信编程的一种解决方案,它比传统回调式更加的强大

2.ES6 之前非常多层次嵌套的同步、异步,执行顺序混乱且不好维护

3.Promise 就很好的解决了这些问题,我们先了解一下它的语法

//创建一个 Promise 实例
let p = new Promise((resolve, reject) => {
    //一顿异步通信操作后,返回成功或失败
    //然后判断成功或失败去执行 resolve 或 reject
    if (true) {
        //console.log('异步通信执行成功!');
        resolve('执行成功!');
    } else {
        //console.log('异步通信执行失败!');
        reject('执行失败!');
    }
});


//then 方法可执行 resolve 的回调函数
//catch 方法可执行 reject 的回调函数
// p.then((value) => {
//     console.log(value);
// }).catch((reason) => {
//     console.log(reason);
// });

//或者这种一体化语法也行
p.then((value) => {
    console.log(value);
},(reason)=>{
    console.log(reason);
});

在这里插入图片描述

PS:如果你有过很多层异步通信实战基础,上面提供的方法会突然感觉清晰很多;
PS:因为它把多层嵌套的回调函数给分离出来,通过 then 和 catch 来实现;

3.通过上面例子的语法,我们发现 p 作为 Promise 实例,可以进行连缀链式操作

4.当执行了 then 方法后,本身依旧返回了当前的 Promise 实例,方便链式

5.注释中也说明了,通过构造方法的两个参数去执行回调函数,并传递参数

6.事实上,catch()方法还可以作为 then 第二参数进行存在,方便多层回调

...
p.then((value) => {
    console.log(value);
},(reason)=>{
    console.log(reason);
});

二.实例测试

1.我们做个模拟多层异步通信的实例测试,要异步多个内容,并按指定顺序执行

2.先给出不进行 Promise 异步,看它执行的顺序

//模拟异步 1
setTimeout(() => {
    console.log('1.返回异步通信');
}, 3500);
//模拟异步 2
setTimeout(() => {
    console.log('2.返回异步通信');
}, 800);
//模拟异步 3
setTimeout(() => {
    console.log('3.返回异步通信');
}, 1500);

在这里插入图片描述
PS:这里不管你怎么调节,最终输出结果总是:2,3,1。需求顺序要:1,2,3;

3.将上面模拟异步通信,通过 Promise 进行改装,再看看执行结果

let p1 = new Promise((resolve, reject) => {
//模拟异步 1
    setTimeout(() => {
//console.log('1.异步通信');
        resolve('1.返回异步通信');
    }, 3500);
});
let p2 = new Promise((resolve, reject) => {
//模拟异步 2
    setTimeout(() => {
//console.log('2.异步通信');
        resolve('2.返回异步通信');
    }, 800);
});
let p3 = new Promise((resolve, reject) => {
//模拟异步 3
    setTimeout(() => {
//console.log('3.异步通信');
        resolve('3.返回异步通信');
    }, 1500);
});
//执行回调
p1.then((value) => {
    console.log(value);
    return p2;
}).then((value) => {
    console.log(value);
    return p3;
}).then((value) => {
    console.log(value);
});

在这里插入图片描述

20.Promise 状态特点

学习要点:
1.状态特点
2.更多方法
本节课我们来开始学习 ES6 新增的 Promise 异步通信方案的状态特点

一.状态特点

1.回顾上一节:Promise 解决了异步多层回调混乱,且执行顺序的问题

2.本节课,了解一下 Promise 对象异步操作的三种状态

(1) .Pending(进行中)
(2) .Fulfilled(已成功)
(3) .Rejected(已失败)

3.当异步操作执行后,它得到的结果来决定其状态,其它任何操作都无法改变

4.Promise 状态只有两种运行方式:从 Pending 到 Fulfilled 或 Rejected;

5.而当状态已经固定后,此时就变成 Resolved(已完成)。关键字详解:请搜索;

pending -> resolve 方法 -> fulfilled -> resolved
pending -> reject 方法 -> rejected -> resolved

PS:测试当前状态,在浏览器环境下比较直观直接:console.log(p1),在不同阶段执行;node环境下看得不明显,用浏览器测试

let p1 = new Promise((resolve, reject) => {
//模拟异步 1
    setTimeout(() => {
//console.log('1.异步通信');
        resolve('1.返回异步通信');
    }, 3500);
});
let p2 = new Promise((resolve, reject) => {
//模拟异步 2
    setTimeout(() => {
//console.log('2.异步通信');
        resolve('2.返回异步通信');
    }, 800);
});
let p3 = new Promise((resolve, reject) => {
//模拟异步 3
    setTimeout(() => {
//console.log('3.异步通信');
        resolve('3.返回异步通信');
    }, 1500);
});

console.log(p1);


//执行回调
p1.then((value) => {
    console.log(p1);
    console.log(value);
    return p2;
}).then((value) => {
    console.log(value);
    return p3;
}).then((value) => {
    console.log(value);
});

在这里插入图片描述

二.更多方法

1.上一节课,我们使用了三组 Promise 实例完成三段异步的排序输出问题

但是那个看起来还是太长了,下面有好的解决方案

2.Promise 提供了一个 all()方法,可以简化多个实例调用输出排序



let p1 = new Promise((resolve, reject) => {
//模拟异步 1
    setTimeout(() => {
//console.log('1.异步通信');
        resolve('1.返回异步通信');
    }, 3500);
});
let p2 = new Promise((resolve, reject) => {
//模拟异步 2
    setTimeout(() => {
//console.log('2.异步通信');
        resolve('2.返回异步通信');
    }, 800);
});
let p3 = new Promise((resolve, reject) => {
//模拟异步 3
    setTimeout(() => {
//console.log('3.异步通信');
        resolve('3.返回异步通信');
    }, 1500);
});

console.log(p1);


//执行回调
// p1.then((value) => {
//     console.log(p1);
//     console.log(value);
//     return p2;
// }).then((value) => {
//     console.log(value);
//     return p3;
// }).then((value) => {
//     console.log(value);
// });

//all方法,可以解决上面那一大堆, p1,p2,p3 是三个 Promise 实例,数组元素顺序即输出顺序
let p = Promise.all([p1, p2, p3]);
//将三个 Promise 实例的回调组合成数组输出
p.then(value => {
    console.log(value);
})

在这里插入图片描述
PS:虽然 p1,p2,p3 都是异步操作,但最终要等待所有异步完成,才可以输出;
PS:只要 p1,p2,p3 中有一个出现了 Rejected,则会执行失败回调

3.Promise 提供了一个 race()方法,只输出第一个改变状态的实例

//p1,p2,p3 只要有一个改变状态,即回调
let p = Promise.race([p1, p2, p3]);
//所以,这里只输出 p2
p.then(value => {
    console.log(value);
});

在这里插入图片描述

4.Promise 提供了 resolve()和 reject(),直接返回一个成功或失败的实例

//直接返回成功或失败的 Promise 实例
let ps = Promise.resolve('成功');
let pj = Promise.reject('失败');
ps.then(value => {
console.log(value);
return pj;
}).catch(reason => {
console.log(reason);
})

等价于

new Promise(resolve => resolve('成功'));

那这样的快捷语法糖有什么用呢?下面是一个例子

function getP() {
if (false) {
return new Promise(resolve => {
resolve('异步成功');
})
} else {
return 0; //强制类型一致保证程序正确性 Promise.resolve(0)
}
}

getP().then(value => {
console.log(value);
});

这样就可能出问题,因为你很有可能会读取失败,我们要保持返回类型的一致性,就可以通过这种语法糖快速调用 resolve回调

function getP() {
if (false) {
return new Promise(resolve => {
resolve('异步成功');
})
} else {
//return 0; //强制类型一致保证程序正确性 Promise.resolve(0)
return Promise.resolve(0);
}
}

//这里你调用.then就肯定可以成功
getP().then(value => {
console.log(value);
});

21.代理 Proxy

学习要点:
1.代理能力
本节课我们来开始学习 ES6 新增的 Proxy 代理方法。

一.代理能力

1.什么是代理?即:给目标对象封装一层拦截,外界访问必须先通过这层拦截

2.举个例子:猎头招聘,你自己发布招聘会暴露自身信息,而通过中介则安全的多

3.首先,我们先来看下代理 Proxy 的语法

//目标对象
let obj = {
    name : 'Mr.Lee',
    age : 100,
    gender : '男'
};
//创建一个代理,参数 1 拦截的目标对象,参数 2 拦截行为
//参数 2 如果是空对象,代理直接会调用目标对象
let p = new Proxy(obj, {
//get 方法用于拦截某个属性的读取操作
    //这里直接 return,通过代理对象无论访问目标对象的任何属性都是 fail
    get(target, property) {
        return 'fail';
    },
});
//代理对象访问 name 为 fail
console.log(p.name);

在这里插入图片描述

4.如果想让代理对象公布出合适的信息,可以通过 get()两个参数来实现

//目标对象
let obj = {
    name : 'Mr.Lee',
    age : 100,
    gender : '男'
};
//创建一个代理,参数 1 拦截的目标对象,参数 2 拦截行为
//参数 2 如果是空对象,代理直接会调用目标对象
let p = new Proxy(obj, {
    //get 方法用于拦截某个属性的读取操作
    get(target, property) {
        if (property === 'age') {
            return target[property] - 80;
        }
    },
});
console.log(p.name);//undefined
console.log(p.age);//20
console.log(p.abc);//不存在的属性 undefined

在这里插入图片描述

4.我们也可以通过 set()方法来对代理对象的属性进行赋值,有三个参数

//目标对象
let obj = {
    name : 'Mr.Lee',
    age : 100,
    gender : '男'
};
//创建一个代理,参数 1 拦截的目标对象,参数 2 拦截行为
//参数 2 如果是空对象,代理直接会调用目标对象
let p = new Proxy(obj, {
    //get 方法用于拦截某个属性的读取操作
    get(target, property) {
        if (property === 'age') {
            return target[property];
        }
    },

    //set 可以拦截某个属性的赋值操作,比 get 多了参数 3
    set(target, property, value) {
        if (property === 'age') {
            if (!Number.isInteger(value) || value > 150) {
                throw new TypeError('年龄数据不合法!');
            }
            target[property] = value;
        }
    }
});

p.age = 150;
// p.age = 200;//年龄数据不合法!

console.log(p.age);//150
console.log(obj.age); //150 目标对象属性也被更改

在这里插入图片描述

PS:代理并不是复制克隆目标对象,只是拦截目标对象更改默认行为;
PS:代理可以使用 set()和 get()方法,对目标对象的数据进行过滤和验证;
PS:代理对象中任何未公开或不存在的属性,可自定义返回内容,比如:fail 或已屏蔽;
PS:代理也可以阻止赋值的默认行为:直接 return false,就禁止赋值了;

set(target, property, value) {
return false;
}

22.异步 async

学习要点:
1.async 语法
本节课我们来开始学习 ES8 新增的异步 async 方法。

一.async 语法

1.async 也是处理异步的,它是对 Promise 的一种扩展,让异步更加方便

2.优势:async 是基于 Promise 的,虽然是异步操作,但看上去像同步

3.首先,我们先来看下 async 的基本语法

let p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('1.返回异步通信');
    }, 3500);
});
let p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('2.返回异步通信');
    }, 800);
});
let p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('3.返回异步通信');
    }, 1500);
});


//创建一个 async 函数,执行异步操作
//await 关键字:等待异步执行完毕后回调;
let as = async () => {
    let result = await p1;
    console.log(result);
};
//执行 async 函数
as();

PS:上面语法,用 ES5 过渡一下,帮助理解,具体如下:
async function as() {}
let as = async function () {}
let obj = {async as() {}}; //也支持对象方式

在这里插入图片描述

4.如果有三个异步需要列队输出,我们用 async 语法来处理一下

//多个异步,按输出顺序加载,没有 then,清晰很多
async function as() {
    let r1 = await p1,
        r2 = await p2,
        r3 = await p3;
    console.log(r1);
    console.log(r2);
    console.log(r3);
}
as();

在这里插入图片描述
PS:await 关键字只能在 async 函数内部,否则不可识别;
PS:从上面的例子中,能感受到语义和清晰度都得到了很大提升,更像同步代码;

5.批量异步列队,类似 Promise.all()

async function as() {
    let all = [await p1, await p2, await p3];
    console.log(all);
}
as();

在这里插入图片描述

6.async 函数如果设置了返回值,这个值是 Promise 对象

//返回值是 Promise 对象
//相当于 Promise.resolve()
async function as() {
    return 'hello, async!';
}

//所以还需要 Promise 对象的then
as().then(value => {
    console.log(value);
});

在这里插入图片描述

7.如果 return await p;这种,会导致提前输出 pending 状态,还是需要 then;

async function as() {
    return await p1;
}
console.log(as()); //得到的是 Promise 对象的 pending 状态
as().then(value => { //这里还是需要 then
    console.log(value);
});

在这里插入图片描述

23.类 class 实现

学习要点:
1.类 class
2.getter 和 setter
本节课我们来开始学习 ES6 新增的类 class 的实现方法。

一.类 class

1.在 ES6 之前,JavaScript 不能像其它语言(PHP,Java)等有完整的类支持;

2.我们采用了原型链实现了面向对象的功能,但从 ES6 开始,提供了真正的类语法

3.当然,虽然说是真正的类语法,而本质上内部实现和原型链还是一样的;

4.对于面向对象和类的基础概念,这里不再赘述,学到这里不可能没这个基础的

5.首先,我们创建一个基本的类,并创建构造函数(构造方法),具体如下

//创建一个类
class Person {
    //构造函数(构造方法)
    constructor(name) {
    //this.name 是类的属性
    //name 是构造参数赋值给属性
        this.name = name;
    }
    //普通方法
    run() {
        console.log('类的方法输出!' + this.name);
    }
}

//实例化一个 Person 对象
let p = new Person('Mr.Lee');
//执行 run()方法
p.run();

//给成员属性赋值
p.name = 'Mr.wang';

//输出对象的属性
console.log(p.name);
//判断 p 是否是 Person 对象
console.log(p instanceof Person);
//判断类的类型:function
console.log(typeof Person);

在这里插入图片描述

6.除了上面的 class Person 这种常规类的写法外,ES6 还支持表达式写法

注意:这里是javascropt才有的写法

//No.1
let Per = class Person {};
//此时 new Person 会报错
let p = new Per('Mr.Lee');
//No.2
let Person = class {};
//No.3
let p = new class {}('Mr.Lee');
p.run();

二.getter 和 setter

1.根据面向对象的三大定律中成员属性,我们需要对它进行封装,变成私有属性

2.而目前的 this.name,基本是对外公开的,可以在类外取值和赋值

3.当我们假设类的属性是私有的,那么需要通过 get()和 set()方法实现

// //创建一个类
// class Person {
//     //构造函数(构造方法)
//     constructor(name) {
//     //this.name 是类的属性
//     //name 是构造参数赋值给属性
//         this.name = name;
//     }
//     //普通方法
//     run() {
//         console.log('类的方法输出!' + this.name);
//     }
// }
//
// //实例化一个 Person 对象
// let p = new Person('Mr.Lee');
// //执行 run()方法
// p.run();
//
// //给成员属性赋值
// p.name = 'Mr.wang';
//
// //输出对象的属性
// console.log(p.name);
// //判断 p 是否是 Person 对象
// console.log(p instanceof Person);
// //判断类的类型:function
// console.log(typeof Person);

//创建一个类
class Person {
    #name; //提案,浏览器暂时不支持
    //构造函数(构造方法)
    constructor(name) {
        this.#name = name; //私有属性,类外无法访问
    }
    get name() {
        return this.#name;
    }
    set name(value) {
        this.#name = value;
    }
}
let p = new Person('Mr.Lee');
//
// // p.#name = 'Mr.Wang'; // Private field '#name' must be declared in an enclosing class 直接不给修改
//
// p.name = 'Mr.Wang';
// console.log(p.name); //为什么这两句可以呢?

//因为上面两句,其实它并没有访问私有成员属性,而是自己创建了一个属性name,就相当于下面的代码
// let obj = {};
// obj.name = 'Mr.wang';
// console.log(obj.name);


//所以这就是容易混淆的地方,此时我们应该访问的是 #name, 那么#name 是私有的属性,那么我们应该怎么访问和修改呢?同时又要拦截外部 name的访问?
//利用 get set 同时名字取成和name相同的名字,就可以防止外部修改了。





24.类 class 继承

学习要点:
1.类的继承
本节课我们来开始学习 ES6 新增的类 class 的继承功能

一.类的继承

1.ES6 也支持子类继承父类,使用 extends 关键字实现

class Person {

    constructor(name) {
        this.name = name;
    }

    get user() {
        return this.name;
    }

    set user(value){
        this.name = value;
    }

    run() {
        return 'name:' + this.name;
    }

}

class Son extends Person {

}


//可以使用父类的构造
let c = new Son('Mr.li');
console.log(c.name);

//get,set 以及方法均可使用
c.user = 'Mr.Wang';
console.log(c.user);
console.log(c.run());

在这里插入图片描述

2.继承之后,一般来说,我们需要覆写父类,然后对子类进行增强

class Person {

    constructor(name) {
        this.name = name;
    }

    get user() {
        return this.name;
    }

    set user(value){
        this.name = value;
    }

    run() {
        return 'name:' + this.name;
    }

}

class Son extends Person {
//子类继承
    constructor(name, age) { //覆写构造
        super(name); //执行父类构造并传参
        this.age = age;
    }
    run() { //覆写方法
        return super.run() + this.age; //执行父类方法并返回内容
    }
}
//覆写
let son = new Son('Mr.Lee', 100);
console.log(son.age);//子类构造自己传递进来的age
console.log(son.run());//先执行父类的方法,然后再执行子类自己的处理

在这里插入图片描述

3.可以使用 Object.getPrototypeOf()判断子类是否继承了父类

console.log(Object.getPrototypeOf(Children) === Person);

在这里插入图片描述

4.ES6 的类支持静态属性和方法,也支持静态被子类继承

class Person {
    static gender = '男';
    static go() {
        return 'GO GO GO !' + Person.gender;//类名调用静态属性
    }
}
class Children extends Person {
    static gender = '女'; //覆写静态
    static go() {
        return 'o o o ' + Person.gender;//这里使用 Person 和 Children 是不一样的  如果这里使用 this.就等于Children类
    }
}

console.log(Person.gender);//男
console.log(Person.go());//调用Person的静态方法


console.log(Children.gender);
console.log(Children.go());

在这里插入图片描述

拓展:es5演示静态方法和实例方法

let Animal = function (type) {
  this.type = type
}
 
// 动态方法
Animal.prototype.walk = function(){
  // 调用静态方法
  Animal.eat()
  console.log('I am walking')
}
 
// 静态方法
Animal.eat = function (food) {
  console.log(`I am eating`);
}
 
let cat = new Animal('cat')
cat.walk()
cat.eat()

在这里插入图片描述

25.Module 模块化

学习要点:
1.浏览器加载
2.Node 加载
本节课我们来开始学习 ES6 新增的模块化导入导出的方法。

一.ES6 模块化

0.在以前我们是怎么做的?

在这里插入图片描述

1.ES6 支持模块化设计,也能其它后端语言一样使用导入导出的功能

2.我们首先,创建一个要被导入的模块 module.js,具体如下

export let name = 'Mr.Lee'; //导出这个变量

PS:里面有很多变量,导出那个那个才可以用,其它不可见

3.再创建一个普通的.js 文件,比如 25.js,然后导入 module.js;

import {name} from './module.js';
console.log(name);

4.最后一步,在.html 文件要加载 25.js 文件,才有小,注意 type 格式;

<script type="module" src="js/25.js"></script>

PS:注意,这种导入导出的方式属于 ES6 模块,仅支持浏览器模式;
如果不设置type="module"则会报错
在这里插入图片描述
在这里插入图片描述

5.除了导出变量、常量之外,还可以导出函数、类等功能

export let name = 'Mr.Lee'; 

export function sum(x, y) {
    return x + y;
}
export class Person {
    constructor(name) {
        this.name = name;
    }
    run() {
        return 'name : ' + this.name;
    }
}

import {name, sum, Person} from './module.js';
console.log(name);
console.log(sum(10, 20));
console.log((new Person('Mr.Lee')).run());

在这里插入图片描述

6.也支持使用*号,将所有导出的内容全部加载进来

import * as obj from './module.js';
console.log(obj.name);
console.log(obj.sum(10, 20));
console.log((new obj.Person('Mr.Lee')).run());

7.支持别名设定,设定别名后,源名即失效了

import {name as user} from './module.js';
console.log(user); //name 无效了

8.统一导出方案,不需要再每一个导出的内容设置 export

let name = 'Mr.Lee';

function sum(x, y) {
    return x + y;
}

class Person {
    constructor(name) {
        this.name = name;
    }

    run() {
        return 'name : ' + this.name;
    }
}

export {
    name,
    sum,
    Person
}

在这里插入图片描述

9.可以给导出设置一个默认值,导入部分就可以不用花括号了

export default name;

import name from './module.js';//导入得时候直接name就可以了

import name, {sum, Person} from './module.js';//如果还要引入别的,逗号,+花括号

二.Node 加载

1.Node 下有自己的导出和导入的加载模式:CommonJS 规范

新建common.js文件

let name = 'Mr.Lee';
module.exports = {
name : name,
};
const name = require('./common.js');
console.log(name);

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/58532.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PC辉光效果一切正常,安卓辉光却没效果、显示异常(爆闪、黑屏等)

一&#xff1a;安卓端辉光不显示问题 问题描述&#xff1a;项目中使用unity的PostProcessing package实现辉光的功能&#xff0c;在pc上辉光效果一切正常&#xff0c;但是打出apk在真机测试时&#xff0c;辉光基本没效果。 解决思路&#xff1a;PostProcessing Bloom效果需要有…

【ArcGIS微课1000例】0056:将单波段栅格背景设置为无数据NoData的方法

本文讲解将单波段栅格背景设置为空值的方法,以DEM数据为例。 文章目录 一、DEM设置无数据二、注意事项单波段数据,一般只有DEM,遥感单波段影像,二值化图像等。 使用珊格计算器通过SetNull 函数(设定空值函数)可以将特定值计算为空值(NoData),SetNull的语法格式为: Se…

[附源码]Python计算机毕业设计Django教育企业网站

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

4-5:关注,取消关注

需求 开发关注、取消关注功能。 统计用户的关注数、粉丝数。 关键 若A关注了B&#xff0c;则A是B的Follower (粉丝)&#xff0c;B是A的Followee (目标)。关注的目标可以是用户、帖子、题目等&#xff0c;在实现时将这些目标抽象为实体。 也是将数据存储到redis中&#xff0c;…

LeetCode刷题复盘笔记—一文搞懂0 - 1背包之494. 目标和问题(动态规划系列第九篇)

今日主要总结一下动态规划0-1背包的一道题目&#xff0c;494. 目标和问题 题目&#xff1a;494. 目标和 Leetcode题目地址 题目描述&#xff1a; 给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘’ 或 ‘-’ &#xff0c;然后串联起所有整数&#…

国外网友分享如何从零开始打造一辆真正的自动驾驶汽车

在 2021 年夏天大学二年级结束后,我决定从事当时最先进的项目之一——从头开发自动驾驶软件并在真车上实现。在公开我的代码的一些主要部分并发布演示视频后,我收到了很多关于该项目的问题。因此,我决定分享开发过程背后的故事。 我一直对与人工智能和机器学习相关的任何事…

Java代码审计——ClassLoader 类加载机制

目录 前言&#xff1a; (一&#xff09;类加载机制 0x01 ClassLoader 类 0x02 loadClass()方法的流程 0x03 自定义的类加载器 0x04 loadClass()方法与 Class.forName 的区别 0x05 URLClassLoader &#xff08;二&#xff09;Java 动态代理 0x01 静态代理 0x02 动态代理…

2022最新 MySQL 内部技术架构面试题

更多面试题&#xff1a;https://javaxiaobear.gitee.io/ 47、MySQL内部支持缓存查询吗&#xff1f; 当MySQL接收到客户端的查询SQL之后&#xff0c;仅仅只需要对其进行相应的权限验证之后&#xff0c;就会通过Query Cache来查找结果&#xff0c;甚至都不需要经过Optimizer模…

dot product【点积】

&#xff08;1&#xff09;概念 点积在数学中&#xff0c;又称数量积&#xff08;dot product; scalar product&#xff09;&#xff0c;是指接受在实数R上的两个向量并返回一个实数值标量的二元运算。 两个向量a [a1, a2,…, an]和b [b1, b2,…, bn]的点积定义为&#xff…

点云数据集ShapeNet

目录 1. 数据采集的作者 2. 下载shapenet数据集的代码 3. 数据特点 3.1 每个数字文件夹代表一个类别 3.2 synsetoffset2category.txt 3.3 train_test_split文件夹 3.4 pts点云文件 3.6 seg分割类别文件 1. 数据采集的作者 article{yi2016scalable,title{A scalable ac…

idea导入eclipse项目的时候,Java图标变成黄色小J了,怎么解决?

凯哥今天导入一个15年时候写的小项目&#xff0c;当时使用的是eclipse写的。最近好几年都在使用idea&#xff0c;习惯了idea的&#xff0c;在用eclipse&#xff0c;不习惯&#xff0c;不顺手&#xff0c;就导入到idea中。发现&#xff0c;Java文件的图标变成了黄色的J。如下图&…

【Linux】详解套接字编程

文章目录网络套接字1.端口号1.1认识端口号1.2端口号VS PID2.TCP与UDP协议3.网络字节序4.socket编程4.1常用接口4.2sockaddr结构4.3.socket接口的底层工作4.4字符串IP VS 整形IP4.5 bind与INADDR_ANY5.UDP聊天服务器5.1va_start和va_end5.2vsnprintf函数5.3自定义日志类5.4UDP服…

【RTS】杜金房大神FreeSwitch分享笔记

技术万变不离其宗不管如何实现原理都是一样的。杜金房大神 RTS 高可用 一台机器上俩fs,公用同一个ip用户连接的是一个ip,不知道切了fs。两台主备数据同步

ARM 汇编编写 LED 灯

一、一步步点亮LED 1. 硬件工作原理及原理图查阅 LED 本身有 2 个接线点&#xff0c;一个是 LED 的正极&#xff0c;一个是 LED 的负极。LED 这个硬件的功能就是点亮或者不亮&#xff0c;物理上想要点亮一颗 LED 只需要给他的正负极上加正电压即可&#xff0c;要熄灭一颗 LED…

Linpack安装测试流程记录

软件背景 虽然很早就接触了HPC&#xff0c;也参与过一些项目&#xff0c;诸如电影动画渲染集群以及某博导老师的基因分析计算集群&#xff0c;但是对于跑超算的linpack&#xff0c;一直没时间上手玩。 Linpack是超算必测项目,也是考验优化能力的套件,很有意思&#xff0c;记录…

软件测试工程师到底要不要转行开发? 2022测试生涯该如何转型升级?

测试工程师到底是干啥的&#xff1f; 测试工程师转开发有多大希望&#xff1f; 为了能够解除大家心中的疑惑&#xff0c;我决定从以下几个方面来补充回答&#xff1a; 测试工程师到底是干什么的&#xff1f; 测试工程师转开发有多大希望&#xff1f; 测试工程师一定要转开发吗…

2023秋招,Java岗最全面试攻略,吃透25个技术栈Offer拿到手软!

我分享的这份春招 Java 后端开发面试总结包含了 JavaOOP、Java 集合容器、Java 异常、并发编程、Java 反射、Java 序列化、JVM、Redis、Spring MVC、MyBatis、MySQL 数据库、消息中间件 MQ、Dubbo、Linux、ZooKeeper、 分布式 &数据结构与算法等 25 个专题技术点&#xff0…

腾讯云服务器2核4G、4核8G、8核16G、16核32G配置报价表出炉

现在腾讯云服务器2核2G、2核4G、4核8G、8核16G、16核32G配置价格表已经出来了&#xff0c;大家可以参考一下。腾讯云轻量应用服务器为轻量级的云服务器&#xff0c;使用门槛低&#xff0c;按套餐形式购买&#xff0c;轻量应用服务器套餐自带的公网带宽较大&#xff0c;4M、6M、…

rocketmq安装、启动

1、下载 >wget http://mirror.bit.edu.cn/apache/rocketmq/4.4.0/rocketmq-all-4.4.0-source-release.zip >unzip rocketmq-all-4.4.0-source-release.zip > cd rocketmq-all-4.4.0/ > mvn -Prelease-all -DskipTests clean install -U > cd distribution/targ…