------------------2019年6月29日
目录
1对象的遍历
首先指出symbol属性的概念,
symbol是ES6引入的一种新的原始数据类型(原始数据类型:保存在栈(stack)中的简单字段如number,boolean,string;引用数据类型,也就是保存在堆(stack)中的对象,存储在栈中的只是一个指针地址)。symbol的引入解决了ES5中对象的属性名只能是字符串所带来的命名冲突,因为他代表的是独一无二的值。
Symbol() === Symbol(); //返回false
var abc = Symbol();
var obj = {[abc]:"一个symbol创建出来的属性值"}; //这里用到了key值构建对象的方法(动态构建)
console.log(obj[abc]);
//返回:"一个symbol创建出来的属性值"
具体的应用场景:
- switch这种每个case项都需要独一无二的情况
- 消除魔术字符串
- 用symbol创建出独一无二的变量作为对象的键
- 对象属性遍历时保护一些属性
注意:访问symbol创建出来的属性值,必须使用中括号访问;node中常用symbol
五种方法遍历:转自
(1)for...in
for...in
循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)。
(2)Object.keys(obj)
Object.keys
返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)。
(3)Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames
返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)。
(4)Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols
返回一个数组,包含对象自身的所有Symbol属性。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys
返回一个数组,包含对象自身的所有属性,不管是属性名是Symbol或字符串,也不管是否可枚举。
验证:
2Iterator和for...of
2.1set和map
set、map是ES6中新增的两个数据结构。
(1)特点:
set结构没有键名(或者说键名和键值是同一个值);set结构中元素不能相等(键名不能相等);
map结构的键名是可以为任意类型的值(包括对象);
注意:实际上,js的对象本质上就是键值对的集合(hash的结构),但只是只能用字符串作为键。
(2)增取删改:
set中的:add(value)、delete(value)、has(value)、clear()
map中的:set(key, "content")、get(key)、delete(key)、has(key)、clear()
(3)遍历
- keys()返回键名的迭代器
- values()返回键值的迭代器
- entries()返回键值对的迭代器
- forEach()使用回调函数遍历每个成员
注意:这里的迭代器就是Iterator对象。其中set的键值与键名是相同的,所以keys()、values()的行为是相同的。
2.2Iterator的使用
Iterator本质上就是一个指针对象
作用:为各种数据结构提供统一、简单的访问接口;使得数据结构的成员能够按某种次序排列;供for...of使用
机理:创建一个指针对象,指向当前数据结构的其实位置;第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员,第二次调用指针对象的next方法,指针就指向数据结构的第二个成员;
使用对象:有些数据结构(原生具备Iterator结构)如:Array、Set、Map,即不用任何处理就可以被for...of遍历,除此之外还有些类数组的对象也可以通过for...of访问,如字符串、DOM的NodeList对象、arguments对象。
使用方法:for...of的方法
- 对于字符串来讲:
let str = "abcdefg";
// let iter = str
for(let ele of str){
console.log(ele);
}
结果:
- 对于Set结构的数据来讲
let s = new Set();
s.add(1);
s.add(2);
s.add(3);
for (let ele of s) {
console.log(ele);
}
结果:
- 对于Map结构的数据来讲
let m = new Map();
m.set("m1", 1);
m.set("m2", 2);
m.set("m3", 3);
for (let [key, ele] of m) {
console.log(key, ele);
}
结果:
注意:set结构返回的只有一个值,而map结构返回的是一个键值对,所以是一个数组。如果硬给set指定一个键值对,会报错
- 对于对象,需要先部署Iterator接口才能使用for...of遍历
方法一:直接将数组的Symbol.iterator属性直接赋值到对象的Symbol.iterator属性
验证出现错误
方法二:使用Generator函数包装一下,
let obj = {
a1: "aaa",
a2: "bbb",
a3: "ccc"
};
function* entries(obj) {
for(let key of Object.keys(obj)){
yield [key, obj[key]];
}
}
for(let [key, val] of entries(obj)){
console.log(key, "--------->", val)
}
结果:
我看来,能用Object.keys(),然后obj[key]访问到键值,没有必要绕弯子去再封装一个Generator函数
- 调用函数生成的Iterator。如上文2.1指出的set、map的entries、keys、values的方法都会产生相应的迭代器对象