当前位置: 首页 > news >正文

以3d全景做的网站临沂seo网站管理

以3d全景做的网站,临沂seo网站管理,毕业设计代做网站靠谱吗,营销型企业网站建设的基本原则是目录 一、由来及意义 二、具体实现流程 三、具有默认 Iterator 接口的数据结构 四、调用 Iterator 接口的场合 五、总结 一、由来及意义 Javascript中表示“集合”的数据结构,主要是 Array、Object、Map、Set 这四种数据集合,除此之外,…

目录

一、由来及意义

二、具体实现流程

三、具有默认 Iterator 接口的数据结构

四、调用 Iterator 接口的场合

五、总结


一、由来及意义

Javascript中表示“集合”的数据结构,主要是 ArrayObjectMapSet 这四种数据集合,除此之外,它们相互之间还可以组合使用,例如Array的成员是MapMap的成员是Object等。因此Javascript得需要一种统一的接口机制,来处理所有不同的数据结构。

遍历器(Iterator)就是这样一种机制。它是一种接口,可以为各种不同的数据结构提供一种访问机制(访问接口),任何数据结构部署Iterator接口,就可以完成该数据结构成员的遍历操作(Iterator 接口主要供for...of使用)。

二、具体实现流程

Iterator的遍历过程:

1. 创建一个指针对象,指向数据解构的起始位置。

2. 第一次调用指针对象的next()方法,指针指向数据结构的第一个成员。

3. 第二次调用指针对象的next()方法,指针指向数据结构的第二个成员。

4. 不停调用指针对象的next()方法,直到它指向数据结构结束的位置。(类似于C语言中的链表)

每一次调用next方法,都会返回数据结构中被指针指向的成员的信息。该信息为一个对象,其中包含valuedone两个属性的对象{ value: something , done: false }value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束(done:false:表示循环还没有结束,done:true :表示循环结束了)。

模拟next方法返回值例子:

下面代码定义了一个makeIterator函数,它是一个遍历器生成函数,作用就是返回一个遍历器对象。对数组['前端','收割','机']执行这个函数,就会返回该数组的遍历器对象(即指针对象)goodjob

function makeIterator(array){var index = 0;//形成闭包保存指针指向位置index,通过三元表达式返回当前信息对象。return {next: function(){return index < array.length ? {value: array[index++], done: false} : {value: undefined, done: true};}}
}var goodjob = makeIterator(['前端','收割','机'])goodjob.next()//  {value: '前端', done: false}
goodjob.next()//  {value: '收割', done: false}
goodjob.next()//  {value: '机',  done: false}
goodjob.next()//  {value: undefined, done: false}

由于 Iterator 只是把接口规格加到数据结构之上,所以,遍历器与它所遍历的那个数据结构,实际上是分开的,完全可以写出没有对应数据结构的遍历器对象,或者说用遍历器对象模拟出数据结构。 

另一种写法:

function makeIterator(array) {var index = 0; //形成闭包保存指针指向位置index,通过if分支语句返回当前信息对象。return {next: function() {var result = {value: undefined, done: true};if (index < array.length) {result = { value: array[index++], done: false };}return result;}};
}// 使用示例
var iterable = makeIterator([1, 2, 3]);
console.log(iterable.next().value); // 输出: 1
console.log(iterable.next().value); // 输出: 2
console.log(iterable.next().value); // 输出: 3
console.log(iterable.next().value); // undefined,迭代结束

makeIterator 这个函数的目的是创建一个迭代器对象,该对象可以遍历传入的数组。在JavaScript中,一个迭代器对象需要实现next方法,该方法在每次调用时返回数组的下一个元素。

在这个解决方案中,makeIterator函数通过返回一个对象,该对象具有一个next方法,来创建一个迭代器。每次调用next方法时,它都会返回数组中的下一个元素,直至遍历完成,此时done属性为true,value属性为undefined。这是符合ES6中Iterable和Iterator协议的定义。 

三、具有默认 Iterator 接口的数据结构

Iterator 接口的目的,就是为所有数据结构,提供了一种统一的访问机制,当使用for...of循环遍历某种数据结构时,该循环会自动去寻找 Iterator 接口。

因此,当某种数据结构具有Iterator 接口,即表示该数据结构是可遍历的(iterable)。

默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。至于属性名Symbol.iterator,它是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为 Symbol 的特殊值,所以要放在方括号内。

const object1 = {[Symbol.iterator] : function () {return {next: function () {return {value: 1,done: true};}};}
};

对象object1是可遍历的(iterable),因为具有Symbol.iterator属性。执行这个属性,会返回一个遍历器对象。该对象的根本特征就是具有next方法。每次调用next方法,都会返回一个代表当前成员的信息对象,具有valuedone两个属性。

凡是部署了Symbol.iterator属性的数据结构,就称为部署了遍历器接口。调用这个接口,就会返回一个遍历器对象。即不用任何处理,就可以被for...of循环遍历。

原生具备 Iterator 接口的数据结构:

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • NodeList 对象
  • 函数的 arguments 对象

数组的Symbol.iterator属性:

let arr = ['前端', '收割', '机'];
let iterator = arr[Symbol.iterator]();  //因为arr中属性Symbol.iterator返回的是一个函数,//所以在[Symbol.iterator]后面添加(),使函数执行,返回一个遍历器对象iterator.next() // { value: '前端', done: false }
iterator.next() // { value: '收割', done: false }
iterator.next() // { value: '机', done: false }
iterator.next() // { value: undefined, done: true }

数组通过for of调用iterator接口生成的遍历器

const arr = ['前端', '收割', '机'];for(let v of arr) {console.log(v); // 前端 收割 机
}

Map通过for of调用iterator接口生成的遍历器

var handsome = new Map();
handsome.set("GuangHui", "1handsome");
handsome.set("JiaHao", "2handsome");
handsome.set("NingDong", 666);
for (var [name, value] of handsome) {console.log(name + ": " + value);
}
// GuangHui: 1handsome
// JiaHao: 2handsome
// NingDong: 666

Set 通过for of调用iterator接口生成的遍历器

var handsome = new Set(["GuangHui", "JiaHao", "NingDong"]);
for (var boy of handsome) {console.log(boy);
}
// GuangHui
// JiaHao
// NingDong

类数组对象通过for of调用iterator接口生成的遍历器

// 字符串
let str = "前端收割机";for (let s of str) {console.log(s); // 前 端 收 割 机
}// DOM NodeList对象
let paras = document.querySelectorAll("p");for (let p of paras) {p.classList.add("前端收割机");
}// arguments对象
function printArgs() {for (let x of arguments) {console.log(x);}
}
printArgs('前端', '收割机');
// '前端'
// '收割机'

对于不具备Iterator接口的数据结构(主要是对象)都需要自己在Symbol.iterator属性上面部署,这样才会被for...of循环遍历。

原因:对象(Object)之所以没有默认部署 Iterator 接口,是因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定。本质上,遍历器是一种线性处理,对于任何非线性的数据结构,部署遍历器接口,就等于部署一种线性转换。

下面是为对象添加 Iterator 接口的例子:

let object2 = {data: [ '前端', '收割','机'],[Symbol.iterator]() {const self = this; //将this指向赋予selflet index = 0;     //初始遍历下标return {next() {if (index < self.data.length) {return {value: self.data[index++], //每次调用,遍历下标自增1done: false};} else {return { value: undefined, done: true }; //遍历结束返回该对象}}};}
};

对于类似数组的对象(存在数值键名和length属性),部署 Iterator 接口,有一个简便方法,就是Symbol.iterator方法直接引用数组的 Iterator 接口。

let object3 = {0: '前端',1: '收割',2: '机',length: 3,[Symbol.iterator]: Array.prototype[Symbol.iterator] //直接引用数组构造函数prototype中的 Symbol.iterator属性
};
for (let item of object3) {console.log(item); // '前端', '收割', '机'
}

注意,普通对象部署特定数据结构的Symbol.iterator方法,并无效果。例如普通对象部署数组的Symbol.iterator方法。

let object4 = {  //该对象不存在数值键名a: '前端',b: '收割',c: '机',length: 3,[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of object4) {console.log(item); // undefined, undefined, undefined
}

如果Symbol.iterator方法对应的不是遍历器生成函数(即会返回一个遍历器对象),解释引擎将会报错。

var object5 = {};obj[Symbol.iterator] = () => '前端收割机';  //返回的是一个字符串[...object5]  // TypeError: [] is not a function

四、调用 Iterator 接口的场合

除了for...of循环,某些场景会默认调用 Iterator 接口(即Symbol.iterator方法)

番外:一文带你了解JavaScript中的for...of循环

注意事项


尽管 for...of 循环非常方便和实用,但在使用时仍需要注意一些细节和注意事项,以避免潜在的 bug 或错误。

首先,需要注意的是,for...of 循环只能用于遍历实现了迭代器协议的对象。如果我们尝试使用 for...of 循环遍历一个不支持迭代器协议的对象,会导致 TypeError 错误。

其次,需要注意的是,for...of 循环只能访问迭代器的值,而不能访问迭代器的索引或键。如果我们需要访问迭代器的索引或键,可以考虑使用其他循环结构,如 for 循环或 forEach 方法。

最后,需要注意的是,for...of 循环中的迭代变量是一个常量,其值在每次迭代中都会被重新赋值。因此,我们不能在循环中修改迭代变量的值,否则会导致错误。

解构赋值

let set = new Set().add('前端').add('收割').add('机'); //Set通过add方法进行链式添加值let [one,two] = set;
// x='前端'; y='收割'let [one, ...two] = set;
// one='前端'; two=['收割','机'];

扩展运算符

// 例一
var str = '前端收割机';
[...str] //  ['前','端','收','割','机']// 例二
let arr = ['是', '靓'];
['我', ...arr, '仔']
// ['我', '是', '靓', '仔']

扩展运算符内部就调用 Iterator 接口,这提供了一种简便机制,可以将任何部署了 Iterator 接口的数据结构,通过扩展运算符,转为数组。

yield*

yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。

let generator = function* () {yield "我";yield* ["是","靓","仔"];yield "啊";
};var iterator = generator();iterator.next() // { value: "我", done: false }
iterator.next() // { value: "是", done: false }
iterator.next() // { value: "靓", done: false }
iterator.next() // { value: "仔", done: false }
iterator.next() // { value: "啊", done: false }
iterator.next() // { value: undefined, done: true }

Array.from()

Array.from()函数以类数组形式输入值,Array.from()函数调用Iterator接口,将输入的类数组转化成数组

let arrayLike = {0: '前端', 1: '收割',2: '机',3: ['GuangHui','JiaHao','NingDong'],'length': 4
}
let arr = Array.from(arrayLike)
console.log(arr) // ['前端','收割','机',['GuangHui','JiaHao','NingDong']]

Map(), Set(), WeakMap(), WeakSet()

Map构造函数以数组形式输入键值对,新建Map对象时,Map构造函数调用Iterator接口,遍历存入键值对

var goodJob  = new Map([['前端',1],['收割机',2]]) 

Promise.all()

Promise.all()函数以Promise数组形式输入值,Promise.all()函数调用Iterator接口,将promise请求遍历执行。

const p = Promise.all([p1, p2, p3]);

Promise.all()方法接受一个数组作为参数,p1p2p3都是 Promise 实例,如果不是,就会先调用Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。

Promise.race()

Promise.race()函数以Promise数组形式输入值,Promise.race()函数调用Iterator接口,将promise请求遍历执行。

const p = Promise.race([p1, p2, p3]);

Promise.race()方法接受一个数组作为参数,p1p2p3都是 Promise 实例,如果不是,就会先调用Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.race()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。

● 补充:Generator 函数与 Iterator 接口的关系:

对象的Symbol.iterator方法,等于该对象的遍历器生成函数,调用该函数会返回该对象的一个遍历器对象。由于 Generator 函数就是遍历器生成函数,因此可以把 Generator 赋值给对象的Symbol.iterator属性,从而使得该对象具有 Iterator 接口。

五、总结

▲遍历器(Iterator)可以为各种不同的数据结构提供一种访问机制(访问接口),任何数据结构部署Iterator接口,就可以完成该数据解构成员的遍历操作(Iterator 接口主要供for...of使用)。

Iterator的遍历过程:创建一个指针对象,指向数据解构的起始位置。不停调用指针对象的next()方法,指针往后移动,直到它指向数据结构结束的位置。每一次调用next方法,都会返回数据结构中被指针指向的成员的信息{ value: something , done: false }。 

ArrayMapSetStringTypedArrayNodeList 对象,函数的 arguments 对象为原生具备 Iterator 接口的数据结构。

调用 Iterator 接口的场合:for...of循环、解构赋值扩展运算符yield*Array.from()Map()Set()、 WeakMap()、 WeakSet()Promise.all()Promise.race()

✔ 参考资料

JavaScript中Iterator迭代器接口和循环_脚本之家 | Iterator(遍历器)接口概念以及用法

JavaScript中Iterator迭代器接口和循环 - Python技术站 | JS– Iterator接口 | JS_ES6 - Iterator

http://www.rdtb.cn/news/985.html

相关文章:

  • 三门峡做网站公司提高工作效率的重要性
  • 绍兴优秀做网站的seo外包是什么意思
  • 网络客服兼职网站排名优化客服
  • 大型购物网站建设大数据营销软件
  • 西安网站建设技术外包万能搜索引擎网站
  • 政府门户网站集约化建设方案国内重大新闻
  • html5 做网站顾问
  • 集约化网站建设管理在线生成html网页
  • wordpress ip设置baidu优化
  • 企业网站重要性全网引流推广 价格
  • 1免费网站建站百度极速版推广员怎么申请
  • 没域名 打开网站厦门seo大佬
  • 做网站全程指导重庆seo全面优化
  • 网站备案查询不出来美橙互联建站
  • 河北移动端网站制作北京百度科技有限公司电话
  • 做甲基化黑点的网站网站排名优化需要多久
  • 网站seo置顶 乐云践新专家桔子seo查询
  • 哪个网站可以找题目给小孩做seo外包公司兴田德润
  • 百度一下你就知道天津seo优化排名
  • 企业黄页网站源码品牌宣传策划方案
  • 建站公司网站建设百青藤广告联盟
  • 易龙天做的网站怎么样网站应该如何推广
  • 政务网站建设交流发言现在的网络推广怎么做
  • 查询备案网站腾讯nba新闻
  • 网站seo报表seo全网推广营销软件
  • 企业网站建设方案论文长春网站关键词排名
  • 从留言板开始做网站建站宝盒
  • 免费tickle网站it行业培训机构哪个好
  • 网站建设jiqb站推广网站入口
  • 域名除了做网站还能做什么广州百度推广代理公司