一、Set
ES6提供了新的数据结构——Set(集合)。它类似于数组,但成员的值都是唯一的,Set实现了iterator(迭代器)接口,所以可以使用【扩展运算符】和【for of】进行遍历。
初识Set
//声明一个Set
let s = new Set();
console.log(s, typeof s); // Set(0) {size: 0} 'object'
除了创建一个新的集合之外,还可以在里面传入一个初始参数(可接收可迭代数据,一般是传入一个数组)
let s2 = new Set([
"大事儿",
"小事儿",
"好事儿",
"坏事儿",
"小事儿",
"大事儿",
]);
console.log(s2); Set(4) {'大事儿', '小事儿', '好事儿', '坏事儿'}
可以自动实现数组去重
Set集合的属性和方法有以下这些
1)size 返回集合的元素个数
let s2 = new Set([
"大事儿",
"小事儿",
"好事儿",
"坏事儿",
"小事儿",
"大事儿",
]);
console.log(s2.size); // 4
2)add 增加一个新元素,返回当前集合
let s2 = new Set([
"大事儿",
"小事儿",
"好事儿",
"坏事儿",
"小事儿",
"大事儿",
]);
s2.add("喜事儿");
console.log(s2); //Set(5) {'大事儿', '小事儿', '好事儿', '坏事儿', '喜事儿'}
3)delete 删除元素,返回boolean值
let s2 = new Set([
"大事儿",
"小事儿",
"好事儿",
"坏事儿",
"小事儿",
"大事儿",
]);
s2.delete("坏事儿");
console.log(s2); //Set(3) {'大事儿', '小事儿', '好事儿'}
4)has 检测集合中是否包含某个元素,返回boolean值
let s2 = new Set([
"大事儿",
"小事儿",
"好事儿",
"坏事儿",
"小事儿",
"大事儿",
]);
let aaa = s2.has("坏事儿");
console.log(aaa); //true
5) clear 清空集合
let s2 = new Set([
"大事儿",
"小事儿",
"好事儿",
"坏事儿",
"小事儿",
"大事儿",
]);
s2.clear();
console.log(s2); //Set(0) {size: 0}
Set集合实践
1)数组去重
let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let result = [...new Set(arr)]; //new Set(arr) 是一个集合,不是数组,所以需要扩展运算符展开
console.log(result); //[1, 2, 3, 4, 5]
2)交集
let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let arr2 = [4, 5, 6, 5, 6];
let result = [...new Set(arr)].filter((item) => {
let s2 = new Set(arr2);
if (s2.has(item)) {
return true;
} else {
return false;
}
});
console.log(result); // [4, 5]
3)并集
let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let arr2 = [4, 5, 6, 5, 6];
let union = [...new Set([...arr, ...arr2])];
console.log(union); //[1, 2, 3, 4, 5, 6]
4)差集
let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let arr2 = [4, 5, 6, 5, 6];
let diff = [...new Set(arr)].filter((item) => !new Set(arr2).has(item));
console.log(diff); // [1, 2, 3]
二、Map
ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用【扩展运算符】和【for of】j进行遍历。
初识Map
//声明Map
let m = new Map();
//添加元素
m.set("name", "尚硅谷");
m.set("change", function () {
console.log("学习前端");
});
console.log(m);
//声明Map
let m = new Map();
let key = {
school: "ATGUIGU",
};
m.set(key, ["北京", "上海", "深圳"]);
console.log(m);
Map的属性和方法:
1)size 返回Map的元素个数
2)set 增加一个新元素,返回当前Map
3) get 返回键名对象的值
4)has 检测Map中是否包含某个元素,返回boolean值
5)clear 清空集合,返回undefined
三、class
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,他的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更加面向对象编程的语法而已。
知识点:
1)class声明类
2)constructor 定义构造函数初始化
3)extends 继承父类
4)super调用父级构造方法
5)static定义静态方法和属性
6)父类方法可以重写
class初步体验
//用es5的方式利用构造函数实例化一个对象
//手机类
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
//添加方法
Phone.prototype.call = function () {
console.log("我可以打电话");
};
//实例化对象
let Huawei = new Phone("华为", 5999);
Huawei.call(); // 我可以打电话
console.log(Huawei); // Phone {brand: '华为', price: 5999}
//用es6 class来实现
class Phone {
//构造方法 名字不能修改 当我们使用 new+类名的时候,就会自动执行构造方法
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
//添加方法 方法必须这样写 方法名+()+{}
call() {
console.log("我可以打电话");
}
}
let onePlus = new Phone("1+", 1999);
console.log(onePlus); //Phone {brand: '1+', price: 1999}
class静态成员static
//构造函数对象与实例对象的属性是不通的,实例对象的属性和构造函数原型对象是通的
function Phone() {}
Phone.name = "手机";
Phone.change = function () {
console.log("我可以改变世界");
};
Phone.prototype.size = "5.5inch";
let nokia = new Phone();
// console.log(nokia.name); // undefined
// nokia.change(); // 报错:nokia.change is not a function
console.log(nokia.size); //5.5inch
实例对象和函数对象的属性是不相通的,函数对象的属性是属于函数对象的。对于这样的属性,我们称之为静态成员。对面向对象而言,这个属性是属于类的,而不属于实例对象。
class Phone {
//静态属性
static name = "手机";
static change() {
console.log("我可以改变世界");
}
}
let nokia = new Phone();
console.log(nokia.name); //undefined
console.log(Phone.name); //手机
对于static标注的属性和方法,它属于类,不属于实例对象
对象继承
es5是如何利用构造函数实现继承的
//手机
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function () {
console.log("我可以打电话");
};
//子类 智能手机
function SmartPhone(brand, price, color, size) {
//用call来实现继承,用this可以继承Phone中的所有方法和属性
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
//设置子级构造函数的原型
//让子类的原型对象指向父类实例, 这样一来在子类实例中找不到的属性和方法就会到原型对象(父
类实例)上寻找
SmartPhone.prototype = new Phone();
SmartPhone.prototype.constructor = SmartPhone;
//声明子类的方法
SmartPhone.prototype.photo = function () {
console.log("我可以拍照");
};
SmartPhone.prototype.playGame = function () {
console.log("我可以玩游戏");
};
const chuizi = new SmartPhone("锤子", 2499, "黑色", "5.5inch");
console.log(chuizi); //SmartPhone {brand: '锤子', price: 2499, color: '黑色', size: '5.5inch'}
class实现对象继承
class Phone {
//构造方法
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
//父类成员的属性
call() {
console.log("我可以打电话");
}
}
class SmartPhone extends Phone {
//构造方法
constructor(brand, price, color, size) {
super(brand, price); //相当于 Phone.call(this,brand,price)
this.color = color;
this.size = size;
}
photo() {
console.log("拍照");
}
playGame() {
console.log("玩游戏");
}
}
const xiaomi = new SmartPhone("小米", 588, "白色", "5.6inch");
console.log(xiaomi); //SmartPhone {brand: '小米', price: 588, color: '白色', size: '5.6inch'}
父类方法的重写
class Phone {
//构造方法
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
//父类成员的属性
call() {
console.log("我可以打电话");
}
}
class SmartPhone extends Phone {
//构造方法
constructor(brand, price, color, size) {
super(brand, price); //相当于 Phone.call(this,brand,price)
this.color = color;
this.size = size;
}
photo() {
console.log("拍照");
}
playGame() {
console.log("玩游戏");
}
call() {
console.log("我可以视频通话");
}
}
const xiaomi = new SmartPhone("小米", 588, "白色", "5.6inch");
console.log(xiaomi);
xiaomi.call(); //我可以视频通话 *在class语法中子类不可以直接调用父类的同名方法
xiaomi.photo(); //拍照
xiaomi.playGame(); //玩游戏
class中getter和setter设置
class Phone {
get price() {
console.log("价格属性被读取了");
return 123;
}
set price(newVal) {
console.log("价格属性被修改了");
}
}
//实例化对象
let s = new Phone();
console.log(s.price); //价格属性被读取了 123
s.price = 456; //价格属性被修改了