çº ECMAScript 2015 ä¸çä¸äºè£å å §å®¹ï¼ä¸¦éæ°çå §å»ºç©ä»¶æèªæ³ï¼èæ¯åè°ãéäºåè°å¯è¢«ä»»ä½éµå®ç¹å®åå®çç©ä»¶æå¯¦ä½ã
æ¬æä»ç´¹å ©ç¨®åè°ï¼å¯è¿ä»£åè°ä»¥åè¿ä»£å¨åè°ã
å¯è¿ä»£åè°å¯è¿ä»£ï¼iterableï¼åè°å
許 JavaScript ç©ä»¶å®ç¾©æå®¢å¶ä»åçè¿ä»£è¡çºï¼ä¾å¦åªäºå¼å¯å¨ for..of
èªæ³çµæ§ä¸è¢«è¿ä»£åºä¾ãé¨åå
§å»ºåå¥çºææé è¨è¿ä»£è¡çºçå¯è¿ä»£å
§å»ºç©ä»¶ï¼å¦ Array
æ Map
ï¼èå
¶ä»åå¥ï¼å¦ Object
ï¼åå¦ã
çºäºæçºå¯è¿ä»£çï¼ä¸åç©ä»¶å¿
é å¯¦ä½ [Symbol.iterator]()
æ¹æ³ï¼æææ¯éåç©ä»¶ï¼æå
¶ååéä¸çå
¶ä¸ä¸åååç©ä»¶ï¼å¿
é ææä¸åéµï¼keyï¼å¼çº [Symbol.iterator]
ï¼å³ Symbol.iterator
常æ¸ï¼ç屬æ§ï¼
[Symbol.iterator]
åå³ç¬¦åè¿ä»£å¨åè°ä¹ç©ä»¶çç¡å¼æ¸å½å¼ã
æ¯ç¶ç©ä»¶éè¦è¢«è¿ä»£æï¼æ¯å¦å¨ä¸åéå§ç for..of
è¿´åä¸ï¼ï¼ç©ä»¶ç [Symbol.iterator]()
æ¹æ³æè¢«ä»¥ä¸å³å
¥å¼æ¸çæ¹å¼å¼å«ï¼ä¸¦æä½¿ç¨å
¶åå³çè¿ä»£å¨ä¾ç²å¾è¢«è¿ä»£åºä¾çå¼ã
è¿ä»£å¨ï¼iteratorï¼åè°å®ç¾©äºä¸åæ¨æºæ¹å¼ä¾ç¢åºä¸é£ä¸²ï¼æéæç¡éï¼çå¼ï¼ä¸¦ä¸å¯è½æ¼ææå¼é½è¢«ç¢åºå¾åå³ä¸åå¼ã
ç¶ç©ä»¶ä»¥ä¸åèªç¾©å¯¦ä½äº next()
æ¹æ³å³çºä¸åè¿ä»£å¨ï¼
next
åå³ä¸åè³å°ææä»¥ä¸å ©å屬æ§ä¹ç©ä»¶çç¡å¼æ¸å½å¼ï¼
done
ï¼å¸æå¼ï¼
true
ãå¨éåæ
æ³ä¸ value
å¯ä»¥æ¯ä»£è¡¨è¿ä»£å¨çåå³å¼ãfalse
ãç¸ç¶æ¼å®å
¨ä¸æå® done
屬æ§ãvalue
- ä»»ä½ç±è¿ä»£å¨æåå³ç JavaScript å¼ã坿¼ done
çº true
æçç¥ãnext
æ¹æ³å¿
é 總æ¯åå³ä¸åå
å«ç¬¦å done
å value
屬æ§çç©ä»¶ãåå¦åå³äºä¸åéç©ä»¶å¼ï¼å¦ false
æ undefined
ï¼ï¼åå°ææåºä¸å TypeError
é¯èª¤ã
åè¨»ï¼ æåç¡æ³åå°æ§çä¸ç¼çåºä¸åç¹å®çç©ä»¶æ¯å¦å¯¦ä½äºè¿ä»£å¨åè°ï¼ç¶èè¦å»ºç«ä¸ååææ»¿è¶³è¿ä»£å¨åå¯è¿ä»£åè°çç©ä»¶å»æ¯ç¸ç¶å®¹æï¼å¦ä¸ä¾æç¤ºï¼ãç¯ä¾çåæ³å 許ä¸åè¿ä»£å¨è¢«ååé æå ¶å¯è¿ä»£è¡çºçèªæ³ææ¶è²»ãå æ¤å¾å°æéè¦å¯¦ä½è¿ä»£å¨åè°èæ²æå¯¦ä½å¯è¿ä»£åè°çæ æ³ã
var myIterator = {
next: function () {
// ...
},
[Symbol.iterator]: function () {
return this;
},
};
è¿ä»£åè°ä½¿ç¨ç¯ä¾
String
çºä¸åå¯è¿ä»£å
§å»ºç©ä»¶ï¼built-in iterable objectï¼çç¯ä¾ï¼
var someString = "hi";
typeof someString[Symbol.iterator]; // "function"
String
çé è¨è¿ä»£å¨æåå³å串ä¸çä¸åä¸ååå
ï¼
var iterator = someString[Symbol.iterator]();
iterator + ""; // "[object String Iterator]"
iterator.next(); // { value: "h", done: false }
iterator.next(); // { value: "i", done: false }
iterator.next(); // { value: undefined, done: true }
é¨åå §å»ºèªæ³çµæ§ï¼built-in constructsï¼ï¼å¦ spread syntaxï¼å ¶å §é¨ä¹ä½¿ç¨äºç¸åçè¿ä»£åè°ï¼
[...someString]; // ["h", "i"]
æåå¯ä»¥èç±æä¾æåèªå·±ç [Symbol.iterator]()
ä¾éæ°å®ç¾©è¿ä»£è¡çºï¼
var someString = new String("hi"); // need to construct a String object explicitly to avoid auto-boxing
someString[Symbol.iterator] = function () {
return {
// this is the iterator object, returning a single element, the string "bye"
next: function () {
if (this._first) {
this._first = false;
return { value: "bye", done: false };
} else {
return { done: true };
}
},
_first: true,
};
};
è«æ³¨æï¼éæ°å®ç¾© [Symbol.iterator]()
æå½±é¿ä½¿ç¨è¿ä»£åè°ä¹å
§å»ºèªæ³çµæ§çè¡çºï¼
[...someString]; // ["bye"]
someString + ""; // "hi"
å¯è¿ä»£ç¯ä¾ å¯è¿ä»£å
§å»ºç©ä»¶
String
ãArray
ãTypedArray
ãMap
以å Set
å
¨é½æ¯å¯è¿ä»£å
§å»ºç©ä»¶ï¼å çºä»åæ¯ä¸åçååç©ä»¶ç實ä½äº [Symbol.iterator]()
æ¹æ³ã
æåå¯ä»¥å»ºç«èªå·±çå¯è¿ä»£ç©ä»¶ï¼åæ¯ï¼
var myIterable = {};
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
[...myIterable]; // [1, 2, 3]
æ¥åå¯è¿ä»£ç©ä»¶çå
§å»º API
æè¨±å¤ APIs æ¥åå¯è¿ä»£ç©ä»¶ï¼å¦ï¼Map([iterable])
ãWeakMap([iterable])
ãSet([iterable])
å WeakSet([iterable])
ï¼
var myObj = {};
new Map([
[1, "a"],
[2, "b"],
[3, "c"],
]).get(2); // "b"
new WeakMap([
[{}, "a"],
[myObj, "b"],
[{}, "c"],
]).get(myObj); // "b"
new Set([1, 2, 3]).has(3); // true
new Set("123").has("2"); // true
new WeakSet(
(function* () {
yield {};
yield myObj;
yield {};
})(),
).has(myObj); // true
å¦å¤å¯åè Promise.all(iterable)
ãPromise.race(iterable)
以å Array.from()
ã
é¨åé³è¿°å¼ï¼statementsï¼åéç®å¼ï¼expressionsï¼çºé æç¨æ¼å¯è¿ä»£ç©ä»¶ï¼ä¾å¦ for-of
è¿´åãspread syntaxãyield*
ï¼åè§£æ§ï¼
for (let value of ["a", "b", "c"]) {
console.log(value);
}
// "a"
// "b"
// "c"
[..."abc"]; // ["a", "b", "c"]
function* gen() {
yield* ["a", "b", "c"];
}
gen().next(); // { value:"a", done:false }
[a, b, c] = new Set(["a", "b", "c"]);
a; // "a"
éè¯å¥½çå¯è¿ä»£ç©ä»¶
åå¦å¯è¿ä»¶ç©ä»¶ç [Symbol.iterator]()
æ¹æ³ä¸æ¯åå³ä¸åè¿ä»£å¨ç©ä»¶ï¼å³æ¯éè¯å¥½çï¼non-well-formedï¼å¯è¿ä»£ç©ä»¶ãå¦ä»¥ä¸æ¹å¼ä½¿ç¨å¯è½æå°è´å·è¡ææç°å¸¸æé¯èª¤è¡çºï¼
var nonWellFormedIterable = {}
nonWellFormedIterable[Symbol.iterator] = () => 1
[...nonWellFormedIterable] // TypeError: [] is not a function
è¿ä»£å¨ç¯ä¾ ç°¡å®çè¿ä»£å¨
function makeIterator(array) {
var nextIndex = 0;
return {
next: function () {
return nextIndex < array.length
? { value: array[nextIndex++], done: false }
: { done: true };
},
};
}
var it = makeIterator(["yo", "ya"]);
console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done); // true
ç¡éè¿ä»£å¨
function idMaker() {
var index = 0;
return {
next: function () {
return { value: index++, done: false };
},
};
}
var it = idMaker();
console.log(it.next().value); // '0'
console.log(it.next().value); // '1'
console.log(it.next().value); // '2'
// ...
æé
çæå¨ï¼generatorï¼
function* makeSimpleGenerator(array) {
var nextIndex = 0;
while (nextIndex < array.length) {
yield array[nextIndex++];
}
}
var gen = makeSimpleGenerator(["yo", "ya"]);
console.log(gen.next().value); // 'yo'
console.log(gen.next().value); // 'ya'
console.log(gen.next().done); // true
function* idMaker() {
var index = 0;
while (true) yield index++;
}
var gen = idMaker();
console.log(gen.next().value); // '0'
console.log(gen.next().value); // '1'
console.log(gen.next().value); // '2'
// ...
æé
ES2015 é¡å¥
class SimpleClass {
constructor(data) {
this.index = 0;
this.data = data;
}
[Symbol.iterator]() {
return {
next: () => {
if (this.index < this.data.length) {
return { value: this.data[this.index++], done: false };
} else {
this.index = 0; //If we would like to iterate over this again without forcing manual update of the index
return { done: true };
}
},
};
}
}
const simple = new SimpleClass([1, 2, 3, 4, 5]);
for (const val of simple) {
console.log(val); //'0' '1' '2' '3' '4' '5'
}
çæå¨ç©ä»¶æ¯è¿ä»£å¨éæ¯å¯è¿ä»£ç©ä»¶ï¼
çæå¨ç©ä»¶åæçºè¿ä»£å¨åå¯è¿ä»£ç©ä»¶ï¼
var aGeneratorObject = (function* () {
yield 1;
yield 2;
yield 3;
})();
typeof aGeneratorObject.next;
// "function", because it has a next method, so it's an iterator
typeof aGeneratorObject[Symbol.iterator];
// "function", because it has an [Symbol.iterator]() method, so it's an iterable
aGeneratorObject[Symbol.iterator]() === aGeneratorObject;
// true, because its [Symbol.iterator]() method returns itself (an iterator), so it's an well-formed iterable
[...aGeneratorObject];
// [1, 2, 3]
åè¦
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4