一、symbol
- 回顾数据类型:
基本类型(原始类型):
- String
- Number
- Boolean
- Undifined
- Null
- Symbol
引用类型:
- Objects
1.1 创建symbol
1. ES 6 为什么引入 Symbol 类型?
a.为了确保每个
属性的名称都是
独一无二的,从根本上防止属性名的冲突。
b.引入 Symbol 类型之后,对象的属性名就有了两种类型,一种是 String 类型的数据,另一种就是 Symbol 类型的数据
2. 怎样创建 Symbol 类型的数据呢?
其他 5 种原始类型都有各自的字面量形式,而 Symbol 没有字面量形式,但是可以通过全局的 Symbol 函数创建一个 Symbol 类型的数据。例如
1 let firstName = Symbol();
2 let obj = {};
3 obj[firstName] = '李金健';
4 console.log(obj[firstName])
3.Symbol 函数接收一个可选参数,它可以让你添加一段文本,描述即将创建的 Symbol,方便我们进行阅读和调试。
let firstName = Symbol('This is my first name');
4. 我们可以使用 typeof 操作符检测变量的值是否为 Symbol 类型。
1 <script> 2 3 // 1. ES 6 为什么引入 Symbol 类型? 4 // 为了确保每个属性的名称都是独一无二的,从根本上防止属性名的冲突。 5 // 引入 Symbol 类型之后,对象的属性名就有了两种类型,一种是 String 类型的数据,另一种就是 Symbol 类型的数据 6 7 // 2. 怎样创建 Symbol 类型的数据呢? 8 // 其他 5 种原始类型都有各自的字面量形式,而 Symbol 没有字面量形式,但是可以通过全局的 Symbol 函数创建一个 Symbol 类型的数据。 9 let firstName = Symbol(); 10 let lastName = Symbol(); 11 12 let obj = {}; 13 14 obj[firstName] = '李金健'; 15 16 console.log(obj) // {Symbol(): "李金健"} 17 console.log(obj[firstName]) //李金健 18 console.log(obj[lastName]) //undefined 19 20 // 上面的代码创建了一个名为 firstName 的 Symbol,用它作为 obj 对象的属性名,并为属性复制为 '李金健', 21 // 每当你想访问这个属性时一定要使用最初定义的 Symbol。 22 // 例如 obj[firstName] 可以访问到之前添加的属性值,而使用另外一个 Symbol 类型的值 lastName 就不能访问。 23 // 也就是说,你定义属性时使用的是哪个 Symbol,访问属性时也要使用使用哪个 Symbol。 24 25 // 3. Symbol 函数接收一个可选参数,它可以让你添加一段文本,描述即将创建的 Symbol,方便我们进行阅读和调试。 26 // let firstName = Symbol('This is my first name'); 27 // let obj = {}; 28 29 // obj[firstName] = '刘逸云'; 30 31 // console.log(obj[firstName]) 32 // console.log(firstName) 33 34 // 4. 我们可以使用 typeof 操作符检测变量的值是否为 Symbol 类型。 35 36 // let firstName = Symbol('This is my first name'); 37 // console.log(typeof firstName); // 'symbol' 38 39 // 5. Symbol 的使用场景 40 // 所有用到可计算属性名的地方,都可以用 Symbol。例如: 41 42 // 1> 对象字面量的可计算属性名中 43 // let firstName = Symbol('This is my first name'); 44 // let obj = { 45 // [firstName]: '王亚坡' 46 // }; 47 48 // 2> 在 Object.defineProperty() 方法中使用 49 // let lastName = Symbol('This is my last name') 50 // Object.defineProperty(obj, lastName, { value: '尼古拉斯' }); 51 52 // 3> 在 Object.defineProperties() 方法中使用 53 54 // let firstName = Symbol('This is my first name'); 55 // let lastName = Symbol('This is my last name'); 56 57 // let obj = {}; 58 59 // Object.defineProperties(obj, { 60 // [firstName]: { 61 // value: '王亚坡', 62 // writable: false 63 // }, 64 // [lastName]: { 65 // value: '尼古拉斯', 66 // writable: false 67 // } 68 // }) 69 70 // console.log(obj[firstName]) 71 // console.log(obj[lastName]) 72 // console.log(obj) 73 74 75 76 script>
1.2 使用symbol
1 <script> 2 3 4 let firstName = Symbol('first name'); 5 let lastName = Symbol('last name'); 6 7 let obj = { 8 [firstName]: '杨帅', 9 [lastName]: '泰坦尼', 10 age: 20, 11 gender: '男' 12 }; 13 14 // 1. 在遍历对象的属性时,Symbol 属性不会被遍历出来 15 // for (const key in obj) { 16 // if (obj.hasOwnProperty(key)) { 17 // console.log(key) 18 // } 19 // } 20 21 // Object.keys(obj).forEach(key => { 22 // console.log(key) 23 // }) 24 25 // 2. 使用 Object.getOwnPropertySymbols() 方法获取对象中所有的 Symbol 属性。 26 27 Object.getOwnPropertySymbols(obj).forEach(key => { 28 console.log(key, obj[key]) 29 }) 30 31 console.log(obj[firstName]) 32 console.log(obj[lastName]) 33 34 35 script>
二、set
2.1 创建set集合
1 <body> 2 3 <script> 4 5 // 集合,集合中的元素是无序的,并且不能重复的。 6 7 // 1. 使用构造函数 Set 创建一个空的集合对象 8 // const set = new Set(); 9 10 // 2. 也可以使用数组来初始化 set 集合,Set 构造函数会过滤掉数组中重复的元素。 11 const set = new Set(['black', 'white', 'gray', 'white']); 12 13 // 3. 将集合转换成数组 14 console.log([...set]) 15 16 // 4. 向集合中添加元素 17 // set.add('red') 18 // set.add('green') 19 20 // 5. 由于集合中的元素不能重复,因此添加失败,但是不会抛出错误。 21 // set.add('red') 22 23 // 6. 在 Set 集合中,不会对所存的值进行强制类型转,因此数字 5 与 字符串 '5' 是两个不同的值。 24 // set.add(5) 25 // set.add('5') 26 27 // 7. 获取集合中元素的数量 28 // console.log(set.size); // 4 29 30 // 8. 判断集合中是否有某个元素 31 // console.log(set.has('green')); // true 32 // console.log(set.has('blue')); // false 33 34 // 9. 获取集合中的键和值 35 // console.log(set.keys()) 36 // console.log(set.values()) 37 38 // 10. 遍历集合中的元素 39 // set.forEach((value, key, self) => { 40 // console.log(key, value) 41 // console.log(self === set) 42 // }) 43 44 // 11. 删除集合中的元素 45 // set.delete(5) 46 // set.delete('red') 47 48 // 12. 清空集合 49 // set.clear() 50 51 console.log(set) 52 53 script> 54 body>
2.2 set集合应用
1 <body> 2 3 <script> 4 5 const set1 = new Set([1, 2, 3, 4]); 6 const set2 = new Set([3, 4, 5, 6]); 7 8 // 1. set1 和 set2 的交集 9 10 // 求交集的方式一: 11 // let intersection1 = new Set(); 12 // set1.forEach(value => { 13 // if (set2.has(value)) { 14 // intersection.add(value) 15 // } 16 // }) 17 18 // 求交集的方式二: 19 // let intersection2 = new Set([...set1].filter(value => set2.has(value))) 20 21 // 2. set1 和 set2 的并集 22 // 求并集的方式一: 23 // let union1 = new Set([...set1, ...set2]) 24 25 // 求并集的方式二: 26 // let union2 = new Set([...set2].reduce((result, value) => { 27 // if (result.indexOf(value) === -1) { 28 // result.push(value) 29 // } 30 // return result; 31 // }, [...set1])) 32 33 // console.log(union1) 34 // console.log(union2) 35 36 // 3. set2 的补集 37 let difference1 = new Set([...set1].filter(value => !set2.has(value))) 38 console.log(difference1) 39 40 // 4. set1 的补集 41 let difference2 = new Set([...set2].filter(value => !set1.has(value))) 42 console.log(difference2) 43 44 45 script> 46 body>
2.3 补充知识点 数组对象的filter方法
1 <body> 2 3 <script> 4 5 const array1 = new Array(1, 2, 3, 4); 6 7 const array2 = array1.filter(function (value, index, self) { 8 9 return value > 2 ? true : false; 10 11 }, thisObj) 12 13 // filter() 方法的参数: 14 15 // callback:回调方法,从数组中每遍历出一个元素就调用一次该方法 16 17 // callback 函数的形参: 18 // value: 当前遍历出的元素 19 // index: 当前遍历出的元素对应的索引 20 // self: 数组本身 21 22 // thisObj:我们可以用过该参数指定回到函数中 this 的指向。 23 24 console.log(array2) 25 26 script>
2.4补充知识点 数组对象的reduce方法
1 <body> 2 3 <script> 4 5 const array1 = new Array(1, 2, 3, 4); 6 const array2 = new Array(3, 4, 5, 6); 7 8 // 求 array1 中所有的元素的和 9 // const result = array1.reduce(function (sum, value, index, self) { 10 // console.log(sum, value) 11 // return sum += value 12 // }, 0) 13 14 15 // 求 array1 和 array2 的并集(合并数组并去重) 16 array2.reduce((result, value) => { 17 if (result.indexOf(value) === -1) { 18 result.push(value) 19 } 20 return result; 21 }, array1) 22 23 console.log(array1) 24 25 script> 26 body>
2.5补充知识点 数组对象的weakset方法
1 <body> 2 3 <script> 4 5 /* 6 WeakSet 集合与 Set 集合类似,集合中的元素是无序的,并且不能重复的。 7 但是 WeakSet 集合中的元素只能是对象(引用类型),不能是其他类型。 8 WeakSet 集合只存储对象的引用,并不存储对象的原始值;集合中的引用如果是对象唯一的引用,则会被回收并释放相应的内存。 9 */ 10 11 const weakset = new WeakSet() 12 13 // 也可以在创建集合时向集合中添加元素 14 // const weakset = new WeakSet([{}, [], new Date()]) 15 16 // 源对象 17 let obj = { 18 name: '张三' 19 }; 20 21 // WeakSet 集合支持 3 个方法,add(),has(),delete() 22 23 // 向集合中添加对象 24 weakset.add(obj) 25 // weakset.add([1, 2, 3]) 26 27 // 判断集合中是否具有某个对象 28 console.log(weakset.has(obj)) 29 30 // 删除集合中的对象 31 // weakset.delete(obj); 32 33 // 清除变量 obj 对源对象的引用 34 obj = null; 35 36 // 过一段时间之后,weakset 集合对源对象的引用也会被删除。 37 setInterval(function() { 38 console.log(weakset) 39 }, 1000) 40 41 42 /* 43 const set = new Set() 44 45 let obj = {}; 46 47 set.add(obj); 48 49 // 移除变量 obj 对空对象的引用 50 obj = null; 51 52 console.log(set.size); // 1 */ 53 54 script> 55 body>
2.6补充知识点 数组对象的map方法
1 <body> 2 3 <script> 4 5 // 创建一个空的 Map 集合 6 // const map = new Map(); 7 8 // 创建一个具有初始元素的集合 9 const map = new Map([['firstName', '黄聪聪'], ['age', 20]]) 10 11 // 向 map 集合中添加键值对 12 // map.set('fullName', '刘旭凯'); 13 // map.set('age', 19); 14 // map.set('fullName', '吕鑫洋'); // 修改了 fullName 键名对应的值 15 // map.set('lastName', '吕鑫洋'); // 值可以相同,只要键名不同即可 16 17 // 根据键值名获取对应的值 18 console.log(map.get('fullName')); // '刘旭凯' 19 console.log(map.get('age')); // 19 20 console.log(map.get('gender')); // 'undefined' 21 22 // 根据键名删除对应的值 23 map.delete('age'); 24 25 // 判断集合是否有某个键值对 26 console.log(map.has('age')); // false 27 console.log(map.has('fullName')); // true 28 29 // 获取所有的键名 30 console.log(map.keys()) 31 32 // 获取所有的键值 33 console.log(map.values()) 34 35 // 获取所有的键值对 36 console.log(map.entries()) 37 38 // 获取集合中元素的数量 39 console.log(map.size); 40 41 // 变量map集合 42 map.forEach(function (value, key, self) { 43 console.log(key, value, self) 44 console.log(this) 45 }, map) 46 47 script> 48 body>