版权声明: https://blog.csdn.net/qq_23521659/article/details/88419608
对于可迭代的数据解构,ES6在内部部署了一个[Symbol.iterator]属性,它是一个函数,执行后会返回iterator对象(也叫迭代器对象),而生存iterator对象[Symbol.iterator]属性叫iterator接口,有这个接口的数据结构即被视为可迭代的
数组中的Symbol.iterator方法(iterator接口)默认部署在数组原型上:
iterator迭代器是一个对象,它具有一个next方法所以可以这么调用:
(function () {
let arr = [1, 2, 3];
let iterator = arr[Symbol.iterator](); //需要使用键名的方式访问Symbol.iterator
/**
* value即每次迭代之后返回的值,而done表示是否还需要再次循环
* done为true表示循环终止
*/
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
})();
了解原理之后,我们来看看我们常用的解构赋值:
ES6:
(function () {
/**
* 解构赋值
*
* 数组解构的原理其实是消耗数组的迭代器,把生成对象的value属性的值赋值给对应的变量
*/
let {
title: titleOne,
test: [
{
title: titleTwo
}
]
} = {
title: 'abc',
test: [
{
title: 'test'
}
]
};
console.log(titleOne); // abc
console.log(titleTwo); // test
})();
这里左边真正声明的其实是titleOne,titleTwo这两个变量,然后会根据左边这2个变量的位置寻找右边对象中title和test[0]中的title对应的值,找到字符串abc和test赋值给titleOne,titleTwo(如果没有找到会返回undefined)
对比下编译成的ES5:
var _slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
(function () {
/**
* 解构赋值
*
* 数组解构的原理其实是消耗数组的迭代器,把生成对象的value属性的值赋值给对应的变量
*/
var _title$test = {
title: 'abc',
test: [{
title: 'test'
}]
},
titleOne = _title$test.title,
_title$test$test = _slicedToArray(_title$test.test, 1),
titleTwo = _title$test$test[0].title;
console.log(titleOne); // abc
console.log(titleTwo); // test
})()
可以看到,编译时默认创建了函数_slicedToArray,通过iterator 迭代器处理了数组,完成了结构赋值;
数组解构的原理其实是消耗数组的迭代器,把生成对象的value属性的值赋值给对应的变量;