ES6 新增特性小結

白晉銘發表於2018-08-10

一、let與const

const宣告常量,會形成塊級作用域,一旦宣告後就無法更改。

const PI=3.14;
console.log(PI);//3.14
PI=1;
console.log(PI);//Identifier 'PI' has already been declared
複製程式碼

let與var都是用來宣告變數,let宣告變數時,會形成塊級作用域,該變數僅能在此作用域內使用,且不會提升。它們的不同之處具體體現在:

1)、變數的提升
var:宣告的變數不管在哪兒,都會被提升到函式的最上方

console.log(a);//undefined
var a=1;

//等價於
var a;
console.log(a);
a=1;
複製程式碼

let:宣告的變數不會提升

console.log(a);//a is not defined
let a=1;
複製程式碼

2)、變數的覆蓋
var:內部變數會覆蓋外層變數

var a=1;
if(true){
    var a=2;
    console.log(a);
}
f();//2
console.log(a);//2
複製程式碼

let:形成塊級作用域,不會汙染全域性變數

let a=1;
if(true){
    let a=2;
    console.log(a);//2
}
console.log(a);//1
複製程式碼

3)、迴圈變數洩露
var:迴圈變數會發生洩露,新的值會覆蓋舊值

var arr=[];
for(var i=0;i<10;i++){
    arr[i]=function(){
        console.log(i);
    }
}
arr[5]();//10  每一次迴圈i的值都會覆蓋之前的值,列印的值為執行完迴圈體後i的值
複製程式碼

let:形成塊級作用域,變數的值只能在作用域內,互不干擾

let arr=[];
for(let i=0;i<10;i++){
    arr[i]=function(){
        console.log(i);
    }
}
arr[5]();//5  每次迴圈都會形成一個作用域,其中放置了i的值,不會發生新值覆蓋舊值的情況
複製程式碼

二、箭頭函式(arrow functions)

格式:()=>{ }
箭頭函式的推出,方便了我們對函式的書寫,逐漸成為我們寫函式時最習慣的方式,下面就來看看箭頭函式的使用

let a=(x)=>{
    return x*2;
}
console.log(a(5));//10

//以上程式碼還可以簡化。
//只有一個形參時可以去掉();
//函式體內只有一行程式碼時可以去掉{};
//一行程式碼如果是return語句,return可以省略
let a=x=>x*2;
console.log(a(5));//10
複製程式碼

注意:箭頭函式沒有this,它內部的this與外部的this是指向同一個物件

三、模板字串(template string)

格式: ``

在裡面的變數寫法不用再拼接了,只需要用${}來劃定範圍就行了,大括號內部可以放入任意的 JavaScript 表示式,可以進行運算,以及引用物件屬性。 如果使用模板字串表示多行字串,所有的空格和縮排都會被保留在輸出之中。

let name="  zhang san";
let age="20"
console.log(`我的名字是${name},今年${age}歲,明年${++age}歲`);//我的名字是  zhang san,今年20歲,明年21歲
複製程式碼

includes:判斷是否包含然後直接返回布林值; repeat: 獲取字串重複n次

let a="hello";
console.log(a.includes("ll"));//true
console.log(a.repeat(3));//hellohellohello
複製程式碼

四、class、extends、super

class(類) 格式:

class  類名{
    constructor(引數){ //constructor構造方法,this指例項物件
        this.屬性=引數;
    }
    method(){ //簡寫方法,省略function

    }
}
複製程式碼

注意: 1)、class 是關鍵字,後面緊跟類名,類名首字母大寫,採取的是大駝峰命名法則。類名之後是{ }。 2)、在{ }中,不能直接寫語句,只能寫方法,方法不需要使用關鍵字 3)、方法和方法之間沒有逗號。不是鍵值對

class使用extends關鍵字來實現繼承,這相比與ES5通過原型鏈來繼承更加清晰明瞭
super指代父類的例項(即父類的this物件),子類在constructor中呼叫super方法來獲得this物件

class繼承案例如下:

class NBAPlayer{
    constructor(name,age,height){
        this.name=name;
        this.age=age;
        this.height=height;
    }
    say(){
        console.log(`我是${this.name},今年${this.age}歲,身高${this.height}cm`)
    }
}
class MVP extends NBAPlayer{
    constructor(name,age,height,year){
        super(name,age,height);
        this.year=year;
    }
    show(){
        console.log(`${this.name}獲得了${this.year}年的MVP`)
    }
}
let person1=new MVP("杜蘭特",30,211,2018);
person1.say();//我是杜蘭特,今年30歲,身高211cm
person1.show();//杜蘭特獲得了2018年的MVP
複製程式碼

分析上面案例: 使用class建立了一個NBAPlayer構造器,接著我們建立了一個MVP構造器,使用extends實現繼承NBAPlayer構造器,且通過呼叫super繼承NBAPlayer構造器中的this物件。當我們需要建立一個新的物件時,通過new MVP(構造器)完成建立,就可以使用其中的方法了。

五、解構(destructuring)

物件字面量和陣列字面量提供了一種簡單的定義一個特定的資料組的方法。 解構賦值使用了相同的語法,不同的是在表示式左邊定義了要從原變數中取出什麼變數。

解構陣列
右邊的值直接賦給左邊對應位置的變數

宣告變數並賦值的解構

let [a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
複製程式碼

為了防止從陣列中取出一個值為undefined的物件,可以為這個物件設定預設值

let [a, b=5] = [1];
console.log(a); // 1
console.log(b); // 5
複製程式碼

忽略某些值

let [a,,b] = [1,2,3];
console.log(a); // 1
console.log(b); // 3
複製程式碼

變數互換

let a=1,b=2;
[a,b]=[b,a];
console.log(a); // 2
console.log(b); // 1
複製程式碼

解構物件
陣列的解構是按次序排列的,變數取值由位置決定的,而物件的屬性是沒有順序的,變數必須與屬性同名才能取到正確的值。

宣告物件,給屬性賦值

var {p, q} = {p: 42, q: true};
console.log(p); // 42
console.log(q); // true
複製程式碼

給新變數命名並提供預設值

var {a:aa = 10, b:bb = 5} = {a: 3};
console.log(aa); // 3
console.log(bb); // 5
複製程式碼

六、陣列擴充套件

擴充套件運算子
擴充套件運算子(spread)是三個點(...),作用是將一個陣列轉為用逗號分隔的引數序列。

console.log(1, ...[2, 3, 4], 5)// 1 2 3 4 5
複製程式碼

Array.from
Array.from方法用於將兩類物件轉為真正的陣列:類似陣列的物件(array-like object)和可遍歷(iterable)的物件

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
};
let arr = Array.from(arrayLike); // ['a', 'b', 'c']
複製程式碼

Array.of
Array.of可以將一組值轉換成陣列,由於它不存在由於引數不同而導致的過載,基本上可以用來替代Array()或new Array()。

Array.of(1, 2, 3) // [1,2,3]
複製程式碼

includes
includes用於判斷元素是否在陣列中存在,返回值是 true/false。

let arr=[1,2,3];
arr.includes(2);//true
arr.includes(5);//flase
複製程式碼

find和findIndex
find:用於找出第一個符合條件的陣列元素。找不到則是 undefined 。注意,它是不會返回多個,只找一個,找到了就返回。如果你要把所有的滿足條件的陣列元素素都找出來,你應該用filter()

let arr=[1,2,3];
arr.find(item=>item>2);//3
複製程式碼

findIndex:返回第一個符合條件的陣列元素的索引。找不到則是-1;

let arr=[1,2,3];
arr.find(item=>item>2);//2
複製程式碼

七、物件擴充套件

物件中的簡潔表達

ES6 允許直接寫入變數和函式,作為物件的屬性和方法。 直接寫變數時,屬性名為變數名, 屬性值為變數的值

let a=1;
let obj={a};

//等同於
let obj={a:a}
複製程式碼

方法也可以簡寫

let obj={
    f(){
        return "hello";
    }
};

//等同於
let obj={
    f:function(){
        return "hello";
    }
};
複製程式碼

Object.assign

Object.assign方法用於物件的合併,將源物件(source)的所有可列舉屬性,複製到目標物件(target)。
Object.assign方法的第一個引數是目標物件,後面的引數都是源物件。

const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
console.log(target); // {a:1, b:2, c:3}
複製程式碼

注意細節:
第一個引數是目標物件,assign這個方法把其它的引數中的屬性全部加在第一個引數身上。
第一個引數在屬性複製過程中,可以被修改,如果有相名屬性,後面的會覆蓋前面的屬性。
assign這個方法的返回值就是第一個引數的引用,也就是返回了第一個引數。
assign這個方法會把原型上面的發展也拷貝了。
assign不能拷貝繼承過來的屬性。
assign也不拷貝不可列舉的屬性。

屬性相關的方法

Obect.getOwnProertyDescriptor() 獲取一個物件中某個屬性的詳細資訊。
Object.defineProperty() 精細化設定一個物件的屬性
Object.values() 獲取物件的值,放到陣列中
Object.keys() 獲取物件自身可列舉的屬性
Object.getOwnPropertyNames() : 獲取物件自身的全部屬性名

相關文章