使用[Symbol.iterator]实现迭代
备注:此处的操作,由于使用的方法是Object.keys(object)的方式获取到对象的属性。
所以遍历所使用的 键(keys()),值(values()),和键值对(entries())方法,均采用Symbol属性。
/**
* 方法名采用Symbol作为属性唯一标识符
* @type {symbol}
*/
let keys = Symbol("keys");
let values = Symbol('values');
let entries = Symbol('entries');
/**
* 示例操作对象
* @type {{name: string, gender: string, age: number, email: string, mobile: string, job: string, skills: string}}
*/
const person = {
name: '张三',
gender: '男',
age: 23,
email: '121212@qq.com',
mobile: '13398754613',
job: 'IT',
skills: 'piano'
}
/**
* 获取键值
* @returns {*}
*/
person[keys] = function () {
return {
self: this,
[Symbol.iterator]() {
let index = 0;
let self = this.self;
return {
//为迭代器必须函数
next() {
let keys = Object.keys(self);
return index < keys.length ? {
value: keys[index++], done: false
} : {value: undefined, done: true}
}
}
}
}
}
/**
* 获取值
* @returns {*}
*/
person[values] = function () {
return {
self: this,
[Symbol.iterator]() {
let index = 0;
let self = this.self;
return {
next() {
let keys = Object.keys(self);
return index < keys.length ? {
value: self[keys[index++]], done: false
} : {value: undefined, done: true}
}
}
}
}
}
/**
* 键值对获取方式
* @returns {*}
*/
person[entries] = function () {
return {
self: this,
[Symbol.iterator]() {
let index = 0;
let self = this.self;
return {
next() {
let keys = Object.keys(self);
return index < keys.length ? {
value: [keys[index++], self[keys[index - 1]]], done: false
} : {value: undefined, done: true}
}
}
}
}
}
**验证代码**
//对象属性遍历,其实这个可以用更简单的方式遍历出来,采用for...in
for (let key of person[keys]()) {
console.log(key); // name gender age email mobile job skills
}
//for-in 遍历属性
for (let key in person) {
console.log(key); // name gender age email mobile job skills
}
//对象属性值遍历,同理可以采用for-in
for (let value of person[values]()) {
console.log(value); //张三 男 23 121212@qq.com 13398754613 IT piano
}
//采用for-in遍历同理
for (let key in person) {
console.log(person[key]); //张三 男 23 121212@qq.com 13398754613 IT piano
}
//对象属性键值对遍历
for (let [key, value] of person[entries]()) {
console.log([key, value]);
// ['name', '张三']
// ['gender', '男']
// ['age', 23]
// ['email', '121212@qq.com']
// ['mobile', '13398754613']
// ['job', 'IT']
// ['skills', 'piano']
}
说明:关于两者的区别,具体应该跟顺序有关系,本身对象是无序的,在使用不同浏览器执行出来的效果可能顺序是不一致的(for-in),这一点在之前接触的项目中有接触过。至于for-of 通过迭代器是具有一定顺序的遍历。所以两者如果是在顺序上有严格的要求的,建议采用for-of的方式进行遍历。也就是实现[Symbol.iterator]**
采用Generator实现对象的遍历
此处采用的示例操作对象依旧是一方式中的person
/**
* 键值对获取方式
* @param obj 此处的对象为字面性对象
*/
function* entries(obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
}
/**
* 键获取方式
* @param obj 此处的对象为字面性对象
*/
function* keys(obj) {
for (let key of Object.keys(obj)) {
yield key;
}
}
/**
* 键值获取方式
* @param obj 此处的对象为字面性对象
*/
function* values(obj) {
for (let key of Object.keys(obj)) {
yield obj[key];
}
}
**测试代码**
//键值
for (let [key, value] of entries(person)) {
console.log([key, value]);
}
//键
for (let key of keys(person)) {
console.log(key);
}
//键值
for (let value of values(person)) {
console.log(value);
}
今日学习成果就展示到这了。如果有志同道合的,有更好的代码,欢迎指点与分享。