系列文章目录
第一章:ES6基础语法(let、const、解构赋值、模板字符串、简化对象、箭头函数、扩展运算符)(一)
第三章:ES6深入(生成器、Promise、async/await)(三)
第四章:ES6+新增API拓展(对象API拓展、数组API拓展、字符串&函数API拓展、数值API拓展)(四)
一、Symbol 基本使用
ES6 引入了一种新的基本数据类型 Symbol,表示独一无二的值。是一种类似于字符串的数据类型。
Symbol 特点
- Symbol 的
值是唯一的
,用来解决命名冲突的问题 - Symbol 值
不能与其他数据进行运算
- Symbol 定义的对象属性
不能使用for…in 循环遍历
,但是可以使用Object.getOwnPropertySymbols()、Reflect.ownKeys 来获取对象的所有键名
案例:
1.创建Symbol值
let sy1 = Symbol("myname");
console.log(sy1, typeof Symbol);//Symbol(myname) function
let sy2 = Symbol("myage");
console.log(sy1 === sy2);//false
//不能与其他数据进行运算
// let result = s + 100;
// let result = s > 100;
// let result = s + s;
2.Symbol创建对象属性
let game = {}
let methods = {
//声明一个对象
up: Symbol("hh"),
down: Symbol("123")
};
game[methods.up] = function () {
console.log("我可以改变形状");
}
game[methods.down] = function () {
console.log("我可以快速下降!!");
}
console.log(game);
let youxi = {
name: "狼人杀",
[Symbol('say')]: function () {
console.log("我可以发言")
},
[Symbol('zibao')]: function () {
console.log('我可以自爆');
}
}
console.log(youxi)
//静态方法
let res = Object.getOwnPropertySymbols(youxi);
console.log(youxi[res[1]])//[Function: [zibao]]
for (let key in youxi) {
console.log(key)//name
}
运行结果:
3.全局注册表
Symbol.for() 并不是每次都会创建一个新的 symbol,它会首先检查给定的 key 是否已经在注册表中了。假如是,则会直接返回上次存储的那个。否则,它会再新建一个。
let sy1 = Symbol('hello');
let sy2 = Symbol("hello");
console.log(sy1 === sy2);
// Symbol.for()
let sy3 = Symbol.for('hello');
let sy4 = Symbol.for("hello");
console.log(sy3 === sy4)
//Symbol.keyFor()可以检测symbol值是否在全局注册表中注册过。 返回对于symbol的描述或者undefined
console.log(Symbol.keyFor(sy1))
console.log(Symbol.keyFor(sy3))
运行结果:
二、Class
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰
、更像面向对象编程的语法而已。
1.class 声明类 ,constructor 定义构造函数初始化
代码示例:
//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);
//ES6
class Shouji {
// 类的构造器 ---必须提供 如果不写默认 提供空的构造器
constructor(brand, price) {
// 实例私有属性
this.brand = brand;
this.price = price;
}
// 实例公共方法--类似于存在于原型对象中Person.prototype
call() {
console.log('dianhua')
}
}
let onePlus = new Shouji("1+", 10000);
onePlus.call();
console.log(onePlus);
运行结果:
2. extends 继承父类
代码示例:
//ES5方法
function Phone(brand, price) {
this.brand = brand;
this.price = price
}
Phone.prototype.call = function() {
console.log("我可以打电话!!!");
}
//智能手机
function SmartPhone(brand, price, color, size) {
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 huawei = new SmartPhone("华为", 2333, "蓝色", "5.5寸");
console.log(huawei);
运行结果:
//ES6
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;
}
//super 调用父级构造方法
call() {
super.call()
console.log('我可以进行视频通话');
}
photo() {
console.log("拍照");
}
playGame() {
console.log("玩游戏");
}
}
const huawei = new SmartPhone("华为", 2333, "蓝色", "5.5寸");
console.log(huawei);
// 继承
// 1.子类的原型对象通过一个指针继承父类的原型对象
console.log(SmartPhone.prototype.__proto__ == Phone.prototype);
// 2.子类对象通过一个指针指向父类对象继承
console.log(SmartPhone.__proto__ == Phone);
console.log(huawei.__proto__ == SmartPhone.prototype);
结果:
3.static 定义静态方法和属性 --属于类不属于实例对象
通过static关键字
来定义静态属性和静态方法
。也可以在外侧添加静态属性;静态属性和静态方法是定义在类【构造函数】上的,所以可以通过类【构造函数】直接访问。在静态方法中,this指向当前类【构造函数】
代码示例:
class Phone {
// 静态属性 由static 声明的属性就是静态属性
static name = '手机'
// 静态方法 由static声明的静态方法
static change() {
console.log("改变世界!!!");
}
}
// console.log(Phone.name);
let nokia = new Phone();
console.log(nokia.name);//报错
console.log(Phone.name);//手机
运行结果:
三、迭代器
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制
。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
Iterator 的作用有三个: 一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费。
原生具备 iterator 接口的数据(可用 for of 遍历)
- Array 2) Arguments 3) Set 4) Map 5) String 6) TypedArray 7)NodeList
案例:
// 返回什么 返回迭代器对象
let [a] = '10'; //字符串实现了迭代器接口 就可以使用for ...of遍历
console.log(a);
let str = 'hello';
for (let k of str) {
console.log(k);
}
运行结果:
Iterator工作原理(遍历过程是这样的)
-
创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
-
第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
-
第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
-
不断调用指针对象的next方法,直到它指向数据结构的结束位置。
拓展: for-of实现原理就是调用迭代器的next()方法,第一次调用将指针指向数据结构的第一个成员,依次调用依次指向,直到没有成员可以指向,done为true
案例:
let arr = [1, 2, 3, 'hello'];
let keys = arr.keys(); //迭代器对象
let values = arr.values(); //迭代器对象 for of 数组元素
let entries = arr.entries();
// 手动调用next 遍历迭代器对象 {value:0 ,done:false}
let result;
while (!(result = values.next()).done) {
console.log(result);
}
// 运行结果
// { value: 1, done: false }
// { value: 2, done: false }
// { value: 3, done: false }
// { value: 'hello', done: false }
console.log("----------------")
console.log(keys.next()); //{ value: 0, done: false } done为false表示不是最后成员
console.log(keys.next()); //{ value: 1, done: false } done为false表示不是最后成员
console.log(keys.next()); //{ value: 2, done: false } done为false表示不是最后成员
console.log(keys.next()); //{ value: 3, done: false } done为false表示不是最后成员
console.log(keys.next()); //{ value: undefined, done: true }
console.log("----------------")
console.log(values.next()); //{ value: 1, done: false }
console.log(values.next()); //{ value: 2, done: false }
console.log(values.next()); //{ value: 3, done: false }
console.log(values.next()); //{ value:'hello', done: false }
console.log(values.next()); //{ value: undefined, done: true }
console.log("----------------")
// console.log(entries.next());
for (let k of entries) {
// keys k ---下标
// values k--数组元素
// entries k-下标和数组元素组成得数组
console.log(k);
}
运行结果:
四、Set
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的
,集合实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,它可以接收一个数组作为参数
集合的属性和方法:
- size
返回集合的元素个数 - add
增加一个新元素,返回当前集合 - delete 删除元素,返回 boolean 值
- has
检测集合中是否包含某个元素,返回 boolean 值 - clear
清空集合,返回 undefined
案例:
// 概念:es6提供新的数据结构 类似于数组 成员是唯一得 没有重复得值
// key和value是一样得
// 创建一个set数据结构
let set = new Set();
// set api
// 1.添加成员
set.add('tom');
set.add('jack');
set.add('jack');
set.add([1]);
set.add([1]);
// console.log(set.size,set);
// 使用add方法添加基本数据类型成员 会做自动去重
// 使用add方法添加引用数据类型成员 全部添加
// 删除成员
console.log(set);
set.delete('tom');
console.log(set);
console.log("-----------")
// 查看set长度 size属性
// 遍历set
console.log(set.keys());
console.log(set.values());
console.log(set.entries());
console.log("-----------")
for (let k of set.keys()) {
console.log(k);
}
console.log("-----------")
let res = set.forEach((key, value, set) => {
console.log(key, value, set);
});
console.log(res);
console.log("-----------")
// 查看有没有某一个成员 has(key/value)
// 返回 或者false值:true
console.log(set.has('tom'));
console.log(set.has('jack'));
console.log("-----------")
// 清空全部set成员 参数 无参 返回值 清空后set
set.clear();
console.log(set);
console.log("-----------")
// 应用 去重数组
// es5 项目中 slice filter map
console.log([...new Set([1, 2, 3, 2, 1])]);
运行结果:
五、Map
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。
但是“键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。
Map 的属性和方法:
- size
返回 Map 的元素个数 - set
增加一个新元素,返回当前 Map - get
返回键名对象的键值 - has
检测 Map 中是否包含某个元素,返回 boolean 值 - clear
清空集合,返回 undefined
案例:
// 概念:类似于对象 是一种集合 键值对组成得数据结构 键可以是任意数据类型
// 对象 键只能是字符串或者是symbol值
let obj = {
name: 'zhangsan',
age: 12
};
// console.log(obj,typeof obj[1]);
let res = Object.entries(obj);
// 创建一个map集合 构造函数
// 购物车 - +
// [] map
console.log(res)
let map = new Map(res);
console.log(map);
console.log("--------------");
// 给map添加成员
let temp = [123];
map.set(temp, 'hello');
console.log(map);
console.log("--------------");
// // 删除map成员
map.delete(temp);
console.log(map);
console.log("--------------");
// delete 可以直接删除基本数据类型得键
// 删除引用数据类型需要删除引用地址
// 遍历方法
console.log(map.keys());
console.log(map.values());
console.log(map.entries());
console.log("--------------");
for (let k of map.keys()) {
console.log(k, '1111');
}
console.log("--------------");
let result = map.forEach((value, key, map) => {
console.log(value, key, map);
});
console.log("--------------");
// 获取map属性
console.log(map.get(temp));
for (let k of map) {
console.log(k);
}
console.log(map.__proto__);
运行结果:
map和object区别?
1.map得键可以是任意数据类型,object得键只能是字符串或者symbol
2.map是一个可迭代得数据结构 对象不可以直接迭代
3.map可以通过size属性获取数据结构长度 对象不可以直接获取
4.map循环遍历按照顺序进行输出 对象属性无序数据结构