ECMAScript是一種由Ecma國(guó)際(前身為歐洲計(jì)算機(jī)制造商協(xié)會(huì),European Computer Manufacturers Association)通過(guò)ECMA-262標(biāo)準(zhǔn)化的腳本程序設(shè)計(jì)語(yǔ)言起愈。這種語(yǔ)言在萬(wàn)維網(wǎng)上應(yīng)用廣泛,它往往被稱為JavaScript或JScript仰迁,但實(shí)際上后兩者是ECMA-262標(biāo)準(zhǔn)的實(shí)現(xiàn)和擴(kuò)展
有五個(gè)ECMA-262版本:
1997年06月列荔,首版
1998年6月比规,ECMAScript2.0版發(fā)布
1999年12月,ECMAScript3發(fā)布陪白,正則表達(dá)式煮落,文字鏈處理,新的控制指令攻柠,異常處理球订,錯(cuò)誤定義更加明確,數(shù)輸出的格式化及其它改變
2007年10月瑰钮,ECMAScript 4.0版草案發(fā)布冒滩,由于過(guò)于激進(jìn),以Yahoo浪谴、Microsoft开睡、Google為首的大公司,反對(duì)JavaScript的大幅升級(jí)苟耻,主張小幅改動(dòng)篇恒,以JavaScript創(chuàng)造者Brendan Eich為首的Mozilla公司,則堅(jiān)持當(dāng)前的草案凶杖,2008年7月胁艰,由于對(duì)于下一個(gè)版本應(yīng)該包括哪些功能,各方分歧太大智蝠,爭(zhēng)論過(guò)于激進(jìn)腾么,ECMA決定中止ECMAScript 4.0的開(kāi)發(fā),將其中涉及現(xiàn)有功能改善的一小部分杈湾,發(fā)布為ECMAScript3.1
2009年12月解虱,ECMAScript 5.0版正式發(fā)布
2011年6月,ECMAscript 5.1版發(fā)布漆撞,并且成為ISO國(guó)際標(biāo)準(zhǔn)(ISO/IEC 16262:2011)
2013年12月殴泰,ECMAScript 6草案發(fā)布,然后是12個(gè)月的討論期叫挟,聽(tīng)取各方反饋
2015年6月17日艰匙,ECMAScript6發(fā)布正式版本限煞,即ECMAScript2015
_______________________________________________________________________________________________
在低版本瀏覽器中使用ES6抹恳、ES7
方法① 在WebStorm中使用babel,將js編譯為ES5
缺點(diǎn):? 非常消耗內(nèi)存
_______________________________________________________________________________________________
ES5:ECMAScript第五個(gè)版本(第四版因?yàn)檫^(guò)于復(fù)雜廢棄了),增加特性如下:
① strict模式
? 嚴(yán)格模式署驻,限制一些用法: "use strict";
② Array增加方法
? 增加了every奋献、some健霹、forEach、filter瓶蚂、indexOf糖埋、lastIndexOf、isArray窃这、map瞳别、reduce、reduceRight等
? 還有其他方法: Function.prototype.bind杭攻、String.prototype.trim祟敛、Date.now
③ Object方法
? Object.getPrototypeOf、Object.create兆解、Object.getOwnPropertyNames馆铁、Object.defineProperty、
? Object.getOwnPropertyDescriptor锅睛、Object.defineProperties埠巨、Object.keys、
? Object.preventExtensions/Object.isExtensible现拒、Object.seal/Object.isSealed辣垒、
? Object.freeze/Object.isFrozen
_______________________________________________________________________________________________
ES6:?ECMAScript6(又稱為ECMAScript 2015),保證向下兼容的前提下,提供了大量新特性:
① 塊級(jí)作用域印蔬、關(guān)鍵字let,常量const
② 對(duì)象字面量的屬性賦值簡(jiǎn)寫(property value shorthand)
var obj = {
? __proto__: theProtoObj, ? ? ? // 原型
? handler, ? ? ? ? ? ? ? ? ? ? ?// Shorthand for 'handler: handler'
? toString(){ ? ? ? ? ? ? ? ? ? // 定義方法
? ? return "d " + super.toString(); ? ?// Super調(diào)用
? },
? [ 'prop_' + (() => 42)() ]: 42 ? ? ? // 動(dòng)態(tài)計(jì)算屬性名
};
③ 賦值解構(gòu)
let singer = { first: "Bob", last: "Dylan" };
let { first: f, last: l } = singer; ? ? ? ?? // 相當(dāng)于 f = "Bob", l = "Dylan"
let [all, year, month, day] = /^(\d\d\d\d)-(\d\d)-(\d\d)$/.exec("2015-10-25");
let [x, y] = [1, 2, 3]; ? ? ? ?? // x = 1, y = 2
④ 函數(shù)參數(shù): 默認(rèn)值乍构、參數(shù)打包、數(shù)組擴(kuò)展(Default扛点、Rest哥遮、Spread)
function findArtist(name='lu', age='26'){?...?} ? ? ?? //默認(rèn)值
function f(x, ...y){ ? ? ?? //參數(shù)打包
? return x*y.length; ? ? ?? //y變成數(shù)組
}
f(3,"hello",true) == 6; ? ? //true
function f(x, y, z){ ? ? ? ?//數(shù)組擴(kuò)展
? return x + y + z;
}
f(...[1,2,3]) == 6 ? ? ? ?? //true,將數(shù)組的每個(gè)值傳給函數(shù)陵究,作為參數(shù)
⑤ 箭頭函數(shù)(Arrow functions)
? 簡(jiǎn)化了代碼形式眠饮,默認(rèn)return表達(dá)式結(jié)果
? 自動(dòng)綁定語(yǔ)義this,即定義函數(shù)時(shí)的this
⑥ 字符串模板(Template strings)
var name = "Bob",time = "today";
`Hello ${name}, how are you ${time}?` ? ? ? ?//return "Hello Bob, how are you today?"
⑧ 迭代器(Iterators)?+ for..of
迭代器有個(gè)next方法铜邮,調(diào)用會(huì)返回:
? 返回迭代對(duì)象的一個(gè)元素: { done: false, value: elem }
? 如果已到迭代對(duì)象的末端: { done: true, value: retVal }
for(var n of ['a','b','c']){
? console.log(n); ? ? ? ?//打印a仪召、b、c
}
⑧ 生成器(Generators)
⑨ Class
Class松蒜,有constructor扔茅、extends、super秸苗,本質(zhì)上是語(yǔ)法糖(對(duì)語(yǔ)言的功能并沒(méi)有影響召娜,更方便程序員使用)
class Artist{
? constructor(name){ this.name = name;?}
? perform(){ return this.name + " performs "; }
}
class Singer extends Artist {
? constructor(name, song) {
? ? super.constructor(name);
? ? this.song = song;
? }
? perform(){ return super.perform() + "[" + this.song + "]"; }
}
let james = new Singer("Etta James", "At last");
james instanceof Artist; ?? // true
james instanceof Singer; ?? // true
james.perform(); ? ? ? ? ?? // "Etta James performs [At last]"
⑩ Modules
ES6的內(nèi)置模塊功能借鑒了CommonJS和AMD各自的優(yōu)點(diǎn):
? 具有CommonJS的精簡(jiǎn)語(yǔ)法、唯一導(dǎo)出出口(single exports)和循環(huán)依賴(cyclic dependencies)的特點(diǎn)
? 類似AMD惊楼,支持異步加載和可配置的模塊加載
lib/math.js:
export function sum(x, y){?return x + y;?}
export var pi = 3.141593;
app.js:
import * as math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));
otherApp.js
import {sum, pi} from "lib/math";
alert("2π = " + sum(pi, pi));
Module Loaders:(動(dòng)態(tài)加載玖瘸,'系統(tǒng)'是默認(rèn)加載器)
System.import('lib/math').then(function(m){
? alert("2π = " + m.sum(m.pi, m.pi));
});
直接操作模塊緩存:
System.get('jquery');
System.set('jquery', Module({$: $})); ?? // WARNING: 未完成
? Map + Set + WeakMap + WeakSet(四種集合類型)
? WeakMap秸讹、WeakSet作為屬性鍵的對(duì)象如果沒(méi)有別的變量在引用它們,則會(huì)被回收釋放掉
var s = new Set(); ? ? ? ? //Sets
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
var m = new Map(); ? ? ? ? //Maps
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;
var wm = new WeakMap(); ? ?//WeakMap
wm.set(s, { extra: 42 });
wm.size === undefined;
var ws = new WeakSet(); ? ? ? //Weak Sets
ws.add({ data: 42 }); ? ? ? ? //因?yàn)樘砑拥膶?duì)象沒(méi)有其他引用雅倒,所以不會(huì)在集合中保存它
Set是一種新的數(shù)據(jù)結(jié)構(gòu)璃诀,它類似于數(shù)組,但是成員的值都是唯一的蔑匣,沒(méi)有重復(fù)的值
Set 本身是一個(gè)構(gòu)造函數(shù)劣欢,用來(lái)生成 Set 數(shù)據(jù)結(jié)構(gòu): let set = new Set()
Set 函數(shù)可以接受一個(gè)數(shù)組(或類數(shù)組對(duì)象)作為參數(shù),用來(lái)初始化: let set=new Set([1,2,3,4,4]);
操作方法:
1裁良、add(value)? ? ?添加某個(gè)值氧秘,返回 Set 結(jié)構(gòu)本身
2、delete(value)? 刪除某個(gè)值趴久,返回一個(gè)布爾值丸相,表示刪除是否成功
3、has(value)? ? ?返回一個(gè)布爾值彼棍,表示該值是否為 Set 的成員
4灭忠、clear()? ? ? ? 清除所有成員,無(wú)返回值
遍歷方法:
1座硕、keys()? ? ?返回鍵名的遍歷器
2弛作、values()? ?返回鍵值的遍歷器
3、entries()? 返回鍵值對(duì)的遍歷器
4华匾、forEach()? 使用回調(diào)函數(shù)遍歷每個(gè)成員映琳,無(wú)返回值
屬性:
1、Set.prototype.constructor? 構(gòu)造函數(shù)蜘拉,默認(rèn)就是 Set 函數(shù)
2萨西、Set.prototype.size? ? ? ? ?返回 Set 實(shí)例的成員總數(shù)
? Math + Number + String + Array + Object 的一些API
Number.EPSILON;
Number.isInteger(Infinity) ?? //false
Number.isNaN("NaN") ? ? ? ? ? //false
Math.acosh(3) ? ? ? ? ? ? ? ? //1.762747174039086
Math.hypot(3, 4) ? ? ? ? ? ?? //5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) ?? //2
"abcde".includes("cd") ? ? ?? //true
"abc".repeat(3) ? ? ? ? ? ? ? //"abcabcabc"
Array.from(document.querySelectorAll('*')) ? ? ? ? ? ? //返回一個(gè)真正的數(shù)組
Array.of(1, 2, 3) ? ? ? ? ? ? //類似于數(shù)組,但沒(méi)有單參數(shù)行為
[0, 0, 0].fill(7, 1) ? ? ? ?? //[0,7,7]
array.fill(value [, start[, end]]);
array ?必需旭旭,數(shù)組對(duì)象
value ?必需谎脯,用于填充數(shù)組的值
start ?可選,用于填充數(shù)組值的起始索引持寄,默認(rèn)值為0
end ? ?可選源梭,用于填充數(shù)組值的結(jié)束索引,默認(rèn)值是this對(duì)象的length屬性
如果start為負(fù)稍味,則start被視為length+start废麻,其中,length是數(shù)組的長(zhǎng)度
如果end為負(fù)模庐,則end被視為length+end
[1, 2, 3].find(x => x == 3) ? ?? //3
[1, 2, 3].findIndex(x =>x==2) ?? //1
[1, 2, 3, 4, 5].copyWithin(3,0)? //[1, 2, 3, 1, 2]
["a", "b", "c"].entries() ? ? ?? //迭代器[0,"a"],[1,"b"],[2,"c"]
["a", "b", "c"].keys() ? ? ? ? ? //迭代器0,1,2
["a", "b", "c"].values() ? ? ? ? //迭代器"a", "b", "c"
Object.assign(Point,{ origin: new Point(0,0) })
? Proxies
使用代理(Proxy)監(jiān)聽(tīng)對(duì)象的操作烛愧,進(jìn)行操作
var target = {};
var handler = {
? get: function (receiver, name){ return `Hello, ${name}!`; }
};
var p = new Proxy(target, handler);
p.world === 'Hello, world!';
可監(jiān)聽(tīng)的操作: get、set、has屑彻、deleteProperty、apply顶吮、construct社牲、getOwnPropertyDescriptor、defineProperty悴了、getPrototypeOf搏恤、setPrototypeOf、enumerate湃交、ownKeys熟空、preventExtensions、isExtensible
??Symbols
Symbol是一種基本類型搞莺,Symbol通過(guò)調(diào)用symbol函數(shù)產(chǎn)生息罗,它接收一個(gè)可選的名字參數(shù),該函數(shù)返回的symbol是唯一的
var key = Symbol("key");
var key2 = Symbol("key");
key == key2; ? ? ?? //false
??Promises
Promises是處理異步操作的對(duì)象才沧,使用了Promise對(duì)象之后可以用一種鏈?zhǔn)秸{(diào)用的方式來(lái)組織代碼迈喉,讓代碼更加直觀(類似jQuery的deferred對(duì)象)
functionfakeAjax(url){? ? ? ? ? ? ?//聲明一個(gè)promise對(duì)象(并指定成功、失敗的條件)(可傳參數(shù))
? return new Promise(function (resolve, reject){
? ? if(!url){ return setTimeout(reject, 1000); }? ? //setTimeout是為了看到效果温圆,通常使用XHR
? ? return setTimeout(resolve, 1000);
? });
}
fakeAjax().then(function(){? ? //使用聲明的promise對(duì)象fakeAjax挨摸,若不傳url,promise會(huì)拒絕
? console.log('success');
? },function(){
? ? console.log('fail');
});
Promise是一個(gè)對(duì)象,用來(lái)傳遞異步操作的消息岁歉。它代表了某個(gè)未來(lái)才會(huì)知道結(jié)果的事件(通常是一個(gè)異步操作)得运,并且這個(gè)事件提供統(tǒng)一的API,可供進(jìn)一步處理
特點(diǎn):
①對(duì)象的狀態(tài)不受外界影響
? Promise對(duì)象代表一個(gè)異步操作锅移,有三種狀態(tài): Pending(進(jìn)行中)熔掺、Resolved(已完成,又稱Fulfilled)和Rejected(已失敗)非剃。只有異步操作的結(jié)果瞬女,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無(wú)法改變這個(gè)狀態(tài)努潘。這也是Promise(承諾)這個(gè)名字的由來(lái)诽偷,表示其他手段無(wú)法改變
②一旦狀態(tài)改變,就不會(huì)再變疯坤,任何時(shí)候都可以得到這個(gè)結(jié)果
? Promise對(duì)象的狀態(tài)改變报慕,只有兩種可能: 從Pending變?yōu)镽esolved和從Pending變?yōu)镽ejected。只要這兩種情況發(fā)生压怠,狀態(tài)就凝固了眠冈,不會(huì)再變了,會(huì)一直保持這個(gè)結(jié)果。就算改變已經(jīng)發(fā)生了蜗顽,你再對(duì)Promise對(duì)象添加回調(diào)函數(shù)布卡,也會(huì)立即得到這個(gè)結(jié)果。這與事件(Event)完全不同雇盖,事件的特點(diǎn)是: 如果你錯(cuò)過(guò)了它忿等,再去監(jiān)聽(tīng),是得不到結(jié)果的
③ 缺點(diǎn): 首先崔挖,無(wú)法取消Promise贸街,一旦新建它就會(huì)立即執(zhí)行,無(wú)法中途取消狸相。其次薛匪,如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯(cuò)誤脓鹃,不會(huì)反應(yīng)到外部逸尖。第三,當(dāng)處于Pending狀態(tài)時(shí)瘸右,無(wú)法得知目前進(jìn)展到哪一個(gè)階段(剛剛開(kāi)始還是即將完成)
varpromise= new Promise(function(resolve, reject){
? if(/*異步操作成功*/){
? ? resolve(value);
? }else{
? ? reject(error);
? }
});
promise.then(
? function(value){?},//成功
function(value){ }//失敗
);
Promise構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù)冷溶,該函數(shù)的兩個(gè)參數(shù)分別是resolve方法和reject方法
如果異步操作成功,則用resolve方法將Promise對(duì)象的狀態(tài)尊浓,從"未完成"變?yōu)?成功"(即從pending變?yōu)閞esolved)
如果異步操作失敗逞频,則用reject方法將Promise對(duì)象的狀態(tài),從"未完成"變?yōu)?失敗"(即從pending變?yōu)閞ejected)
基本的API
1栋齿、Promise.resolve()? ? //異步操作成功
2苗胀、Promise.reject()? ? ?//異步操作失敗
3、Promise.prototype.then()
4瓦堵、Promise.prototype.catch()
5基协、Promise.all()? ? ? ? //所有的都完成
? ? var p = Promise.all([p1, p2, p3]);
6、Promise.race()? ? ? ?//競(jìng)速菇用,完成一個(gè)即可
promises的奇妙在于給予以前的return與throw澜驮,每個(gè)Promise都會(huì)提供一個(gè)then()和一個(gè)catch()函數(shù)
somePromise().then(functoin(){
? //do something
})
可以做3件事:
1、return另一個(gè)promise
2惋鸥、return一個(gè)同步的值(或者undefined)
3杂穷、throw一個(gè)同步異常throw new Eror('')
_______________________________________________________________________________________________
解構(gòu)
作用: 可以快速取得數(shù)組或?qū)ο螽?dāng)中的元素或?qū)傩裕鵁o(wú)需使用arr[x]或者obj[key]等傳統(tǒng)方式進(jìn)行賦值
原理: 賦值的兩邊具有相同的結(jié)構(gòu)卦绣,就可以正確取出數(shù)組或?qū)ο罄锩娴脑鼗驅(qū)傩灾?/p>
數(shù)組解構(gòu)賦值:
var arr = ['this is a string', 2, 3];
var [a, b, c] = arr; ? ? ?? //解構(gòu)賦值
console.log(a); ?? //this is a string
console.log(b); ? ?//2
console.log(c); ? ?//3
函數(shù)傳參解構(gòu):
① var arr = ['this is a string', 2, 3];
functionfn1([a, b, c]){
? console.log(a); ? ?//this is a string
? console.log(b); ? ?//2
? console.log(c); ? ?//3
}
fn1(arr);
②?var?obj = {a:1, b:2, c:3};
functionfn2({a, b}){ console.log(a, b) }
fn2(obj);
var x = 1, y = 2;
var [x, y] = [y, x]; ? ?//變量互換
console.log(x); ?? //2
console.log(y); ?? //1
var str = 'love';
var [a, b, c, d] = str; ? ?//字符串解構(gòu)
console.log(a); ? ?//l
console.log(b); ? ?//o
console.log(c); ? ?//v
console.log(d); ? ?//e
_______________________________________________________________________________________________
擴(kuò)展運(yùn)算符(spread)
擴(kuò)展運(yùn)算符用三個(gè)點(diǎn)號(hào)表示耐量,功能是把數(shù)組或類數(shù)組對(duì)象展開(kāi)成一系列用逗號(hào)隔開(kāi)的值
var foo = function(a, b, c){
? console.log(a);
? console.log(b);
? console.log(c);
}
var arr = [1, 2, 3];
foo(arr[0], arr[1], arr[2]); ? ?//傳統(tǒng)寫法
foo(...arr); ? ?//使用擴(kuò)展運(yùn)算符? //1,2滤港,3
//數(shù)組深拷貝(復(fù)制數(shù)組,地址值不同)
var arr2 = arr;
var arr3 = [...arr];
console.log(arr===arr2); ? ?//true,說(shuō)明arr和arr2指向同一個(gè)數(shù)組
console.log(arr===arr3); ?? //false,說(shuō)明arr3和arr指向不同數(shù)組
//把一個(gè)數(shù)組插入另一個(gè)數(shù)組字面量
var arr4 = [...arr, 4, 5, 6];
console.log(arr4); ? ?//[1, 2, 3, 4, 5, 6]
//字符串轉(zhuǎn)數(shù)組
var str = 'love';
var arr5 = [...str];
console.log(arr5); ? ?//['l', 'o', 'v', 'e']
配合Set刪除數(shù)組中的重復(fù)項(xiàng)
var arr = [...new Set([1, 2, 3, 3, 4, 5, 5])]
_______________________________________________________________________________________________
rest運(yùn)算符
rest運(yùn)算符也是三個(gè)點(diǎn)號(hào)廊蜒,不過(guò)其功能與擴(kuò)展運(yùn)算符恰好相反,把逗號(hào)隔開(kāi)的值序列組合成一個(gè)數(shù)組
主要用于不定參數(shù),所以ES6開(kāi)始可以不再使用arguments對(duì)象
var bar = function(...args) {
? for(let el of args){
? ? console.log(el);
? }
}
bar(1, 2, 3, 4); ?? //1山叮,2著榴,3,4
bar = function(a, ...args){
? console.log(a);
? console.log(args);
}
bar(1, 2, 3, 4); ? ?//1屁倔,[2, 3, 4]
rest運(yùn)算符配合解構(gòu)使用:
var [a, ...rest] = [1, 2, 3, 4];
console.log(a); ? ? ? //1
console.log(rest); ? ?//[2, 3, 4]
_______________________________________________________________________________________________
總結(jié):
三個(gè)點(diǎn)號(hào): 三點(diǎn)放在形參或者等號(hào)左邊為rest運(yùn)算符(放在被賦值一方)
? ? ? ? ? 三點(diǎn)放在實(shí)參或者等號(hào)右邊為擴(kuò)展運(yùn)算符(放在賦值一方)
在等號(hào)賦值或for循環(huán)中脑又,如果需要從數(shù)組或?qū)ο笾腥≈担M量使用解構(gòu)
在自己定義函數(shù)的時(shí)候汰现,如果調(diào)用者傳來(lái)的是數(shù)組或?qū)ο蠊业螀⒈M量使用解構(gòu)方式叔壤,優(yōu)先使用對(duì)象解構(gòu)瞎饲,其次是數(shù)組解構(gòu)
在調(diào)用第三方函數(shù)的時(shí)候,如果該函數(shù)接受多個(gè)參數(shù)炼绘,并且要傳入的實(shí)參為數(shù)組嗅战,則使用擴(kuò)展運(yùn)算符
rest運(yùn)算符使用場(chǎng)景應(yīng)該稍少一些,主要是處理不定數(shù)量參數(shù)俺亮,可以避免arguments對(duì)象的使用
_______________________________________________________________________________________________
vue.watch的原理
/**
* @desc 屬性改變監(jiān)聽(tīng)驮捍,屬性被set時(shí)出發(fā)watch的方法,類似vue的watch
* @author **
* @data 2018-04-27
* @constructor
* @param {object} opts - 構(gòu)造參數(shù). @default {data:{},watch:{}};
* @argument {object} data - 要綁定的屬性
* @argument {object} watch - 要監(jiān)聽(tīng)的屬性的回調(diào)
* watch @callback (newVal, oldVal)? 新值與舊值
*/
class watcher{
? constructor(opts){
? ? this.$data = this.getBaseType(opts.data) === 'Object' ? opts.data : {};
? ? this.$watch = this.getBaseType(opts.watch) === 'Object' ? opts.watch : {};
? ? for(let key in opts.data){
? ? ? this.setData(key)
? ? }
? }
? getBaseType(target){
? ? const typeStr = Object.prototype.toString.apply(target);
? ? return typeStr.slice(8, -1);
? }
? setData(_key){
? ? Object.defineProperty(this,_key,{
? ? ? get: function(){
? ? ? ? return this.$data[_key];
? ? ? },
? ? ? set: function(val){
? ? ? ? const oldVal = this.$data[_key];
? ? ? ? if(oldVal === val) return val;
? ? ? ? this.$data[_key] = val;
? ? ? ? this.$watch[_key] && typeof this.$watch[_key] === 'function' && (
? ? ? ? ? this.$watch[_key].call(this,val,oldVal)
? ? ? ? );
? ? ? ? return val;
? ? ? }
? ? });
? }
}
let wm = new watcher({? ? //使用方法
? data:{
? ? a: 0
? },
? watch:{
? ? a(newVal,oldVal){
? ? ? $('.bb').html(newVal);
? ? }
? }
})
setInterval(function(){
? wm.a = ++wm.a;
},1000)
_______________________________________________________________________________________________
JavaScript生成器
生成器最重要的特性: 只有在需要的時(shí)候它才會(huì)產(chǎn)生下一個(gè)值脚曾,而不會(huì)一次性產(chǎn)生所有的值
語(yǔ)法:在函數(shù)關(guān)鍵詞后加上一個(gè)星號(hào)
例:
function * fn () { }
let fn = function * () { }
class MyClass {
? *generator() { }
? * generator() { }
}
const obj = {
? *generator() { }
? * generator() { }
}
注意: 不能使用箭頭函數(shù)創(chuàng)建生成器
關(guān)鍵詞yield: 類似于return东且,但不完全相同
return 會(huì)在完成函數(shù)調(diào)用后簡(jiǎn)單地將值返回,在 return 語(yǔ)句之后無(wú)法進(jìn)行任何操作
yield?之后仍然可以執(zhí)行操作本讥,但只會(huì)返回一次珊泳,當(dāng)再次調(diào)用同一函數(shù)時(shí),會(huì)執(zhí)行至下一個(gè) yield 語(yǔ)句處拷沸,而前面的 yield?不再返回東西
在生成器中色查,通常會(huì)在輸出時(shí)得到一個(gè)對(duì)象。這個(gè)對(duì)象有兩個(gè)屬性: value 與 done
value?是返回值撞芍,done 會(huì)顯示生成器是否完成了它的工作
在生成器中秧了,不僅可以使用 yield,也可以使用 return 來(lái)返回同樣的對(duì)象序无。但是验毡,在函數(shù)執(zhí)行到第一個(gè) return 語(yǔ)句時(shí),生成器將結(jié)束它的工作
帶星號(hào)的 yield 可以將它的工作委托給另一個(gè)生成器帝嗡,通過(guò)這種方式米罚,可以將多個(gè)生成器連接在一起
例:
function * anotherGenerator(i) {
? yield i + 1;
??yield i + 2;
??yield i + 3;
}
function * generator(i) {
? yield* anotherGenerator(i);
}
var gen = generator(1);
gen.next().value;? ? //2
gen.next().value;????//3
gen.next().value;????//4