es6經常使用的語法(一)

一、 let和const命令

es5只有全局做用域和函數做用域,沒有塊級做用域。
下面看一個例子:es6

for(var i = 0;i < 10;i++){
    //...
}
alert(i)  //10;

對於有塊級做用域的語言來講,for語句初始化變量的表達式所定義的的變量,只會存在於循環的環境中。然而對於JavaScript來講,由for語句建立的變量i,即便在for語句循環結束後,也依舊存在於外部的執行環境中,這就是所說的變量提高。
es6新增了let和const命令,用來聲明變量和常量,let命令只在所在的代碼塊內有效。
例子:面試

{
        let a = 10;
        var b = 1;
    }
    console.log(a) //ReferenceError:a is not defined.
    console.log(b) //1

在上面的代碼塊之中,分別用let和var聲明瞭兩個變量。在代碼塊以外調用這兩個變量,
發現let聲明的變量錯誤,由於let的做用域是在它所在的當前代碼塊,不會被提高到當前函數的最頂部。json

常見的面試題:數組

var a = [];
for (var i = 0;i < 10;i++){
    a[i] = function(){
        console.log(i);
    }
}
a[6](); //10

上面的代碼中,變量i是var聲明的,在全局範圍內都是有效的,因此全局只有一個變量i,每一次循環,變量i的值都會發生變化,被賦給數組a的函數內部的console.log(i),裏面的i指向的就是全局的i。也就是說,全部數組a的成員裏面的i,指向的都是同一個i,致使運行時的輸出的時最後一輪的i的值,也就是10.
如何使a[6]()輸出的是6哪?數據結構

//es5閉包解決循環綁定問題
var a = [];
for (var i = 0;i < 10;i++){
    a[i] = (function(value){
        return function(){
            console.log(value)
        }
    })(i)
}
a[6](); //6

//es6
//使用let,聲明的變量僅在塊級做用域內有效
var a = [];
for (let i = 0;i < 10;i++){
    a[i] =  function(){
            console.log(i)
        }  
}
a[6](); //6
    上面代碼中,變量i是let聲明的,當前的i只在本輪循環有效,因此每一次循環的i其實都是一個新的變量,因此最後輸出的是6。
由於JavaScript引擎內部會記住上一輪循環的值,初始化本輪的變量i時,就在上一輪循環的基礎上運算。
    另外,for循環的一個特別的地方,就是設置循環變量的部分是一個父做用域,而循環體內部是一個單獨的子做用域。
for(let i =0;i < 3;i++){
    let i = 'abc';
    console.log(i)
}
//abc
//abc
//abc
    上面代碼輸出3次abc。這說明函數內部的變量i與循環變量i不在同一個做用域內,有各自單獨的做用域。

const聲明一個只讀的常量。一旦聲明常量的值就不能改變.
const一旦聲明變量,就必須當即初始化,不能留到之後賦值。閉包

const PI = 3.1415;
PI; //3.1415
PI = 3; // TypeError: Assignment to constant variable
const foo;//SyntaxError: Missing initializer in const declaration

二、變量的解構賦值

什麼是解構?app

解構不是構造一個新的對象或者數組,而是逐個拆分現有的對象或數組、字符串,來提取須要的數據。
es6中被解構的數據項位於賦值運算符=的右側,能夠是數組、對象、字符串。

2.一、數組的解構

數組解構:使用一個數組做爲一個數據項,根據數組模式(只要等號兩邊的模式相同,左邊的變量就會賦予對應的值)從這個數組裏面提取提取一個或者多個變量賦值。
基本用法:函數

//把數組中全部的數值賦給一個個單獨的變量
let [a,b,c] = [1,2,3];
a  //1
b  //2
c  //3

//第一個不提取,其他都提取
let [,b,c] = ['li','yong','good'];
b  //'yong'
c  //'good'

//中間第二個不提取,其他都提取
let [a,,c] = ['li','yong','good'];
a  //'li'
c  //'good'

//最後一個不提取,其他都提取(不徹底解構)
let [a,b] = ['li','yong','good']
a  //'li'
b  //'good'

//第一個提取,其他的放到一個數組裏,要用到rest操做符
//rest操做符:用來獲取多餘的參數,將多餘的參數放入數組中。
let [head,...tail] = [1,2,3,4];
head //1
tail //[2,3,4]

默認值:
解構賦值容許指定默認值:ui

let [foo = true] = [];
foo //true

let [x,y = 'yong'] = ['li'];
x //'li'
y //'yong'

let [x,y = 'yong'] = ['li',undefined];
x //'li'
y //'yong'

let [x = 'li'] = [null]
x //null
若是一個數組成員是null,默認值不會生效。

以上代碼中,undefined 和 null的區別:
undefined使用默認值;
null是有值,但值是空。this

2.二、對象的解構

對象的解構與數組的解構不一樣,數組的元素是按次序排列的,變量的取值由它的位置決定;對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。
基本用法:

//變量名和屬性同名
let {a,b} = {a:'li',b:'yong'}
a //'li'
b //'yong'

//變量名與屬性名不一致
let {a:xxx} = {a:'li',b:'yong'}
xxx //'li'
對象的解構賦值的內部機制,是先找到同名屬性,而後再賦給對應的變量。

默認值:

let {x,y = 5} = {x:1};
x //1
y //5

let {x = 3} = {x: undefined};
x //3

let {x = 3} = {x:null};
x //null

若是將一個已經聲明的變量用於解構賦值,必須當心
//錯誤的寫法
let x;
{x} = {x:1};// SyntaxError: Unexpected token 
上面代碼的寫法會報錯,由於JavaScript引擎會將{x}理解成一個代碼塊,從而發生語法錯誤。
//正確的寫法
let x;
({x} = {x:1});
x //1

2.3 字符串的解構

字符串能夠解構賦值。由於字符串被轉換成一個相似數組的對象。

const [a,b] = 'yes';
a //'y'
b //'e'
c //'s'

2.4 函數參數的解構

function move({x = 0,y = 0} = {}){
    return [x, y];
}
move({x: 3, y:8}); // [3, 8]
move({x: 3});      // [3, 0]
move({})           // [0, 0]
move()             // [0, 0]
上面代碼中,函數move的參數是一個對象,經過對這個對象進行解構,獲得變量x 和 y 的值。若是解構失敗, x 和 y 等於認值。
注意下面的寫法:
function move({x, y} = {x: 0, y: 0}){
    return [x, y];
}
move({x: 3,y: 8}) //[3,8]
move({x:3})       //[3, undefined]
move({})          //[undefined,undefined]
move()            //[0, 0]
上面的代碼是爲函數move的參數指定默認值,而不是爲變量x 和 y 指定默認值,因此獲得與前一種寫法不一樣的結果。

寫了那麼多,來總結一下在工做中的經常使用的例子:

  • 交換變量的值
let x = 1;
    let y = 2;
    [x, y] = [y, x];
    x //2
    y //1
    上面的代碼交換變量x 和 y 的值。
  • 從函數返回多個值
函數返回多個值,只能將它們放在數組或對象裏返回。
    有了解構賦值,取出這些值就很是方便了。
    
    //返回一個數組
    
    function example(){
        return [1,2,3];
    }
    let [a, b, c] = example();
    
    //返回一個對象
    function example(0{
        return {
            foo: 1,
            bar: 2
        }
    }
    let { foo, bar } = example();
  • 函數參數的定義
解構賦值能夠將一組參數與變量名對應起來
   //參數是一組有次序的值
    function f([x,y,z]){....}
    f([1,2,3])
    
   //參數是一組無次序的值
   function f({x, y, z}){...}
   f({z: 3, y: 2, x: 1})
  • 提取Json數據
let jsonData = {
        id : 42,
        status: 'ok',
        data : [77,909]
    };
    let { id, status, data:number } = jsonData;
    id      // 42
    status  // 'ok'
    number  // [77,909]
  • 輸入模塊的指定方法
加載模塊時,指定輸入哪些方法。
    const { SourceMapConsumer, SourceNode } = require("source-map");

三、模板字符串

es6引入模板字符串(``),進行字符串的拼接,對於字符串中嵌入變量,使用${}。

var str = '這是字符串變量';
$('#body').append(`liyong,${str},good`);
es5字符串查找:
    只有indexOf()方法,能夠用來肯定一個字符串是否包含裏一個字符串。返回子字符串的位置(若是沒有找到該子字符串,則返回-1)
    var d = 'this is a line';
    d.indexOf('is') //2
es6提供了一種查找子字符串的方法:includes()
    -includes(): 返回布爾值,表示是否找到了參數字符串。
    var d = 'this is a line';
    d.includes('is') //true

四、數組的知識

4.1數組的擴展運算符

//將一個數組轉化爲用逗號分割的參數序列
    console.log([1,...[2,3,4],5]) //[1,2,3,4,5]

4.二、複製數組

數組是複合的數據類型,直接複製的話,只是複製的指向底層數據結構的指針,而不是克隆了一個新的數組。

es5中數組的複製;
    const a1 = [1,2];
    const a2 = a1;
    a2[0] = 2;
    a1;  //[2,2]
    上面代碼,a2不是a1的克隆,而是指向同一個數據的另外一個指針。修改a2,會直接致使a1的變化。
    另一種es5的方法:
    const a1 = [1,2];
    const a2 = a1.concat();
    a2[0] = 2;
    a1; //[1,2]
    上面代碼中,a1會返回原數組的克隆,再修改a2就不會對a1產生影響。
    es6擴展運算符的複製數組的寫法:
    const a1 = [1,2];
    const a2 = [...a1];
    a2[0] = 2;
    a1;  //[1,2]

4.三、合併數組

數組合並的寫法:

//es5
    const b1 = [3,4,5]
    [1,2].concat(b1) //[1,2,3,4,5]
    //es6
    [1,2, ...b1]     //[1,2,3,4,5]

4.四、Array.from()

將一組相似數組的對象(一組Dom節點)轉爲真正的數組

let arrayLike = {
        '0':'li',
        '1':'yong',
        length:2
    }
    //es5的寫法
    let arr = [].slice.call(arrayLike); //['li','yong']
    let arr = Array.prototype.slice.call(arrayLike);//['li','yong']
    //es6的寫法
    let arr = Array.from(arrayLike); //['li','yong']

4.五、Array.of()

用於將一組值,轉換爲數組。

Array.of(3,11,8)  //[3,11,8]

4.六、數組實例的find()和findIndex()

數組實例的find方法,用於找出第一個符合條件的數組成員。它的參數是一個回調函數,全部的數組成員依次執行該回調函數,直到找出第一個返回值爲true的成員,而後返回該成員。若是沒有符合條件的成員,則返回undefined.

[1,4,-5,10].find((n) => n < 0)  //-5
    以上代碼找出數組中第一個小於0的成員

4.七、數組實例的includes()

與字符串的includes方法相似,Array.prototype.includes方法返回一個布爾值。

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

4.八、數組實例的entries(),keys(),values()

keys()是對鍵名的遍歷、values()是對鍵值的遍歷、entries()是對鍵值對的遍歷

let arr = ['li','yong'];
 for(let [index,value] of arr.entries()){
    console.log(`索引 ${index} : 鍵值 ${value}`)
}
//索引 0 : 鍵值 li
//索引 1 : 鍵值 yong

4.九、數組的遍歷方法

  • forEach:會自動省略爲空的數組元素
let arr = ['li','yong','good',''];
  arr.forEach((value,index)=>console.log(`索引${index} : 鍵值${value}`))
//索引0 : 鍵值li
// 索引1 : 鍵值yong
// 索引2 : 鍵值good
  • filter:建立一個新的數組,新數組中的元素是經過檢查指定數組中符合條件的全部的元素。
    filter()不會對空數組進行檢測
    filter()不會改變原始數組
let arr = ['li','yong','good'];
   arr.filter(x=>{if(x == 'li'){return console.log(`篩選的是:${x}`)}})

4.十、數組轉換字符串

  • join()方法
let arr = ['li','yong','good'];
    console.log(arr.join('|'))
    //li|yong|good
  • toString()方法
let arr = ['li','yong','good'];
    console.log(arr.toString())
    //li,yong,good

五、對象的擴展

5.一、對象的屬性和方法的簡寫

const name = 'li';
    const age = 00;
    const o = {name, age,method(){
        console.log(this.name)
    }}
    o.method() //'li'

5.二、Object.is()

es5 比較兩個值是否相等,相等運算符(==)和嚴格相等運算符(===)。前者的不足是,會自動轉換數據類型,後者的NaN不等於自身,以及+0等於-0。
es6 提出"Same-value-equality"(同值相等)。Object.is就是比較兩個值是否嚴格相等。

Object.is(true,1) //false
    Object.is(true,true) //true
    Object.is(+0,-0)   //false
    Object.is(NaN,NaN)  //true

5.三、Object.assign()

Object.assign方法用於對象的 合併,將源對象(source)的全部的可枚舉屬性,複製到目標對象(target)。

const target = {a: 1};
    const source1 = {b: 2};
    const source2 = {c: 3};
    Object.assign(target, source1, source2)
    target //{a:1, b:2, c:3}

5.四、Object.assign()

  • 爲對象添加屬性
    const bbbb = {name:'li'};
    Object.assign(bbbb,{age:18,height:00})
    bbbb;
    //{
    // age:18
    // height:0
    // name:"li"
    // }
  • 爲對象添加方法
    直接將兩個函數放在大括號中,再使用assign方法添加到目標對象中。
    const bbbb = {name:'li'};
    Object.assign(bbbb,{

    getName(){
           return this.name;
       },
       getAge(){
           return this.age;
       }

    })

5.五、Object.keys(),Object.values(),Object.entries(),

返回一個數組
Object.entries的用途是遍歷對象的屬性。

const obj = {name:'li',age:00 };
    for( let [key,value] of Object.entries(obj) ){
        console.log(`屬性${JSON.stringify(key)}:屬性值${value}`)
    }
    //屬性"name":屬性值li
    //屬性"age":屬性值00
相關文章
相關標籤/搜索