ES6學習筆記(一)

最近學習了ES6,被它更簡潔的代碼編寫方式、面向?qū)ο笠约澳K化開發(fā)所吸引。ES6有一定的學習成本而且知識點比較瑣碎,我把自己經(jīng)常用到的知識點進行了整理。

安裝與配置

es6很強大,遺憾的是所有瀏覽器都沒有完美支持它。因此我們需要通過babel將es6轉(zhuǎn)換成es5讓我們的代碼在瀏覽器端運行。

我本人用的是webpack+babel,你也可以使用gulp或者直接將babel的browser.js引入,將type設為"text/babel"。

首先安裝webpack

npm install webpack --save-dev 

webpack需要安裝相應的loader加載器—babel-loader,別忘了安裝轉(zhuǎn)換規(guī)則—babel-preset-es2015

npm install babel-loader --save-dev
npm install babel-preset-es2015 --save-dev

接下來簡單地配置一下webpack.config.js文件

module.exports = {
  entry: "./main.js",
  output: {
    path: __dirname,
    filename: "after.js"
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015']
        }
      }
    ]
  },
}

上面的main.js就是我們即將要寫的es6代碼,通過在命令行輸入webpack將其轉(zhuǎn)化成es5并保存在after.js中,因此我們只需要引入after.js即可。如果你希望webpack可以實時監(jiān)聽并編譯,可以安裝webpack-dev-server,這里不多說明。

小貼士:如果你在使用es6中的Generator、async的時候遇到了錯誤信息regeneratorRuntime is not defined,請單獨安裝babel-polyfill:在webpack.config.js的頭部var babelpolyfill = require("babel-polyfill");,將入口文件改寫成entry:["babel-polyfill","./main.js"],,然后在你的js中import "babel-polyfill"

準備工作已經(jīng)完成,接下來我們可以測試一下,我準備了一個用es6編寫的main.js文件

class MyClass{
    constructor(x,y){
        this.x=x;
        this.y=y;
    }
    print(){
        return `(${this.x},${this.y})`;
    }
}
var myclass=new MyClass(2,3);
console.log(myclass.print());

運行webpack后看看生成的after.js里面都有啥

//部分代碼
var MyClass = function () {
        function MyClass(x, y) {
            _classCallCheck(this, MyClass);
            this.x = x;
            this.y = y;
        }
        _createClass(MyClass, [{
            key: "print",
            value: function print() {
                return "(" + this.x + "," + this.y + ")";
            }
        }]);
        return MyClass;
    }();
    var myclass = new MyClass(2, 3);
    console.log(myclass.print());

可以看到webpack已經(jīng)將es6轉(zhuǎn)化為es5,現(xiàn)在可以盡情使用es6了。

let和const

let

let是新的變量聲明方式,使用方法類似于var,但是let聲明的變量只在它所在的代碼塊內(nèi)有效

{
    var name="SunnyChuan";
    let age=22;
}
console.log(name); //"SunnyChuan"
console.log(age);  //age is not defined

let變量只在自己的塊級作用域內(nèi)有效,也就意味著使用let可以代替閉包解決常見的for循環(huán)引用同一個變量的問題

for(let i=0;i<5;i++)console.log(i);  //0 1 2 3 4

let不存在變量聲明提升,必須先聲明后使用

console.log(name); //ReferenceError
let name="SunnyChuan";

let不允許在同一個作用域內(nèi)重復聲明同一個變量(無論新變量是let/const/var)

let name="SunnyChuan";
var name="DannyQin"; //報錯

const

const是es6增加的另一個變量聲明方式,它用來聲明常量,并且聲明后變量的值不能再更改。因此一旦聲明必須初始化,不能稍后再賦值

const a=100;
a=10; //TypeError
const b  //SyntaxError;
b=100;

const和let一樣存在自己的作用域,個人認為除了變量的值是否可以改變以及是否必須聲明立即初始化之外,let和const沒有其他區(qū)別。需要注意的是,對于對象,數(shù)組等復合型的變量,const保證的是地址不變而不是值不變

const arr=[1,2,3];
arr.push(4); //地址不變,改變值是可以的
arr=[5]; //修改了地址,報錯

變量的解構(gòu)賦值

es6支持解構(gòu)賦值的形式將變量的賦值簡單化,數(shù)組/對象/字符串/數(shù)值/布爾/函數(shù)均可解構(gòu)賦值。最為常用的是數(shù)組和對象。

數(shù)組的解構(gòu)賦值

只要等號兩邊的模式相同即可解構(gòu)成功

var [a,b,c]=[1,2,3] //a=1,b=2,c=3
var [a,,b] //a=1,b=3
var [a,..b] //a=1,b=[2,3]

當左邊的數(shù)量大于右邊時,右邊會默認用undefined進行補充,導致解構(gòu)不成功

let [a,b,c]=[1,2] //a=1,b=2,c=undefined

允許指定默認值,默認值只有當左邊的變量所對應的右邊的值嚴格等于undefined才生效

var [a,b,c=3]=[1,2]; //a=1,b=2,c=3
var [a,b,c=3]=[1,2,null]; //a=1,b=2,c=null

對象的解構(gòu)賦值

與數(shù)組不同的是,對象解構(gòu)賦值依靠的是key值,因此只要左邊和右邊key值同名即可(變量名等于屬性名),無所謂順序,而數(shù)組是按照順序賦值的

var {name,age}={name:"SunnyChuan",age:22}; //name="SunnyChuan" age=22 
//相當于
var {name:name,age:age}={name:"SunnyChuan",age:22};

按照上面的匹配方式,變量名必須等于屬性名,如果不相等則匹配失敗。如果變量名不等于屬性名,只能使用屬性名:變量名的形式,不能省去變量名。這時候,屬性只不過是一個模式,真正被賦值的是變量

var {name:myName,age:myAge}={name:"SunnyChuan",age:22};
//name is not defined, age is not defined, myName="SunnyChuan", myAge=22

對象解構(gòu)賦值也提供了默認值,與數(shù)組相同,只有屬性值嚴格等于undefined時才生效

var {name,age=22}={name:"SunnyChuan"} //name="SunnyChuan" age=22
var {name,age=22}={name:"SunnyChuan",age:null} //name="SunnyChuan" age=null

解構(gòu)賦值最常用的地方就是交換變量。不需要額外的臨時變量temp,一句代碼就搞定

[x,y]=[y,x]

字符串/數(shù)值/數(shù)組的擴展

字符串的擴展

includes(str),返回布爾值,是否在當前字符串中找到了str

"SunnyChuan".includes("Chuan"); //true

startsWith(str),返回布爾值,當前字符串是否以str開頭

"SunnyChuan".startsWidth("Sunny"); //true

endsWith(str),返回布爾值,當前字符串是否以str結(jié)尾

"SunnyChuan".endsWith("Chuan"); //true

repeat(n),將當前字符串重復n次(可以理解為在原有的基礎上重復n-1次)并返回新字符串,如果n是小數(shù)則向下取整。當n小于等于0時,返回空字符串

"x".repeat(3); // "xxx"

模板字符串

var name="SunnyChuan";
var str=`hello ${name},this is ES6 `;
//等同于"hello"+name+",this is ES6";

數(shù)值的擴展

Number.isFinite(n),布爾值,檢查n是否有窮,與es5的isFinite()不同的是,它不會進行類型轉(zhuǎn)換,因此只對真正的數(shù)值有效

Number.isFinite(10); //true
Number.isFinite(NaN); //false
Number.isFinite(Infinity); //false
Number.isFinite("10"); //false

Number.isNaN(n),布爾值,檢查n是否是NaN,與es5的isNaN()不同的是,它不會進行類型轉(zhuǎn)換,因此只對真正的NaN有效

Number.isNaN(NaN); //true
Number.isNaN("str"); //false

Number.isInteger(n),布爾值,檢查n是否是整數(shù),需要注意1.0和1是同一個值

Number.isInteger(1); //true
Number.isInteger(1.0); //true
Number.isInteger(1.2); //false

Math.trunc(n),去除小數(shù)部分并返回(正數(shù)向下取整,負數(shù)向上取整)

Math.trunc(1.2); //1
Math.trunc(-1.2); //-2

Math.sign(n),布爾值,n是正數(shù)返回+1,是負數(shù)返回-1,0返回0,-0返回-0,其他值返回NaN

Math.sign(100); //+1
Math.sign(-100); //-1
Math.sign(0); //0
Math.sign(-0); //-0
Math.sign("str"); //NaN

數(shù)組的擴展

Array.from(list),將list轉(zhuǎn)化成真正的數(shù)組,常用于將nodeList/arguments等偽數(shù)組
轉(zhuǎn)化成數(shù)組

var obj={a:1,b:2,c:3};
Array.from(obj); //[1,2,3]
var div=document.getElementsByTagName("div");
Array.from(div); //[[object HTMLDivElement],[object HTMLDivElement],[object HTMLDivElement]]

includes(n),布爾值,檢查當前數(shù)組是否包含n,可以接收兩個參數(shù),第二個參數(shù)代表搜索的起始位置(負數(shù)代表從后往前)

[1,2,3,4].include(2); //true
[1,2,3,4].include(2,2); //false
[1,2,3,4].include(2,-3); //true

數(shù)組新增三種遍歷方式:entries()(遍歷key和value)/keys()(遍歷key)/values()(遍歷value)

for(let v of ["a","b","c","d"].values()){
    console.log(v);
} //"a" "b" "c" "d"

for(let k of ["a","b","c","d"].keys()){
    console.log(k);
} //0 1 2 3

for(let [k,v] of ["a","b","c","d"].entries()){
    console.log(k,v);
} //0 "a" 1 "b" 2 "c" 3 "d"

函數(shù)和對象的擴展

函數(shù)的擴展

es6支持函數(shù)的參數(shù)設置默認值,但是這些參數(shù)必須位于函數(shù)的尾部,并且參數(shù)的變量是默認聲明的,因此不能用let/const再次聲明

function func(x,y=5){
    console.log(y); //5
    let y=3; //error
}

擴展運算符,用于將數(shù)組(偽數(shù)組)展開成參數(shù)序列

console.log(...[1,2,3]); //1 2 3
[...document.getElementsByTagName("div")]; //[[object HTMLDivElement],[object HTMLDivElement],[object HTMLDivElement]]

擴展運算符有很多應用場景,這里列舉三個

  1. 數(shù)組合并
[1,2,3].concat([4,5,6]); //es5
[1,2,3,...[4,5,6]]; //es6

2.與解構(gòu)結(jié)合(用于生成數(shù)組)

let [a,b,...c]=[1,2,3,4,5]; //a=1,b=2,c=[3,4,5] 擴展運算符必須放在最后

3.Math.max的參數(shù)不支持數(shù)組,在es5中需要用到apply。用擴展運算符可以解決該問題

Math.max.apply(Math,[1,2,3]); //es5
Math.max(...[1,2,3]); //es6 相當于Math.max(1,2,3)

箭頭函數(shù),如果不需要參數(shù)則用圓括號代替參數(shù)部分,如果函數(shù)體有多行代碼則用大括號括起來

var func=x=>x*2; //var func=function(x){return x*2;}
var func=()=>true; //var func=function(){return true;}
var func=(x,y)=>{var z=x+y;console.log(z);} //var func=function(x,y){var z=x+y;console.log(z);}
var func=()=>({a:1,b:2}); //返回對象需要用圓括號包起來,圓括號代表函數(shù)體,花括號代表這是一個對象

函數(shù)綁定,使用a::b的形式取代傳統(tǒng)的bind/call/apply

a::b; //b.bind(a);
a::b(...arguments); //b.apply(a,arguments);

對象的擴展

es6允許在對象中只寫key,這樣默認了value等于key所代表的變量值

var [name,age]=["SunnyChuan",22];
var obj={name,age}; //obj={name:"SunnyChuan",age:22} 
//相當于obj={name:name,age:age};

對象的方法也可以簡寫

var obj={
    func(){
        //函數(shù)體
    }
}
//相當于
var obj={
    func:function(){
        //函數(shù)體
    }
}

Object.assign(obj,obj1,obj2,...),將obj1/obj2/...與obj進行拼接(修改obj本身)

var [obj,obj1,obj2]=[{a:1},{b:2},{c:3}];
Object.assign(obj,obj1,obj2);
console.log(obj); //{a:1,b:2,c:3}

Object.is(obj1,obj2),布爾值,判斷兩個值是否嚴格相等,與===不同的是,+0不等于-0,NaN等于NaN

Object.is(100,100); //true
Object.is(NaN,NaN); //true
Object.is(+0,-0); //false
Object.is({a:1},{a:1}); //false
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容