摘要:返回的遍歷器對象,可以依次遍歷函數內部的每一個狀態。以后,每次調用遍歷器對象的方法,就會返回一個有著和兩個屬性的對象。由于函數就是遍歷器生成函數,因此可以把賦值給對象的屬性,從而使得該對象具有接口。
let 和 const 作用域的概念
全局作用域
函數作用域
塊作用域
如何使用let和const
1、形成塊級作用域
2、es6下強制開啟嚴格模式,而在es5下,需要"use strice"才能開啟嚴格模式;
1、聲明的常量不能修改;但是對象可以修改,因為對象是對地址的引用,我們可以在內存空間中更改對象
function last() { const k={ a:1 }; k.a=123; console.log(k) }
2、聲明的時候,必須賦值;
3、const也有塊作用域的概念;
Symbol的作用:避免屬性名相同的問題
注意:對象中,有用到symbol做key值的話,是取不到的;即let...of只能拿到非Symbol對象的值;
let a1=Symbol.for("abc"); let obj={ [a1]:"123", "abc":345, "c":456 }; console.log(obj) for(let [key,value] of Object.entries(obj) ){ console.log("let of",key,value) }
解決辦法:通過以下代碼可以取到Symbol的值;Object.getOwnPropertySymbols可以拿到Symbol對象的值;
Object.getOwnPropertySymbols(obj).forEach(function (item) { console.log(obj[item]) })
返回了所有key和value值;通過es6最增的Reflect.ownKeys(obj)
Reflect.ownKeys(obj).forEach(function (item) { console.log(item,obj[item]) });//返回了所有key和value值;Set的用法
Set的用法:set數據類型的元素,必須是唯一的;添加重復的元素不會報錯,只是不會生效;
他在轉換元素的時候,不會進行數據類型的隱式轉換;
可以用它來去重;
let arr=[1,2,3,4,2,1,2,3,2]; let list=new Set(arr); console.log(list)Set()實例的方法:
1、add() 添加元素
2、delete() 移出
3、clear() 清空
4、has() 判斷元素中是否有某個內容
let arr=["add","delete","clear","has"]; let list=new Set(arr); console.log(list.has("add")) console.log(list.delete("add"),list) console.log(list.clear(),list)Set實例的遍歷
//1:遍歷屬性名
for(let key of list.keys()){ console.log(key) }
//2:遍歷屬性值 for(let value of list.values()){ console.log(value) } //3:遍歷屬性名和屬性值 for(let [key,value] of list.entries()){ console.log(key,value) }Set實例的 forEach
list.forEach(function (item) { console.log(item) })WeakSet的用法
let weakList=new WeakSet()
WeakSet和set的區別:1、WeakSet和set支持的數據類型不一樣;
2、WeakSet中的對象都是若引用;不會檢測地址是否被垃圾回收掉;
3、他的屬性,沒有size屬性,沒有clear方法,不能遍歷;
map的屬性名可以是任意數據類型;
map增加值,用set,獲取值用get
map的兩種寫法
//第一種寫法:
let map=new Map();
let arr=["123"];
map.set(arr,456);
console.log("map",map,map.get(arr))
//第二種寫法
let map=new Map([["a",123],["b",456]])
console.log(map)
map常用的屬性值和方法
map.size 長度
set設置,get獲取
delete() 刪除; clear()清空
WeakMap的用法
前者接收的值只能是對象
他沒有set屬性,不能使用clear()
不能遍歷; 跟weakSet和set的區別一樣;
//數據結構橫向對比,增,查,改,刪 let map=new Map(); let ary=[]; //增 map.set("t",1); ary.push({t:1}); //console.info("map-array",map,ary) //查 let map_exits=map.has("t"); let ary_exites=ary.find(item=>item.t); /*console.log(map_exits) //返回true,表示存在 console.log(ary_exites) //返回當前對象*/ //改 map.set("t",2); ary.forEach(item=>item.t?item.t=2:""); console.log(map,ary) //刪除 map.delete("t"); let index=ary.findIndex(item=>item.t); ary.splice(index,1); console.log(map,ary)
Set與Array的對比
let set=new Set(); let ary=[]; let item={t:1}; //增加 set.add(item); ary.push({t:1}) console.log(set,ary) //查 let set_exist=set.has(item); let ary_exist=ary.find(item=>item.t) console.log(set_exist,ary_exist) //改 set.forEach(item=>item.t?item.t=2:""); ary.forEach(item=>item.t?item.t=2:""); //刪 set.forEach(item=>item.t?set.delete(item):""); let index=ary.findIndex(item=>item.t) ary.splice(index,1) console.log(set,ary)數據結構- 和對象Object的對比
###Map,Set與Object的對比 //map,set,object對比 let item={t:1}; let set=new Set(); let map=new Map(); let obj={}; //增 map.set("t",1); set.add(item); obj["t"]=1; console.log("map-set-obj",map,set,obj) //查 console.info({ map_exist:map.has("t"), set_exist:set.has(item), obj_exist:"t" in obj }) //改 map.set("t",2); item.t=2; obj["t"]=2; console.log("map-set-obj",map,set,obj) //刪 map.delete("t") set.delete(item) delete obj["t"]; console.log("map-set-obj",map,set,obj)
小總結:數據開發中,涉及數據結構,能使用map,不使用數組;如果對數據要求比較高,比如數據唯一性,考慮使用
類 類的基本定義和生成實例: classclass Parent{ constructor(name="leilei"){ this.name=name; } } let v_parent=new Parent("ymy"); console.log(v_parent.name)類的繼承: extends
class Parent{ constructor(name="leilei"){ this.name=name; } } class Child extends Parent{ //繼承:子類怎么在自己的構造函數中傳遞參數 constructor(name="child"){ super(name);//如果不傳參,子類使用的是父類默認的參數;super一定放在構造函數的第一行; this.type="child"; } } console.dir(new Child("hello"))
類中的getter和setter
分別用來獲取屬性和設置屬性
class Parent{ constructor(name="leilei"){ this.name=name; } get longName(){ return "ymy "+this.name; } set longName(value){ this.name=value; } } // 創建實例 let p1=new Parent(); console.log(p1.longName) //獲取屬性 p1.longName="tangtang"; //設置屬性
給類中添加靜態方法 static
注意:static屬性只能用來設置類的靜態方法,不能用來設置類的靜態屬性
類的靜態屬性只能通過: 類.key=value;來設置
類的靜態方法,只有類能使用,實例不能使用,實例只能使用原型上的屬性和方法;
class Parent{ constructor(name="leilei"){ this.name=name; } //設置靜態方法 static tell(){ console.log("tell"); } } Parent.sex="gril"; //設置類的靜態屬性 Parent.tell() //調用類的靜態方法;es6 Iterator 和 for...of 循環 什么是Iterator接口
ES6中內置了一些Symbol,其中最重要的一個恐怕就是Symbol.iterator了,相當于迭代器的接口,只有對象里有這個symbol的屬性,才可以認為此對象是可迭代的。
我們先看一下規范中對這個symbol的描述:
A method that returns the default Iterator for an object. Called by the semantics of the for-of statement.
js中哪些對象里實現了這個接口呢?常見的有Array,String,arguments,還有后面高級的數據結構,如Set,Map等。
for...of
for...of循環的過程,其實就是通過不斷調用Iterator接口來達到這種形式;
也就是說,不同的數據結構,通過for...of這種統一的形式,來達到讀取不同數據結構的目標;但是背后的Iterator接口其實不同;
數組自動幫我們帶了iterator接口
let arr=["hello","world"]; let map=arr[Symbol.iterator](); console.log(map.next()); console.log(map.next()); console.log(map.next());
Object {value: "hello", done: false};done代表,是否做完了所有操作,true:代表是; false:代表無,還有其他操作;
Object對象不是一個iterator,那么如何把它變成一個iterator呢?
let obj={ start:[1,3,2], end:[7,8,9], [Symbol.iterator](){ let self=this; let index=0; let arr=self.start.concat(self.end); let len=arr.length; return { next (){ if(indexlet...of的使用
let arr=["hello","world"]; for(let value of arr){ console.log(value); }Generator 基本概念Generator函數有多種理解角度。從語法上,首先可以把它理解成,Generator函數是一個狀態機,封裝了多個內部狀態。
執行Generator函數會返回一個遍歷器對象,也就是說,Generator函數除了狀態機,還是一個遍歷器對象生成函數。返回的遍歷器對象,可以依次遍歷Generator函數內部的每一個狀態。
形式上Generator函數是一個普通函數,但是有兩個特征。
function關鍵字與函數名之間有一個星號*;
函數體內部使用yield語句,定義不同的內部狀態(yield語句在英語里的意思就是“產出”)。let tell=function* () { yield "a"; yield "b"; yield "c"; }; let k=tell(); console.log(k.next()); console.log(k.next()); console.log(k.next()); console.log(k.next());上面代碼定義了一個Generator函數tell,它內部有三個yield語句"a","b"和"c" ; 即該函數有三個狀態:"a","b"和"c"語句(結束執行)。
總結一下,調用Generator函數,返回一個遍歷器對象,代表Generator函數的內部指針。以后,每次調用遍歷器對象的next方法,就會返回一個有著value和done兩個屬性的對象。value屬性表示當前的內部狀態的值,是yield語句后面那個表達式的值;done屬性是一個布爾值,表示是否遍歷結束。true:表示遍歷結束,false:表示遍歷沒結束;
yield需要注意的是,yield語句后面的表達式,只有當調用next方法、內部指針指向該語句時才會執行,因此等于為JavaScript提供了手動的“惰性求值”(Lazy Evaluation)的語法功能。
function* gen() {
yield 123 + 456;
}
上面代碼中,yield后面的表達式123 + 456,不會立即求值,只會在next方法將指針移到這一句時,才會求值。yield語句注意事項
yield語句不能用在普通函數中,否則會報錯。
yield語句如果用在一個表達式之中,必須放在圓括號里面。
console.log("Hello" + yield); // SyntaxError
console.log("Hello" + yield 123); // SyntaxErrorconsole.log("Hello" + (yield)); // OK
console.log("Hello" + (yield 123)); // OK
yield語句用作函數參數或賦值表達式的右邊,可以不加括號。
foo(yield "a", yield "b"); // OK
let input = yield; // OK
暫緩執行函數Generator函數可以不用yield語句,這時就變成了一個單純的暫緩執行函數。
function* f() { console.log("執行了!") } var generator = f(); setTimeout(function () { generator.next() }, 2000);上面代碼中,函數f如果是普通函數,在為變量generator賦值時就會執行。但是,函數f是一個Generator函數,就變成只有調用next方法時,函數f才會執行。
Generator 與 Iterator接口的關系
任意一個對象的Symbol.iterator方法,等于該對象的遍歷器生成函數,調用該函數會返回該對象的一個遍歷器對象。
由于Generator函數就是遍歷器生成函數,因此可以把Generator賦值給對象的Symbol.iterator屬性,從而使得該對象具有Iterator接口。
//generator對象的新應用:給obj對象部署Iterator;
let obj={}; obj[Symbol.iterator]=function* () { yield 1; yield 2; yield 3; }; for(let value of obj){ console.log(value); }用Generator寫抽獎
let draw=function (count) { //具體抽獎邏輯 console.info(`剩余${count}抽獎次數`); }; let residue=function* (count) { while(count>0){ count--; yield draw(count); } }; let star=residue(5); let btn=document.createElement("button"); btn.innerHTML="點擊抽獎"; document.body.appendChild(btn); btn.onclick=function () { star.next(); }前端定時的去接收服務端的變化
兩種辦法:1)websocket-兼容性不好 ; 2)常輪詢-看如下代碼
let ajax=function* () { yield new Promise((resolve,reject)=>{ setTimeout(function () { resolve({code:0}) },200) }) }; let pull=function () { let generator=ajax(); let step=generator.next(); //拿回后臺的數據 step.value.then(function (d) { if(d.code!=0){ setTimeout(function () { console.info("wait"); pull(); },1000) }else{ console.log(d); } }) }; pull();
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88702.html
摘要:本套課程包含兩大部分,第一部分是基礎部分,也是重要部分,參考官方文檔結構,針對內容之間的關聯性和前后順序進行合理調整。 showImg(https://segmentfault.com/img/bVbpBA0?w=1460&h=400); 講師簡介: iview 核心開發者,iview-admin 作者,百萬級虛擬渲染表格組件 vue-bigdata-table 作者。目前就職于知名互...
摘要:那么什么是基礎對象組件呢,舉兩個例子我們再來看看屬性訪問器,就是括號操作符及點號操作符都做了什么屬性訪問器也就是說括號跟點號對解釋器而言是一樣的。 ES規范解讀之賦值操作符&屬性訪問器 原文:https://github.com/kuitos/kuitos.github.io/issues/24事情起源于某天某妹子同事在看angular文檔中關于Scope的說明Understandin...
摘要:所以這是一篇插隊的文章,用于去理解中的裝飾器和概念。因此,該的作用就是根據入參返回具體的描述符。其次局部來看,裝飾器具體應用表達式是,其函數簽名和是一模一樣。等裝飾器語法,是和直接使用是等效等價的。 ================前言=================== 初衷:以系列故事的方式展現 MobX 源碼邏輯,盡可能以易懂的方式講解源碼; 本系列文章: 《【用故事解...
摘要:最近開始看源碼,并將源碼解讀放在了我的計劃中。相對于其他源碼解讀的文章,基本都會從整體設計開始講起,樓主覺得這個庫有點特殊,決定按照自己的思路,從用代替說起。源碼沒有出現注意,其實有出現一處,是為,而不是,而用代替之。 Why underscore 最近開始看 underscore源碼,并將 underscore源碼解讀 放在了我的 2016計劃 中。 閱讀一些著名框架類庫的源碼,就好...
閱讀 2384·2023-04-26 02:54
閱讀 2307·2021-10-14 09:43
閱讀 3341·2021-09-22 15:19
閱讀 2837·2019-08-30 15:44
閱讀 2697·2019-08-30 12:54
閱讀 980·2019-08-29 18:43
閱讀 1932·2019-08-29 17:12
閱讀 1325·2019-08-29 16:40