一道解构面试题
题目
//让下面的代码成立
var [a, b] = { a:1, b: 2 };
运行结果
类型错误:{(intermediate value)(intermediate value)} is not iterable
表示这个对象是不可迭代的。
var [a, b] = { a:1, b: 2 };
^
TypeError: {(intermediate value)(intermediate value)} is not iterable
at Object.<anonymous> (e:\Study\Web前端\√061.一道解构的面试题js\tempCodeRunnerFile.js:1:14)
at Module._compile (node:internal/modules/cjs/loader:1155:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1209:10)
at Module.load (node:internal/modules/cjs/loader:1033:32)
at Function.Module._load (node:internal/modules/cjs/loader:868:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:22:47
原理
概念
解构的对象不一定是数组,只要这个对象是可迭代的对象。数组本身就是一个可以迭代的对象。所以我们只有将{ a:1, b: 2 }
变成可以迭代的对象就能解决这个问题。
在 JavaScript
中,可迭代对象是指具有 Symbol.iterator
方法的对象。这个方法返回一个迭代器(Iterator
)对象,它通过 next()
方法提供对可迭代对象中的每个元素的访问。
除了数组,还有一些其他的内置类型,例如字符串
、Set
、Map
等,都是可迭代对象。此外,自定义对象也可以实现可迭代接口,使其成为可迭代对象。
{
[Symbol.iterator]:function(){
return 迭代器
}
}
数组迭代器
下面以数组[1,2,3]
作为示例,了解可迭代的对象的规则:
- 查看数组的
Symbol.iterator
类型:[Function: values]
表示是一个方法
代码
var arr = [1,2,3];
console.log(arr[Symbol.iterator]);
运行结果
[Function: values]
- 查看数组的
Symbol.iterator
方法的返回值:Object [Array Iterator] {}
表示数组迭代器。
代码
var arr = [1,2,3];
const iter = arr[Symbol.iterator]();
console.log(iter);
运行结果
Object [Array Iterator] {}
3.查看数组迭代器中的next类型:[Function: next]
表示方法。
代码
var arr = [1,2,3];
const iter = arr[Symbol.iterator]();
console.log(iter.next);
运行结果
[Function: next]
4.使用迭代器的next()
方法执行一次:获取第1个结果{ value: 1, done: false }
代码
var arr = [1,2,3];
const iter = arr[Symbol.iterator]();
console.log(iter.next());
运行结果
{ value: 1, done: false }
5.使用迭代器的next()
方法执行两次:获取第1、2个结果{ value: 1, done: false } { value: 2, done: false }
代码
var arr = [1,2,3];
const iter = arr[Symbol.iterator]();
console.log(iter.next());
console.log(iter.next());
运行结果
{ value: 1, done: false }
{ value: 2, done: false }
6.使用迭代器的next()
方法执行三次:获取第1、2、3个结果{ value: 1, done: false } { value: 2, done: false } { value: 3, done: false }
代码
var arr = [1,2,3];
const iter = arr[Symbol.iterator]();
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
运行结果
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
7.使用迭代器的next()
方法执行四次:获取第1、2、3个结果及迭代完成标志{ value: 1, done: false } { value: 2, done: false } { value: 3, done: false } { value: undefined, done: true }
,其中{ value: undefined, done: true }
表示迭代器对象已经完成了所有的迭代操作。
代码
var arr = [1,2,3];
const iter = arr[Symbol.iterator]();
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
运行结果
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: undefined, done: true }
8.使用迭代器的next().value
方法模拟var [a,b] = [1,2,3];
的解构。
代码
var arr = [1,2,3];
const iter = arr[Symbol.iterator]();
var a = iter.next().value;
var b = iter.next().value;
console.log(a, b);
运行结果
1 2
答案
答案(1)、在对象中添加一个数组迭代器
1.使用临时数组添加迭代器
代码
var [a, b] = {
a: 1,
b: 2,
[Symbol.iterator](){
var arr = [1,2];
const iter = arr[Symbol.iterator]();
return iter;
},
};
console.log(a, b);
运行结果
1 2
2. 对象值输出结果
代码
var [a, b] = {
a: 3,
b: 4,
[Symbol.iterator](){
var arr = [1,2];
const iter = arr[Symbol.iterator]();
return iter;
},
};
console.log(a, b);
运行结果
1 2
3.使用Object.values(this);拿到对象的值
代码
var [a, b] = {
a: 3,
b: 4,
[Symbol.iterator](){
var arr = Object.values(this);
const iter = arr[Symbol.iterator]();
return iter;
},
};
console.log(a, b);
运行结果
3 4
答案(2)、在对象原型上添加数组迭代器
1.按步骤实现数组迭代器
代码
Object.prototype [Symbol.iterator] = function () {
var arr = Object.values(this);
const iter = arr[Symbol.iterator]();
return iter;
}
var [a, b] = { a:1, b: 2 };
console.log(a, b);
运行结果
1 2
2. 简化步骤
代码
Object.prototype [Symbol.iterator] = function () {
return Object.values(this)[Symbol.iterator]();
}
var [a, b] = { a:1, b: 2 };
console.log(a, b);
运行结果
1 2
答案(3)、使用迭代器生成器
下面所示代码中的生成器函数function* () {}
定义了一个迭代器生成器。当该迭代器被调用时,它会返回一个可迭代对象,并且通过yield*
语句将对象的值作为迭代器的值逐个产生出来。
代码
Object.prototype [Symbol.iterator] = function* () {
return yield* Object.values(this);
}
var [a, b] = { a:1, b: 2 };
console.log(a, b);
运行结果
1 2