用於塊級做用域
不存在變量提高
不可重複聲明
未聲明不可以使用
不可以使用window去調用前端
不可重複定義
不可對重複賦值
不存在變量提高
不容許先賦值後聲明es6
規定程序源代碼中定義的變量執行區域
規定了如何查找等一些列規則正則表達式
全局做用域(global,window)
局部做用域(函數做用域)
塊級做用域(let。const定義的代碼塊區域)
動態做用域(this)數組
函數之外定義的變量
函數內部不經過var定義的變量
不經過var等定義的變量屬於window下面的屬性能夠被刪除。var則不能夠,嚴格意義上來講直接定義的變量不屬於全局變量promise
對於可迭代的對象建立一個迭代循環app
轉成數組,用法:
Array.from(arrayLike[, mapFn[, thisArg]])
arrayLike類數組或可迭代對象
mapFn若是指定了該參數,都會執行
可選參數,執行回調函數 mapFn 時 this 對象異步
填充數組
arr.fill(value[, start[, end]])
value填充元素
start起始索引
end結束索引
let arr=[1,4,6,7]
arr.fill(99,1,9)async
建立數組
let arr=Array.of(1,43,6,8)函數
find() 方法返回數組中知足提供的測試函數的第一個元素的值,不然返回 undefined。測試
findIndex()方法返回數組中知足提供的測試函數的第一個元素的索引。不然返回-1。其實這個和 find() 是成對的,不一樣的是它返回的是索引而不是值。
如何定義並實例化一個類?
es5
function Fn(type) { this.name = type } let fn = new Fn('miya') console.log(fn)
es6
class Fn { constructor(val) { this.name = val } } let fn = new Fn('miya') console.log(fn)
如何讀寫屬性?
es6容許把屬性放到函數最頂層,而不是必須放到constructor()函數中
放到最頂層前面加set或者get,由於添加上就會變成屬性。
set和get的操做可讓咱們靈活改變返回值,可是返回值和出口值不能相同
get+set
class Animal {
constructor (type, age) { this.type = type this._age = age } get age () { return this._age } set age (val) { this._age = val }
}
es5屬性進行修改沒法攔截,有條件寫和設置丟作不到
es6經過get。set就能夠作到,讓你在讀寫操做上有更大的操做權,甚至能夠定製化
操做方法
經過對象實例 添加方法
經過類的靜態方法添加
定義時前面添加static fn(){}
使用時類調用
class Animal { constructor(type, age) { this.type = type this._age = age } get age() { return this._age } set age(val) { this._age = val } static run() { console.log('run ') } } let a = new Animal('miya', 18)
不屬於對象實例上的方法,屬於類的靜態方法,直接從對象實例訪問不到
經過類去訪問
若是這個方法不依賴對象實例上的屬性和方法使用類的靜態方法
反之,使用對象的實例方法
對象屬性值簡寫
key。value的簡寫
屬性支持變量和表達式,只需用花括號抱起來便可
在obejct中能夠添加異步函數(加*)
let [x,y]=[1,99] let obj={x,y,[x+y]:8,* fn (){console.log(212)}}
set
值能夠是任意值
方法:添加
let s=new Set()
s.add(12).add(89)
方法:刪除某一項。
let s=new Set()
s.add(12).add(89)
s.delete(10)
方法:刪除全部。
let s=new Set()
s.add(12).add(89)
s.clear()
方法:判斷元素是否存在
let s=new Set()
s.add(12).add(89)
s.has(12)
keys=>獲取全部keys值
values=>獲取全部value值
s.entries()=>獲取健值對
屬性:獲取已經存元素的長度
let s=new Set()
s.add(12).add(89)
s.size()
map
添加修改:
let m=new Map()
m.set('a',1).set('b',2)
根據key值查找
let m=new Map()
m.set('a',1).set('b',2)
m.has('a')
let m=new Map()
m.set('a',1).set('b',2)
m.delete('a')
方法:刪除全部。
let m=new Map()
m.set('a',1).set('b',2)
s.clear()
let m=new Map()
m.set('a',1).set('b',2)
keys=>獲取全部keys值
values=>獲取全部value值
m.entries()=>獲取健值對
屬性:獲取已經存元素的長度
let m=new Map()
m.set('a',1).set('b',2)
m.size()
Object.assign
對象的拷貝
優缺點:
優勢實現對象的淺拷貝
缺點會出現數據丟失,不能直接實現深拷貝(用遞歸能夠實現)
淺拷貝對不是引用類型的值作數據替換;引用類型則直接替換地址
若是目標對象是undefined或者null會引起錯誤
原對象是undefined或者null則會返回object
let target={}
Object.assign(target,{a:1.b:2})
y修飾符(粘連)
連續匹配,用法以下:
let str = 'aaa_aa_a' let r1 = /a+/g let r2 = /a+/y console.log(r1.exec(str)) console.log(r2.exec(str)) console.log(r1.exec(str)) console.log(r2.exec(str))
u修飾符
使用方法:我是前端的${'小學生 '}
變量結構賦值:重點是在賦值,賦值的元素是要拷貝出來賦值給變量,賦值元素自己將不會收到改變
Array Destructuring
若是想忽略數組中的某一項,可使用逗號來處理
let [a,,b]=['miya','youzi','hanmeimei','xioaming']
let [a,b,c]='abc'
let [x,y,z]=new Set([1,2,4])
let user={}
[user.name,user.surname]='Ilya Kantor'.split(' ')
user //{name: "Ilya", surname: "Kantor"}
四、循環體
let obj = {
name: 'hanmeimei', addr: 'beijing' } for (let [k, v] of Object.entries(obj)) { console.log(k, v) }
let [x,y,...rest]=[1,3,5,6,8,9]
let [u,i] =[]
默認值爲 undefined
object Destructuring
在這個結構賦值的過程當中,左側的「模板」結構要與右側的 Object 一致,可是屬性的順序無需一致。
let {name,addr}={name:'liming',addr:'beijing'}
let options={title:'Menu'}
let {width=100,height=200,title}=options
let obj1={name:'hanmeimei'}
let obj2={addr:'beijing'}
let obj3={...obj1,...obj2}
js中有不少異步操做,異步操做不是此刻完成,而是以後完成後,
描述按順序加載不一樣的腳本,採用了回調以後再回調的連鎖過程,這樣代碼看起來就會臃腫不少
嵌套越深,代碼層次就會變深,維護難度也就加增長,因此出現了promise
Promise的工做原理?
首先new Promise的時候,咱們須要關心2個內容。
status:會有一個padding狀態被掛起
result:返回值此時是underfind
經過resolve和reject方法去改變狀態,此時需注意。狀態不可逆,一旦確認,沒法改變
經過then方法去傳遞執行,執行then方法以後會返回一個promise對象,這樣就能夠完成鏈式操做
靜態方法
使用.catch能夠捕獲鏈式操做的錯誤
是promise對象上的方法,不是promise靜態的方法
避免每次在then上部署錯誤處理
不要使用throw的方式去觸發,使用reject的方法去觸發promise狀態的改變,去捕獲錯誤
並行操做
Promise.race 生成並返回一個新的 Promise 對象。
參數 promise 數組中的任何一個 Promise 對象若是變爲 resolve 或者 reject 的話, 該函數就會返回,並使用這個 Promise 對象的值進行 resolve 或者 reject。
是promise2個靜態的方法,必須使用promise的類調用執行
resove觸發成功操做
reject觸發失敗的操做
對象上的方法
使用。catch能夠捕獲鏈式操做的錯誤
是promise對象上的方法,不是promise靜態的方法
避免每次在then上部署錯誤處理
不要使用throw的方式去觸發,使用reject的方法去觸發promise狀態的改變,去捕獲錯誤
then方法
- 怎麼去用? then是promise對象原型上的方法,只要是promis對象就能夠調用此方法。 語法fn().then(onFulfilled,onReject) onFulfilled,onReject分別對應成功與失敗2個方法 若是沒傳函數,默認會被忽略,返回一個空的promise對象 若是後面不是函數,是表達式也會被執行,返回結果, 調用.then會返回一個promise實例 - 工做原理是什麼? 首先調用,then()它會返回一個promise對象。因此才能夠產生鏈式調用 當then的參數不爲函數時。返回使用return中斷後續then方法
反射機制。函數執行先調用。再去查找那個方法使用。
defineProperty
靜態方法 Reflect.defineProperty() 基本等同於 Object.defineProperty() 方法,惟一不一樣是返回 Boolean 值。
deleteProperty
靜態方法 Reflect.deleteProperty() 容許用於刪除屬性。它很像 delete operator ,但它是一個函數。
apply
經過指定的參數列表發起對目標(target)函數的調用
能夠動態化去控制方法,
apply
原來:先肯定調用對象,後跟apply方法Math.floor.apply(null,[12.433])
如今:先綁定apply。在進行執行方法。Reflect.apply(Math.floor,null,[12.433])
使用場景
價格判斷,好比超多100使用向下取整,沒超過使用向上取整
old:let price = 18.9090
price = price >= 100 ? Math.floor.apply(null, [price]) : Math.ceil.apply(null, [price])
new: price = Reflect.apply(price >= 100 ? Math.floor : Math.ceil, null, [price])
construct
Reflect.construct() 方法的行爲有點像 new 操做符 構造函數 , 至關於運行 new target(...args).
newTarget新建立對象的原型對象, 參考 new.target 操做符,默認值爲target。
Reflect.construct容許你使用可變的參數來調用構造函數 ,這和使用new操做符搭配對象展開符調用同樣。
Reflect.construct(target, argumentsList[, newTarget])
被運行的目標構造函數
類數組,目標構造函數調用時的參數。
新建立對象的原型對象, 參考 new.target 操做符,默認值爲target。
雖然兩種方式結果相同,但在建立對象過程當中仍一點不一樣
當使用Object.create()和Function.prototype.apply()時,若是不使用new操做符調用構造函數,構造函數內部的new.target值會指向undefined。
當調用Reflect.construct()來建立對象,new.target值會自動指定到targe(或者newTarget,前提是newTarget指定了)。
get
Reflect.get()方法與從 對象 (target[propertyKey]) 中讀取屬性相似,但它是經過一個函數執行來操做的。
getOwnPropertyDescriptor
Reflect.getOwnPropertyDescriptor() 與 Object.getOwnPropertyDescriptor() 方法類似。若是在對象中存在,則返回給定的屬性的屬性描述符。不然返回 undefined。
描述符分爲:數據描述符和存取描述符
value:‘數據’
writable:是否可被重寫,默認false
enumerable:是否能夠被遍歷,默認false
configurable:是否能夠被刪除,默認false
getPrototypeOf
getPrototypeOf返回指定對象的原型
has
靜態方法 Reflect.has() 做用與 in 操做符 相同。
Reflect.has({x: 0}, "y"); // false
Reflect.has({x: 0}, "x"); // true
isExtensible
靜態方法 Reflect.isExtensible() 判斷一個對象是否可擴展 (便是否可以添加新的屬性)。與它 Object.isExtensible() 方法類似,但有一些不一樣,
傳值爲一個對象,返回當前對象是否能夠添加擴展屬性
傳入非對象會觸發錯誤
也是判斷當前傳入對象是否能夠擴展
傳入非對象時,非對象的第一個參數會被強制轉換爲一個對象。返回布爾值。不會報錯
ownKeys
Reflect.ownKeys() 返回一個由目標對象自身的屬性鍵組成的數組。
preventExtensions
Reflect.preventExtensions() 方法阻止新屬性添加到對象 例如:防止未來對對象的擴展被添加到對象中)。該方法與 Object.preventExtensions()類似,但有一些不一樣點。
返回值爲布爾值
當傳入的值不爲對象的時候,會引起錯誤
Object.preventExtensions() 方法, 非對象的第一個參數將被強制轉換爲對象。
set
Reflect.set() 工做方式就像在一個對象上設置一個屬性。
返回值爲一個布爾值
setPrototypeOf
指定對象的原型
它能夠自定義一些行爲,好比查找,循環、賦值。函數執行
基礎用法:new proxy(target,handler)
target要被代理的對象,能夠是對象,函數,或者另外一個代理
handler一個對象。被代理的過程
處理key。value值
過濾不存在的屬性
表單驗證
閱後即焚
proxy中有能夠建立臨時代理,能夠取消,一旦調用revoke。prox將失效,也就是是臨時代理
用法
let obj={name:'柚子'}
let o=Proxy.revocable(obj,{})
o.revoke()
用法
let obj = {
name: 'miya', age: 190 } window.addEventListener('error', e => { console.log(e) }, true) let validator = { set(target, key, value) { if (!Reflect.has(target, key)) return '' if (key === 'age') { if (typeof value !== 'number' || Number.isNaN(value)) { throw new TypeError('Age mast be a number') } if (value <= 0) { throw new TypeError('Age must be a positive number') } } return target[key] = value } } let d = new Proxy(obj, validator) d.age = '90' console.log(d.age)
可控制迭代器的函數,能夠暫停,也能夠選擇任什麼時候候恢復
比普通函數多了一個*
函數內部使用yield來控制函數執行的暫停
Generator不可使用尖頭函數,會產生錯誤
Generator函數能夠嵌套,在yield後添加*
恢復執行函數適應next方法,此函數返回一個對象,分別是當前程序執行的狀態和數據,也可傳參數,參數將做爲yield返回值
抽獎(批量產生)
異步數據的加載
常常玩一些小遊戲,好比數數字,遇到 3 的倍數就要跳過,從 1 一直往下數
斐波那契數列
方法
Generator 對象經過next方法來獲取每次遍歷的結果。這個對象返回一個對象,對象中包含2個屬性:
value:當前程序運行的結果
done:遍歷是否結束
next方法能夠接受參數。這個參數是能夠傳入到Generator函數中,這個參數就是做爲yield的返回值
可使 Generator 遍歷終止,相似for break
也可傳參數,做爲yield的返回值
也是能夠中斷函數執行
能夠經過 throw 方法在 Generator 外部控制內部執行的「終斷」。
若是想退出遍歷 catch 以後能夠配合return false, 能夠起到break 的功效
yield表達式用於暫停和恢復一個生成器函數
yield表達式返回是一個underfind,可是遍歷器對象的next方法能夠傳參數改變這個默認值。
yield後可添加*,表示後面繼續是個可遍歷,可迭代對象,也可嵌套Generator對象
function* fn(x=0,y=1){ while(1){yield x+y; [y,x]=[x,x+y]}}
let f=fn()
f.next()
{value: 1, done: false}
f.next()
{value: 1, done: false}
f.next()
{value: 2, done: false}
f.next()
{value: 3, done: false}
f.next()
{value: 5, done: false}
f.next()
{value: 8, done: false}
for of是爲可迭代對象建立一個迭代循環。
可迭代協議容許js去自定義定製他的迭代行爲,例如在for of中那些元素能夠被循環等。一些內置的對象有默認迭代行爲,好比array,map,另外一類則不具有(object)
自定義遍歷器必須知足2個條件。
可迭代協議
迭代器協議
什麼是迭代器協議?
首先是一個對象
返回一個無參函數next()
函數返回一個對象,對象包含done和value屬性。
down表明當前遍歷程序是否結束
value表明當前遍歷數據
4.next(返回若是不是對象)會報錯
爲了變成可迭代對象, 一個對象必須實現 @@iterator 方法, 意思是這個對象(或者它原型鏈 prototype chain 上的某個對象)必須有一個名字是 Symbol.iterator 的屬性
若是讓一個對象是可遍歷的,就要遵照可迭代協議,該協議要求對象要部署一個以 Symbol.iterator 爲 key 的鍵值對,而 value 就是一個無參函數,這個函數返回的對象要遵照迭代器協議。
Generator是自然的具有迭代器協議。
使用Generator 配合可迭代協議就再也不須要顯示的寫迭代協議了(next方法和包含 done、value 屬性的返回對象)。
用法
需求咱們須要遍歷全部的做者名字
let authors = {
allAuthors: { fiction: [ 'Agatha Christie', 'J. K. Rowling', 'Dr. Seuss' ], scienceFiction: [ 'Neal Stephenson', 'Arthur Clarke', 'Isaac Asimov', 'Robert Heinlein' ], fantasy: [ 'J. R. R. Tolkien', 'J. K. Rowling', 'Terry Pratchett' ] } }
allAuthors[Symbol.iterator] = function* () {
let allAuthors = this.allAuthors let keys = Reflect.ownKeys(allAuthors) let values = [] while (1) { if (!values.length) { if (keys.length) { values = allAuthors[keys[0]] keys.shift() yield values.shift() } else { return false } } else { yield values.shift() } } } for (let item of obj) { console.log(item) }
導出
export const name='miya'
export let addr=''beijing'
export let list=[1,2,4]
or:
const name='miya'
let addr=''beijing'
let list=[1,2,4]
export {name,addr,list}
export function say (content){
console.log(content);
}
export let run=(content)=>console.log(content)
or:
function say (content){
console.log(content);
}
let run=(content)=>console.log(content
export {say,run}
let data={code:0,msg:'請求成功',data:{name:'miya'}}
export {data}
export class Test{
constructor(){
this.id = 2
}}
or :
class Test{
constructor(){
this.id = 2
}}
export {Test}
導入
export const name='miya'
export let addr=''beijing'
export let list=[1,2,4]
導入:
import {name,addr,list} from 'a.js'
export const name='miya'
export let addr=''beijing'
export let list=[1,2,4]
導入:
import {name as cname,addr,list} from 'a.js'
export const name = 'miya'
export let addr = 'beijing'
export let list = [1, 2, 4]
導入:
import * as md from 'index.js'
判斷一個元素是否存在數組中,返回值爲布爾值用法以下:
let arr=[12,40,289]
arr.includes(40) //true
arr.find(key=>key===40) //40
Math.pow() 函數返回基數(base)的指數(exponent)次冪,即 baseexponent
用法以下:
Math.pow(2,5)//32
2**5//32
是promise的語法糖
使用 Promise 以後可讓咱們書寫異步操做更加簡單,而 async 是讓咱們寫起 Promise 像同步操做
async 函數顯式返回的不是 Promise 的話,會自動包裝成 Promise 對象
await 不能夠脫離 async 單獨使用
獲取對象的描述符
用於遍歷集合,建立一個循環來迭代可迭代的對象
處理異步操做
for awite of
用於操做異步集合的操做
// function geo(time) { // return new Promise((resolv, reject) => { // setTimeout(() => { // resolv(time) // }, time) // }) // } // async function test() { // let arr = [geo(2000), geo(100), geo(3000)] // for await (const item of arr) { // console.log(new Date().getTime(), item) // } // } // test()
Promise.prototype.finally() 方法返回一個Promise,在promise執行結束時,不管結果是fulfilled或者是rejected,在執行then()和catch()後,都會執行finally指定的回調函數。這爲指定執行完promise後,不管結果是fulfilled仍是rejected都須要執行的代碼提供了一種方式,避免一樣的語句須要在then()和catch()中各寫一次的狀況。
數組中咱們經常使用...來合併數組
對象中合併也可使用object的rest進行2個對象的合併。他的原理是淺拷貝。不是引用。用法以下:
let obj={a:1,b:2,c:3}
let obj2={...obj,f:9090}
console.log(obj2)//{a: 1, b: 2, c: 3, f: 9090}
當對象 key-value 不肯定的時候,把必選的 key 賦值給變量,用一個變量收斂其餘可選的 key 數據,用法以下:
let obj={a: 1, b: 2, c: 3, f: 9090}
let {a,b,...rest}=obj
console.log(a,b,rest)
1 2 {c: 3, f: 9090}
do Al l
正則表達式中,點(.)是一個特殊字符,表明任意的單個字符,可是有兩個例外。
一、一個是四個字節的 UTF-16 字符,這個能夠用u修飾符解決;
二、另外一個是行終止符(line terminator character)。/n 和/r
用法以下:
/foo.boo/s.test('foonboo')
命名捕獲
後行斷言
先行斷言
對於一些超出範圍的 Unicode,爲其輸出轉義序列,使其成爲有效 Unicode
https://developer.mozilla.org...
指定嵌套數組結構應展平的深度級別。默認爲1。
let arr=[1,[2,6,[9]]]
arr.flat(1) // [1, 2, 6, Array(1)]
arr.flat(2) //[1, 2, 6, 9]
arr.flat(Infinity) //[1, 2, 6, 9]
https://developer.mozilla.org...
首先使用映射函數映射每一個元素,而後將結果展平爲新數組。它與深度爲1 map()的a 相同flat(),但flatMap()一般很是有用,由於將二者合併爲一種方法效率更高。
let arr= [1, 0, 6, 9]
arr.flatMap(item=>[item*2]) //[2, 0, 12, 18]
https://developer.mozilla.org...
去開始空格
let str=' u '
str.trimStart() // 'u '
去除結束空格
let str=' u '
str.trimEnd() // ' u'
matchAll()
針對字符串返回正則表達式的全部匹配項。
let str = '"foo" "boo" sd "ooo"'
let collectGroup1 = (str, regExp) => {
let matches = [] for (let item of str.matchAll(regExp)) { matches.push(item[1]) } return matches } console.log(collectGroup1(str, /"([^"]*)"/g))
把鍵值對列表轉換爲一個對象,這個方法是和 Object.entries() 相對的。
let search = window.location.search.substr(1).split('&');
Object.fromEntries(search.map(k => k.split('=')))
經過 description 方法獲取 Symbol 的描述
let symbol=Symbol('My name is miya')
symbol.description// My name is miya
toString() 方法返回一個表示當前函數源代碼的字符串
let say=()=>console.log('hhhh')
say.toString() //()=>console.log('hhhh')
try {
console.log('Foobar')
} catch {
console.error('Bar')
}
XMind: ZEN - Trial Version