Day 81 ES6
ES6
var a = 2; var a = 5; console.log(a); // 5
let
1、let 聲明變量,沒有變量提升
console.log(b) // Uncaught ReferenceError: Cannot access 'b' before initialization let b = 3 console.log(b) # 3
2、是一個塊作用域
if(1===1){ let c = 10; console.log(c) // 10 } console.log(c) // Uncaught ReferenceError: c is not defined
3、不能重復聲明
let d = 10; let d = 20; console.log(d) // Uncaught SyntaxError: Identifier 'd' has already been declared
const
聲明常量,一旦被聲明,無法修改
const 聲明變量,沒有變量提升;是一個塊作用域;不能重復聲明
const max = 10; const max = 20; // Uncaught SyntaxError: Identifier 'max' has already been declared console.log(max)
const 可以修改常量內的值
const dit = { "name":'ysg' } dit.name='ysging' console.log(dit) // {name: "ysging"}
作用
作用一:for循環的經典例子
var arr = [] for (var i = 0; i < 10; i++) { arr[i] = function () { return i } } console.log(arr[5]()) // 10 const arr = [] for (let i = 0; i < 10; i++) { arr[i] = function () { return i } } console.log(arr[5]()) // 5
作用二:不會污染全局變量
var count = 10; console.log(count) // 10 console.log(window.count) // 10 let count = 10; console.log(count) // 10 console.log(window.count) // undefined 建議:一般情況下使用 count 來聲明變量,而只有你在知道變量值需要被修改的情況下使用 set 。
模板字符串
模板字符串:使用反引號,插入值:${}
const Box = document.querySelector('#box') let name = 'ysg' let id = 16 let htmlstr = ` <ul> <li> <p id=${id}>${name}</p> </li> </ul> ` Box.innerHTML = htmlstr
函數之默認值
function add(a=10,b=20){ return a + b } console.log(add())
剩余參數
剩余參數:...參數名,解決了 arguments 的問題
function add(a,...keys){ let res = Object.create(null); for(let i=0; i<keys.length; i++){ res[keys[i]] = a[keys[i]] } return res # {name: "ysg", age: "16", city: "新鄉"} } let dit = { 'name':'ysg', 'age':'16', 'city':'新鄉' } console.log(add(dit,'name','age','city'))
擴展運算符:將一個數組分割,并將各個項作為分離的參數傳遞給函數
const arr = [12,485,85,156,54,1,6,]
console.log(Math.max(...arr))
箭頭函數
箭頭函數:使用 => 來定義,相當于 function(){} 等于 ()=>{}
// 無參數 let fun = () => "Hello world" + ' 123' console.log(fun()) let fun = () =>({'name':'ysg','age':'16'}) console.log(fun()) // 一個參數 let fun = val => val console.log(fun(10)) // 兩個參數 let add = (a,b) => { return a + b } console.log(add(10,20)) let add = (a,b) => a + b console.log(add(10,20)) // 閉包函數 let fn = (()=>{ return ()=>{ console.log('hello world') } })(); fn();
箭頭函數沒有 this 指向,箭頭函數內部 this 值只能通過查找作用域鏈接來確定
let PageHandle = { id:123, init:function(){ // 箭頭函數沒有 this 指向,箭頭函數內部 this 值只能通過查找作用域鏈接來確定 document.addEventListener('click',(event)=>{ this.dcSomeThings(event,type) },false) }, dcSomeThings:function(type){ console.log(`事件類型:${this},當前id:${this.id}`); } } PageHandle.init();
注意:
使用箭頭函數注意事項:
1、函數內部沒有 arguments
2、不能使用 new 關鍵字實例化對象
解構賦值
解構賦值是對賦值運算符的一種擴展,它針對數組和對象進行操作;優點:代碼書寫更簡潔易讀。
let dit = { 'name':'ysg', 'age':'17' } let {name,age} = dit console.log(name,age) // ysg 17 let list = [1,2,3]; let [a,b,c] = list console.log(a,b,c) // 1 2 3
對象的擴展功能
ES6 允許直接寫入變量和函數,作為對象的屬性和方法
const name = 'ysg',age = 20 const person = {name, age, sayName(){ console.log(this.name) }} person.sayName()
let cart={ wheel:4, set(newVal){ if (newVal < this.wheel) { throw new Error('輪子太少了') } this.wheel = newVal; }, get(){ return this.wheel; } } cart.set(7); console.log(cart.get());
對象的方法
is() 等價于 === ,比較兩個字是否嚴格相等
console.log(NaN === NaN) // false console.log(Object.is(NaN,NaN)) // true
assign() 用戶對象的合并
let newObj = Object.assign({c:3},{a:1},{b:2})
console.log(newObj) # {c: 3, a: 1, b: 2}
Synbol 類型
原始數據類型,它表示獨一無二的值,最大的用途:用來定義對象的私有變量
獨一無二意味著內存地址不同
// 定義 const name = Symbol('name') const name2 = Symbol('name') console.log(Object.is(name,name2)) // false // 取值 let s1 = Symbol('ysg') console.log(s1) // Symbol(ysg) let obj = { [s1] : '小馬哥' } console.log(obj) // {Symbol(ysg): "小馬哥"} // 方法一: console.log(obj[s1]) // 小馬哥 // 方法二: let s = Object.getOwnPropertySymbols(obj) console.log(s[0]) // 方法三:反射 let m = Reflect.ownKeys(obj); console.log(m)
Set 集合
是一組無重復的有序列表
// 新建集合 let set = new Set() console.log(set) // Set(0) {} // 添加數據 set.add(1) set.add(2) set.add(2) console.log(set) // {1, 2} // 校驗數據 console.log(set.has(2)) // true // 查看長度 console.log(set.size) // 2 // 刪除數據 set.delete(2); console.log(set) // Set(1) {1} // 將 set 轉為數組 let set2 = new Set([1,2,4,5,6]) let lsit = [...set2] console.log(lsit) // [1, 2, 4, 5, 6]
注意:Set 中對象的引用無法被釋放,一般是 WeakSet() 來引用
weakSet
1、不能傳入非對象類型的參數
2、不可迭代
3、沒有 forEach()
4、沒有 size 屬性
Map 類型
是一組鍵值對的有序列表,鍵和值可以是任意類型
let map2 = new Map([ ['張三','zhangsan'], ['李四','lisi'] ]); console.log(map2); let map = new Map() map.set('name','ysg') map.set('age','16') console.log(map) console.log(map.get('name')) console.log(map.has('name')) console.log(map.size) map.delete('name') console.log(map) map.clear() console.log(map)
數據的擴展
from() 將維數組轉為真正的數組
<div id = 'box'> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </div> # 簡單實例 function add(){ let arr = Array.from(arguments) console.log(arr); } add(1,2,3) let li = document.querySelectorAll('li') // from let list = Array.from(li) console.log(list) // 擴展運算符 let lis = [...li] console.log(lis) // from 還可以傳遞第二個參數,用來對每個元素進行處理 let list2 = Array.from(li,li=>li.textContent) console.log(list2)
of() 將任意一組數值,轉換為數組
of_list = Array.of('1','2','3') console.log(of_list)
copyWithin() 數組內部將指定位置的元素復制到其它的位置,返回當前數組
list = [1,2,3,4,5,6,7,8].copyWithin(0,3)
console.log(list)
find() 查找元素,返回第一個符合條件的元素
findindex() 查找索引,返回第一個符合條件的元素下標
let num = [1,2,3,4,5,6,7,8].find(n => n > 6) console.log(num) // 7 let num2 = [1,2,3,4,5,6,7,8].findIndex(n => n > 6) console.log(num2) // 6
keys()、values()、entries() 遍歷器,可以使用 for ... of 循環進行遍歷
for(let index of ['a','b'].keys()){ console.log(index) // 索引:0 1 } for(let index of ['a','b'].values()){ console.log(index) // 值:a b } for(let index of ['a','b'].entries()){ console.log(index) // 索引,值:(2) [0, "a"] (2) [1, "b"] }
includes() 返回一個布爾值,表示某個數組是否包含指定的值
console.log([1,2,3].includes(3)) // true
console.log([1,2,3].includes(4)) // false
迭代器
1、迭代器是一個接口,能快捷的方位數據,通過 Symbol.iterator 來創建迭代器,通過迭代器的 next() 獲取值
2、迭代器是用于遍歷數據結構的指針(類似于數據庫中的游標)
const items = ['ysg','ysging','czx'] const ite = items[Symbol.iterator](); console.log(ite.next()); // {value: "ysg", done: false} done 如果為 false,表示遍歷繼續,為 true 表示遍歷完成 console.log(ite.next()); console.log(ite.next()); console.log(ite.next());
生成器
generator 函數,可以通過 yield 關鍵字,將函數掛起,為了改變執行流提供了可能,同時為異步編程提供了方案
語法:function* add() { yield x}
function* add() { console.log('one') let x = yield '2'; console.log('one:' + x) let y = yield '3'; console.log('two:' + y) return x + y; } const fn = add(); // one console.log(fn.next()); // {value: "2", done: false} console.log(fn.next(30)); // {value: "3", done: false} console.log(fn.next(20)); // {value: 50, done: true}
使用場景,為不具備 Interator 接口的對象提供了遍歷操作。
Promise 承諾
相當于一個容器,保存著未來才會結束的事件(異步操作)的一個結果
各種異步操作都可以用同樣的方法進行處理 axios
特點:
1.對象的狀態不受外部影響 處理異步操作,三個狀態 Pending(進行) Resolved(成功) Rejected(失敗)
2.一旦狀態改變,就不會在變,任何時候都可以得到這個結果。
function timeOut(ms) { return new Promise((resolved,Rejected)=>{ setTimeout(() => { resolved('hello promise success!!!') },ms); }) } timeOut(2000).then((val)=>{ console.log(val) // hello promise success!!! })
Promise對象的其它用法
resolve() reject() all() race() done() finally()
resolve() 將任意類型的對象轉為 promise 對象
reject() 與 resolve() 效果一樣
let p = new Promise(resolve=>resolve('foo')); p.then((data)=> console.log(data) // foo ) console.log(p) // Promise {<resolved>: "foo"}
all() 所有異步 Promise 方法執行成功,才執行后續內容
應用:一些游戲類的素材比較多,等待圖片、flash、靜態文件 都加載完成,才進行頁面的初始化
let p1 = new Promise((resolve,reject)=>{}); let p2 = new Promise((resolve,reject)=>{}); let p3 = new Promise((resolve,reject)=>{}); let p = Promise.all([p1,p2,p3]) p4.then(()=>{ // 三個都成功,則成功 }).catch(err=>{ // 如果一個失敗,則失敗 })
race() 用于設置超時時間,并在超時后執行相應的操作
請求圖片資源
function requestImg(imgSrc) { return new Promise((resolve,reject)=>{ const img = new Image() img.onload = function() { resolve(img) } img.src = imgSrc }); } function timeout(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ reject('圖片請求超時') },1000) }) } Promise.race([requestImg('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1594089011992&di=9847cc1d804fbccdf77e67d9bcdc61aa&imgtype=0&src=http%3A%2F%2Fi4.17173.itc.cn%2F2010%2Fnews%2F2010%2F03%2F01%2Ft0301syu01s.jpg'),timeout()]).then(res=>{ console.log(res) }).catch(err=>{ console.log(err); })
done() finally() 無論 Promise 成功與否,都執行其中的內容,比較少用
async的用法
作用:使得異步操作更加方便
基本操作:async 它會返回一個 Promise 對象,then catch
async 是 Generator 的一個語法糖
// 成功的操作 async function fun() { let s = await 'hello world' let data = await s.split('') return data; } fun().then(v=>{console.log(v)}).catch(e=>console.log(e)) // 失敗的操作 async function fun2() { try{ throw new Error('出錯了') }catch(errer){ } return await Promise.resolve('hello') } fun2().then(v=>{console.log(v)}).catch(e=>console.log(e))
class類的用法
class Person { // constructor 實例化的時候會立即被調用 constructor(name,age){ this.name = name this.age = age } // 添加方法 方法一 // getName(){ // return this.name // } // getAge(){ // return this.age // } } // 添加方法 方法二 // 通過 Object.assign() 一次性向類中添加多個方法(用的不多) Object.assign(Person.prototype,{ getName(){ return this.name }, getAge(){ return this.name } }) let p = new Person('ysg',16) // console.log(p) // Person {name: "ysg", age: 16} console.log(p.getName()) // ysg
類的繼承
class Animal{ constructor(name,age){ this.name = name this.age = age } getName(){ return this.name } getAge(){ return this.age } } class Dog extends Animal{ constructor(name,age,color){ super(name,age); this.color = color; } // 新建類 getColor(){ return this.color } // 重寫類 getName(){ return this.name + this.age + this.color } } let d = new Dog('小左',3, 'red') console.log(d.getName()) console.log(d.getColor())
ES6的模塊化實現
es6主要有兩個命令構成:export 和 import
exprot:用于規定模塊的對外接口
import:用于輸入其它模塊提供的功能
一個模塊就是一個獨立的文件
模塊文件:index.js
// 方法一 export name = 'ysg' export function fun() { // body... return 'my name is ' + name } // 方法二 age = '16' function fun2(){ return '年齡: ' + age } export{ age,fun2 } // 方法三,使用別名 class Person(){ constructor(){ } getAge(){ console.log(age) } getName(){ console.log(name) } } export default Person
調用文件:model.html
import {name} from './index.js' console.log(name) // 使用別名調用 import Person from './index.js' const p = new Person(); console.log(Person(p.getName))

浙公網安備 33010602011771號