小弟大部分時間都是使用java開發
最近因為一些原因需要使用javascript因此碰的一鼻子灰...
程式碼:
// iterable宣告法
function myIterable() {
this.StorageArray = {
storage1: {slot1:'1', slot2:'2'},
storage2: {slot1:'1', slot2:'2'},
};
this.length = 2;
}
myIterable.prototype[Symbol.iterator] = () => {
return {
i:0,
next() {
if(this.i < this.length) {
return {value: this.StorageArray[this.i], done: false};
}
return {value: undefined, done: true};
}
};
};
let myIterableTest = new myIterable();
for (const value of myIterableTest) {
console.log(value);
}
主要想法是想把一個物件變成一個可以用index來迭代的(實作iterable)。
預期的輸出應該為StorageArray的兩個storage物件。
但是看樣子length與StorageArray都是undefine呢。
預先謝謝各位願意看這個奇怪的code >w<
這個程式碼是毫無意義的 只是把一些我對js的妄想寫出來....
大概也知道物件是要用解構的,或是用forin來迭代
但還是想知道不work的原因
大大的 code 問題主要是出在 JavaScript 變數 scope 的問題:
this
會指向 「定義此函示當下,包覆函示的物件」,以你的例子來說會是主要的環境 (例如你在 Chrome 的 console 執行就會是 Window 物件)。因此按照你的需求應該改寫為:myIterable.prototype[Symbol.iterator] = function() {
// 略
};
this
也跟你預期的不一樣。由於你的 next()
是屬於你要 return 的 {},所以 next()
中的每一個 this
都會指向 return 的 {};也因此 this.i
會是指向你所定義的 i:0,
;而 this.length
與 this.StorageArray
因為都沒有定義於 return 的 {} 當中所以會是 undefined。按照你的需求有下面兩種改寫方式:myIterable.prototype[Symbol.iterator] = function() {
const myIterableInstance = this;
return {
i: -1,
next() {
if(this.i < myIterableInstance.length) {
this.i++;
return {value: myIterableInstance.StorageArray[this.i], done: false};
}
return {value: undefined, done: true};
}
};
};
或
myIterable.prototype[Symbol.iterator] = function() {
const result = {
i: -1,
next: () => {
if(result.i < this.length) {
result.i++;
return {value: this.StorageArray[result.i], done: false};
}
return {value: undefined, done: true};
}
};
return result;
};
i
) 去取出 StorageArray 中的元素,可是你的 StorageArray 並沒有任何 key 是 0, 1, 2, ...,所以會回傳 undefuned,按照你的需求有下面兩種改寫方法:function myIterable() {
this.StorageArray = [
{slot1:'1', slot2:'2'},
{slot1:'1', slot2:'2'},
];
this.length = 2;
}
或
// 略
next: () => {
if(result.i < this.length) {
result.i++;
return {
value: Object.values(this.StorageArray)[result.i],
done: false
};
}
return {value: undefined, done: true};
}