本篇文章為大家帶來了關於javascript的相關知識,其中主要介紹了關於類別數組和可迭代物件的實作原理,包括了把物件本身建構成迭代器、String的迭代器等等相關內容,下面一起來看看吧,希望對大家有幫助。
【相關推薦:javascript影片教學、web前端】
陣列是一個特殊的對象,它和普通對象的差異不僅僅在於元素的順序存取、儲存。另一個重要的差異是:數組是可迭代的,也就是可以使用for ... of
語句來存取(迭代)所有的元素。
我們可以簡單的做一個小實驗:
let arr = [1,2,3,4,5]for(let val of arr){ console.log(val)}
程式碼執行結果:
以上程式碼就簡單的使用了陣列的迭代特性,我們在存取陣列元素的時候,不必使用元素的下標。
如果我們對一個普通物件使用for ... of
語句會發生什麼事呢?
let obj = { name:'xiaoming', age:12,}for(let para of obj){ //代码会报错 console.log(para)}
執行效果如下:
這證明普通的物件和陣列之間還有一個可迭代的差距,我們稱具備迭代功能的物件為可迭代物件。
如果我們希望一個物件可以迭代,必須為物件添加一個名為Symbol.iterator
的方法(一個專門使物件可迭代的內建Symbol
)。
方法作用包括:
for ... of
循環迭代物件時,就會呼叫Symbol.iterator
方法,這個方法必須傳回一個迭代器(一個有next()
方法的物件)。 for ... of
會不斷的呼叫迭代器的next()
方法獲得下一個元素。 next()
方法傳回的內容必須符合格式:{done:Boolean,value:any}
,當done:true
時,循環結束,否則value
就是下一個值。 迭代器:
迭代器是藉用
C
等語言的概念,迭代器的原理就像指標一樣,它指向資料集合中的某個元素,你可以取得它指向的元素,也可以移動它以取得其它元素。迭代器類似陣列中下標的拓展,各種資料結構,如鍊錶(List
)、集合(Set
)、映射(Map
)都有與之對應的迭代器。
JS
中的迭代器是專門為了遍歷這一操作設計的。每次取得到的迭代器總是初始指向第一個元素,且迭代器只有next()
一種行為,直到取得到資料集的最後一個元素。我們無法靈活地移動迭代器的位置,所以,迭代器的任務,是按某種次序遍歷資料集中的元素。
實作一個可迭代物件:
let obj = { from:1, to:5,}obj[Symbol.iterator] = function(){ //返回一个迭代器 return { current:this.from, last:this.to, next(){ if(this.current<this.last><p>程式碼執行效果:</p> <p><img src="https://img.php.cn/upload/article/000/000/067/05759c456d9c107fab3194b506d39378-4.png" alt="JavaScript類別數組和可迭代物件的實作原理詳解"></p> <p>注意,以上物件雖然可以進行迭代了,但是,迭代使用使用的材料並非對象,而是<code>Symbol.iterator</code>返回的迭代器(也是一個對象)。 </p> <h2>把物件本身建構成迭代器</h2> <p>以上程式碼建構了一個內建函數<code>Symbol.iterator()</code>,這個函式回傳了一個迭代器物件。我們也可以採用另外一種實作迭代器的方式:把物件本身做成迭代器:</p> <pre class="brush:php;toolbar:false">let obj = { from:1, to:5, [Symbol.iterator](){ this.current = this.from; return this;//返回对象本身 }, next(){//给对象添加一个next方法 if(this.current<this.to><p>程式碼執行效果和上面的圖片展示相同。 </p> <blockquote><p>這麼做雖然程式碼更簡潔了,但是由於沒有新的可迭代物件產生,我們就沒有辦法同時執行兩個<code>for ... of</code>循環迭代同一個物件了,但是兩個並行的迭代在同一個物件上是非常罕見的。 </p></blockquote> <p>我們可以總結可迭代對象的概念:</p> <p>所謂可迭代對象,就是比普通對像多了一個名為<code>Symbol.iterator</code>方法的普通對象,這個方法回傳一個迭代器。 </p> <p>或者,具有<code>Symbol.iterator</code>同時具備<code>next</code>方法的物件也是可迭代的物件。 </p> <h2>String也是可迭代的</h2> <p>陣列和字串都是可以迭代的,我們可以很方便的使用<code>for...of</code>語句迭代數組中的字符元素:</p> <pre class="brush:php;toolbar:false">let str = '123'for(let c of str){ console.log(c)}
这对于代理对(UTF-16
扩展字符)同样是有效的:
let str = '...'for(let c of str){ console.log(c)}
执行效果如下:
并非只有for...of
语句能够使用迭代器,我们还可以显式的调用迭代器:
let str = '12345'let itr = str[Symbol.iterator]()while(true){ let result = itr.next() if(result.done)break; console.log(result.value)}
代码执行效果:
以上代码执行了遍历字符串字符的操作,是不是觉得可迭代对象就没有这么神秘了!
类数组和可迭代在遍历功能上非常相似,都可以方便的方式内部元素,但是二者仍然有明显的区别:
iterable
可迭代对象:实现了Symbol.iterator
的对象;array-like
类数组对象:具有数字索引,并且有length
属性;字符串就是一个即使类数组又是可迭代的对象。
可迭代和类数组对象通常都不是数组,如果我们想把一个可迭代或者类数组对象转为数组,需要使用Array.from
方法。
使用Array.from
将字符串转为数组:
let str = '123'let arr = Array.from(str)console.log(arr)
代码执行效果如下:
把自定义的类数组对象转为数组:
let obj = { 0:'0', 1:'1', 2:'2', length:3}let arr = Array.from(obj)console.log(arr)
代码执行结果:
Array.from
的完整语法:
Array.from(obj[, mapFunc, thisArg])
mapFunc
方法会在生成数组之前对每个可迭代或类数组元素调用,如果mapFunc
是一个成员方法,可以使用thisArg
提供this
指针。
举个例子:
let str = '12345'let arr = Array.from(str,itm=>+itm)console.log(arr)
代码执行结果:
这里通过映射函数,将本应该生成字符数组转为数字数组。
for...of
语法的对象被称为可迭代对象
Symbol.iterator
方法的对象Symbol.iterator
方法返回了一个迭代器;next
方法,该方法返回下一个元素的值;next
方法返回值需要满足格式{done:Boolean,value:nextVal}
,当done:true
时,迭代结束Array.from
可以把类数组和可迭代对象转为数组;
【相关推荐:javascript视频教程、web前端】
以上是JavaScript類別數組和可迭代物件的實作原理詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!