實例感覺-es6的經常使用語法和優越性

1.前言

前幾天,用es6的語法重寫了個人一個代碼庫,說是重寫,其實改動的並很少,工做量不大。在重寫完了的時候,就我的總結了一下es6經常使用的一些經常使用的語法和比es5優越的方面。下面提到的語法可能也就是es6新特性的10%-20%,可是開發上佔了80%左右的。下面的文章,按照es6經常使用新特性進行分類,文章說起的實例,有些是我代碼庫的小實例,有些是本身隨便編的,你們知道就好!但願能夠幫到你們,若是你們以爲文章有什麼地方寫錯了,或者哪裏寫得不對,歡迎指出!javascript

1.可能還有些人不知道我說的的代碼庫是什麼,簡單的打下廣告:這個代碼庫是我封裝了一些javascript經常使用的小實例,好比: 數組去重字符替換經常使用Dom操做圖片懶加載等的57個小實例( 查看說明)。代碼也上傳到github上面了!es5版本-- ec-do-1.1.4。es6版本-- ec-do-2.0.0。歡迎你們star。也但願你們能夠多給意見,或者和你們一塊兒完善這個項目!
2.至於這個代碼庫的使用方法,去github看一下就知道了,這裏很少說!
3.es6發佈兩年多了,如今都發布了es7,es8了,可是es7和es8更新的東西很少,能夠參考下面兩個連接! 聊聊ES7與ES8特性10分鐘學會ES7+ES8

2.let const

letvar區別在於,let有塊級做用域的的區分概念。css

以下實例html

//至關於聲明瞭一個全局的i變量。
for(var i=0;i<10;i++){
    console.log(i)
}
console.log('最後的值:'+i)

clipboard.png

//j只在這個for循環有效,若是在循環外調用就會報錯
for(let j=0;j<10;j++){
    console.log(j)
}
console.log('最後的值:'+j)

clipboard.png

還有一個常見的使用場景是:好比一個頁面有5個li,索引固然就是0,1,2,3,4。點擊某一個li,顯示該li的索引。java

var oLi= document.querySelectorAll('li')
for (var i = 0,len = oLi.length; i < len; i++){
    oLi[i].onclick = function(){
        console.log(i)
    }
}

這樣寫,其實不管點擊那個li,都是顯示5。由於當點擊li的時候,上面的代碼已經執行完了,那麼每一個i,就是等於5,就顯示5。git

用let就不會出現這個問題es6

var oLi= document.querySelectorAll('li')
for (let i = 0,len = oLi.length; i < len; i++){
    oLi[i].onclick = function(){
        console.log(i)
    }
}

用了let,若是點擊第一個li,就顯示0,點擊第三個li,就顯示2。這個你們能夠自行嘗試下!github

說完了let,說下constconst初始化賦值以後就不能再改變賦值。以下圖。segmentfault

clipboard.png

這個我目前是用在引用插件,庫,或者模塊化開發上!數組

clipboard.png

好比上面這個,在開發上能夠因爲重名而帶來的異常!微信

3.arrow function

箭頭函數,使用的頻率很是的高!寫法也是很是的簡潔和清晰!

以下的數組求和實例

//sumArr都是ecDo在這個對象裏面的屬性,可是你們看到es6和es5的定義方式不同,是es6簡寫方式。
//es6寫法-隱式返回
sumArr(arr) {
    return arr.reduce((pre, cur) =>pre + cur)
}
//es6寫法-顯式返回
sumArr(arr) {
    return arr.reduce((pre, cur) =>{return pre + cur})
}
//es5寫法
sumArr: function (arr) {
    return arr.reduce(function (pre, cur) {
        return pre + cur
    })
},

還有一個經常使用的場景是,當使用了setTimeout或者setInterval的時候。以下‘圖片懶加載的實例’(代碼暫時能夠不用看得太細,看圖片就好,貼代碼是爲了讓你們看到整個函數,不讓你們蒙)。過程不詳細說,看es6es5的使用區別!

//es6寫法,(若是看到函數參數有不懂的不用急,後面會提到!)
loadImg(className = 'ec-load-img', num = 0, errorUrl = null) {
    let oImgLoad = document.getElementsByClassName(className);
    for (let i = 0, len = oImgLoad.length; i < len; i++) {
        //若是圖片已經滾動到指定的高度
        if (document.documentElement.clientHeight + document.documentElement.scrollTop > oImgLoad[i].offsetTop - num && !oImgLoad[i].isLoad) {
            //記錄圖片是否已經加載
            oImgLoad[i].isLoad = true;
            //設置過渡,當圖片下來的時候有一個圖片透明度變化
            oImgLoad[i].style.cssText = "transition: ''; opacity: 0;";
            if (oImgLoad[i].dataset) {
                this.aftLoadImg(oImgLoad[i], oImgLoad[i].dataset.src, errorUrl, function (o) {
                    //添加定時器,確保圖片已經加載完了,再把圖片指定的的class,清掉,避免重複編輯
                    setTimeout(()=>{
                        if (o.isLoad) {
                            this.removeClass(o, className);
                            o.style.cssText = "";
                        }
                    }, 1000)
                });
            } else {
                this.aftLoadImg(oImgLoad[i], oImgLoad[i].getAttribute("data-src"), errorUrl, function (o) {
                    //添加定時器,確保圖片已經加載完了,再把圖片指定的的class,清掉,避免重複編輯
                    setTimeout(()=>{
                        if (o.isLoad) {
                            this.removeClass(o, className);
                            o.style.cssText = "";
                        }
                    }, 1000)
                });
            }
            (function (i) {
                setTimeout(()=>{
                    oImgLoad[i].style.cssText = "transition:all 1s; opacity: 1;";
                }, 16)
            })(i);
        }
    }
}

//es5寫法
loadImg: function (className, num, errorUrl) {
    var _className = className || 'ec-load-img', _num = num || 0, _this = this,_errorUrl=errorUrl||null;
    var oImgLoad = document.getElementsByClassName(_className);
    for (var i = 0, len = oImgLoad.length; i < len; i++) {
        //若是圖片已經滾動到指定的高度
        if (document.documentElement.clientHeight + document.documentElement.scrollTop > oImgLoad[i].offsetTop - _num && !oImgLoad[i].isLoad) {
            //記錄圖片是否已經加載
            oImgLoad[i].isLoad = true;
            //設置過渡,當圖片下來的時候有一個圖片透明度變化
            oImgLoad[i].style.cssText = "transition: ''; opacity: 0;"
            if (oImgLoad[i].dataset) {
                this.aftLoadImg(oImgLoad[i], oImgLoad[i].dataset.src, _errorUrl, function (o) {
                    //添加定時器,確保圖片已經加載完了,再把圖片指定的的class,清掉,避免重複編輯
                    setTimeout(function () {
                        if (o.isLoad) {
                            _this.removeClass(o, _className);
                            o.style.cssText = "";
                        }
                    }, 1000)
                });
            } else {
                this.aftLoadImg(oImgLoad[i], oImgLoad[i].getAttribute("data-src"), _errorUrl, function (o) {
                    //添加定時器,確保圖片已經加載完了,再把圖片指定的的class,清掉,避免重複編輯
                    setTimeout(function () {
                        if (o.isLoad) {
                            _this.removeClass(o, _className);
                            o.style.cssText = "";
                        }
                    }, 1000)
                });
            }
            (function (i) {
                setTimeout(function () {
                    oImgLoad[i].style.cssText = "transition:all 1s; opacity: 1;";
                }, 16)
            })(i);
        }
    }
}

代碼貼了這麼多,其實區別就三小塊

clipboard.png

clipboard.png

簡單解釋一下:當使用箭頭函數了,函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。(好比上面提到的實例,setTimeout裏面的this,本來指向window,可是使用的箭頭函數,就指向ecDo這個對象)
緣由是箭頭函數沒有this,它的this是繼承外面的,所以內部的this就是外層代碼塊的this。

4.template string

模板字符串,這個日常使用的頻率也很是高,並且也很實用!

以下實例:到某一個時間的倒計時

//es6寫法
getEndTime(endTime) {
    let startDate = new Date(); //開始時間,當前時間
    let endDate = new Date(endTime); //結束時間,需傳入時間參數
    let t = endDate.getTime() - startDate.getTime(); //時間差的毫秒數
    let d = 0,
        h = 0,
        m = 0,
        s = 0;
    if (t >= 0) {
        d = Math.floor(t / 1000 / 3600 / 24);
        h = Math.floor(t / 1000 / 60 / 60 % 24);
        m = Math.floor(t / 1000 / 60 % 60);
        s = Math.floor(t / 1000 % 60);
    }
    return `剩餘時間${d}天${h}小時${m}分鐘${s}秒"`;
}
//es5寫法
getEndTime: function (endTime) {
    var startDate = new Date(); //開始時間,當前時間
    var endDate = new Date(endTime); //結束時間,需傳入時間參數
    var t = endDate.getTime() - startDate.getTime(); //時間差的毫秒數
    var d = 0,
        h = 0,
        m = 0,
        s = 0;
    if (t >= 0) {
        d = Math.floor(t / 1000 / 3600 / 24);
        h = Math.floor(t / 1000 / 60 / 60 % 24);
        m = Math.floor(t / 1000 / 60 % 60);
        s = Math.floor(t / 1000 % 60);
    }
    return "剩餘時間" + d + "天 " + h + "小時 " + m + " 分鐘" + s + " 秒";
}

可能你們還不以爲模板字符串怎麼好用,那麼接下來再說一個實例,好比往一個div添加一大段的html內容時。es5的作法是

var obj={
    author:'守候',
    time:'2017.11.8',
    thing:'看下模板字符串的方便性。'
}
$("#test").append(
  "<p>這是<i>" + obj.author+ "</i> " +
      "寫的一個實例。這個實例是爲了" +
      "<i>" + obj.thing +
      "</i>"+"<span>寫做日期是:"+obj.time+
      "</span></p>"
);

而使用es6,就簡單多了

let obj={
    author:'守候',
    time:'2017.11.8',
    thing:'看下模板字符串的方便性。'
}
$("#test").append(
  `<p>
      這是<i>${obj.author}</i>
      寫的一個實例。這個實例是爲了
      <i> ${obj.thing}</i>
      <span>寫做日期是:${obj.time}</span>
   </p>`
);

5.destructuring

解構賦值這個用得算是比較多的,簡單明瞭,就是一個簡寫方式!

//es5
var name='守候'
var sex='男'
var info= {name:name, sex: sex}
console.log(info)  //Object {name: "守候", sex: "男"}

//es6
let name='守候'
let sex='男'
let info= {name, sex}
console.log(info)  //Object {name: "守候", sex: "男"} 

//es6也能夠反過來 
let info={name: "守候", sex: "男"};
let {name,sex}=info;
console.log(name,sex)// "守候" "男"

6.default, rest

default,就是函數參數的默認值,很好理解
比格式化處理字符串這個函數

//es6寫法
formatText(str, size = 3, delimiter = ',') {
    let regText = '\\B(?=(\\w{' + size + '})+(?!\\w))';
    let reg = new RegExp(regText, 'g');
    return str.replace(reg, delimiter);
}
//es5寫法
formatText: function (str, size, delimiter) {
    var _size = size || 3, _delimiter = delimiter || ',';
    var regText = '\\B(?=(\\w{' + _size + '})+(?!\\w))';
    var reg = new RegExp(regText, 'g');
    return str.replace(reg, _delimiter);
}

rest這個我不知道怎麼說,看下面的實例吧

function param(first,...all){
    console.log(first)
    console.log(all)
    console.log(Object.prototype.toString.call(all))
}
animals('第一個', '第二個', '第三個')

clipboard.png

這樣寫,all就是一個數組,不用像arguments那樣轉成數組!

7.export & import

這兩個對應的就是對應的特性就是,模塊化開發,這個能夠說是最實用的一個新特性了!功能也強大,可是寫起來就很簡單!就幾個代碼!看圖吧!

封裝模塊的時候,用export把模塊暴露出去

clipboard.png

須要使用的時候,用import引進行來,完事

clipboard.png

順便提一下,另外一個按需引入的方法

clipboard.png

clipboard.png

8.API推薦

8-1.字符串

repeat

repeat方法返回一個新字符串,表示將原字符串重複n次。

'守候'.repeat(3)
//"守候守候守候"

includes & startsWith & endsWith

includes:是否找到了參數字符串,返回布爾值。
startsWith:參數字符串是否在原字符串的頭部,返回布爾值。
endsWith:參數字符串是否在原字符串的尾部,返回布爾值。

三個方法都接受兩個參數,第一個參數是參數字符串,第二個是開始檢索的位置

var str='我就是守候'
str.startsWith('我就是')//true
str.startsWith('我')//true
str.startsWith('我',2)//false
str.startsWith('守候')//false
str.endsWith('守候')//true
str.includes('守候')//true
str.includes('我',3)//false

padStart & padEnd

padStart:若是字符串不夠指定長度,在頭部補全指定字符
padEnd:若是字符串不夠指定長度,在尾部補全指定字符

兩個方法都接收兩個參數,第一個是指定字符串的最小長度,第二個用來補全的字符串。若是指定字符串的長度,等於或大於指定的最小長度(第一個參數)。就直接返回原字符串,若是忽略第二個參數,就使用空格補全原字符串!

var str='守候'
str.padEnd(10,'123')//"守候12312312"
str.padStart(10,'123')//"12312312守候"
str.padEnd(10)//"守候        "
str.padStart(10)//"        守候"
str.padStart(1)//"守候"
str.padEnd(1)//"守候"

8-2.數值

isNaN

檢查一個值是否爲NaN

Number.isNaN(NaN)//true
Number.isNaN(15)//false

isInteger

判斷一個值是否爲整數,須要注意的是,好比1和1.0都是整數。

Number.isInteger(1)//true
Number.isInteger(1.0)//true
Number.isInteger(1.1)//false

sign

判斷一個數究竟是正數、負數、仍是零

Math.sign(-10)// -1
Math.sign(10)// +1
Math.sign(0)// +0
Math.sign(-0)// -0
Math.sign(NaN)// NaN
Math.sign('10')// +1
Math.sign('守候')// NaN
Math.sign('')// 0
Math.sign(true)// +1
Math.sign(false)// 0
Math.sign(null)// 0

trunc

去除一個數的小數部分,返回整數部分

Math.trunc(1.1)//1
Math.trunc(-1.1)//-1
Math.trunc(-0.1)//-0
Math.trunc('123.456')//123
Math.trunc('守候')//NaN

8-3.對象

assign

用於對象的合併,複製到目標對象。

var _name={name:'守候'},sex={sex:'男'},city={'city':'廣州'}
Object.assign(_name,sex,city)//{name: "守候", sex: "男", city: "廣州"}

var info1={name:'守',sex:'男'},info2={name:'候',city:'廣州'}
Object.assign(info1,info2)//{name: "候", sex: "男", city: "廣州"}

克隆原來這樣對象,這樣克隆對象,修改了info1或者info3,不會影響info3或者info1,可是Object.assign並非深拷貝。詳細的能夠參考我以前的文章--對象深淺拷貝

var info1={name:'守',sex:'男'}
var info3=Object.assign(info1,{})//{name:'守',sex:'男'}

keys

根據對象自身可遍歷的鍵名進行遍歷,返回一個數組

var info={name: "守候", sex: "男", city: "廣州"}
Object.keys(info)//["name", "sex", "city"]

values

根據對象自身可遍歷的鍵值進行遍歷,返回一個數組

Object.values(info)//["守候", "男", "廣州"]

entries

根據對象自身可遍歷的鍵值對進行遍歷,返回一個數組

Object.entries(info)//[["name", "守候"],["sex", "男"],["city", "廣州"]]

8-4.數組

from

from用於將兩類對象轉爲真正的數組:相似數組的對象和可遍歷的對象

Array.from('守候')//["守", "候"]
//常見的使用方式還有-將Dom集合和arguments轉成真正的數組
let oLi = document.querySelectorAll('li');
Array.from(oLi ).forEach(function (item) {
  console.log(item);
});

// arguments對象
function fn() {
  let args = Array.from(arguments);
}
//順便說下Set
let newSet = new Set(['a', 'b','a','c'])
Array.from(newSet) // ['a', 'b','c'] 
//ES6 新增的數據結構--Set。它相似於數組,可是成員的值都是惟一的,不重複的。
//相信你們很容易想到怎麼用了,好比數組去重,用Set實現就簡單多了。   
removeRepeatArray(arr) {
    //return [Array.from(arr)]
    return [...new Set(arr)]
}

find

find方法,用於找出第一個符合條件的數組成員。若是沒找到符合條件的成員就返回underfind

//第一個大於2的成員
[1, 2, 3, 4].find((n) => n > 2)//3

findIndex

findIndex方法,用於找出第一個符合條件的數組成員的索引。

//第一個大於2的成員的索引
[1, 2, 3, 4].findIndex((n) => n > 2)//2

includes

includes方法,用於某個數組是否包含給定的值,返回一個布爾值。若是沒找到符合條件的成員就返回underfind

[1, 2, 3].includes(2)//true
[1, 2, 3].includes(5)//false
[1, 2, NaN].includes(NaN)//true

9.小結

好了,關於es6的經常使用語法和比es5優越的方面區別,就說到這裏了,這些是我在日常開發用的比較多。若是想詳細學習es6,移步到阮一峯的-ECMAScript 6 入門。這些語法相信在開發了已經佔了很大的一個比重了!固然若是你們還有什麼好的語法,API推薦,或者以爲我哪裏寫錯了,寫得很差,歡迎給出寶貴的意見,指點下迷津。也期待你們相互學習,一塊兒進步!

-------------------------華麗的分割線--------------------
想了解更多,關注關注個人微信公衆號:守候書閣

clipboard.png

相關文章
相關標籤/搜索