ES6經常使用語法總結

letconst關鍵字

ES6 以前,JavaScript 中變量默認是全局性的,只存在函數級做用域,聲明函數曾經是創造做用域的惟一方法。這點和其餘編程語言存在差別,其餘語言大多數都存在塊級做用域。因此在 ES6 中,新提出的 letconst 關鍵字使這個缺陷獲得了修復。javascript

if (true) {
    let a = 'name';
}
console.log(a); // ReferenceError: a is not defined

同時還引入的概念 const,用來定義一個常量,一旦定義之後不能夠修改,若是是引用類型,那麼能夠修改其引用屬性,不能夠修改其引用。html

const MYNAME = 'liangyin';
MYNAME = 'doke';
// TypeError: Assignment to constant variable.
const MYNAME = {
    first: 'liang'
};
MYNAME.last = 'yin';
// {first: "liang", last: "yin"}

有如下幾點須要注意:前端

  • 儘可能使用 letconst 代替 var
  • 聲明方法儘可能使用 const 以防止後期無心覆蓋
  • const 定義的變量使用大寫形式

函數

箭頭函數

箭頭函數是一種更簡單的函數聲明方式,能夠把它看做是一種語法糖,箭頭函數永遠是匿名的java

let add = (a, b) => {
    return a + b;
}
// 當後面是表達式(expression)的時候,還能夠簡寫成
let add = (a, b) => a + b;
// 等同於
let add = function(a, b) {
    return a + b;
}
// 在回調函數中應用
let number = [1, 2, 3];
let doubleNumber = number.map(number => number * 2);
console.log(doubleNumber);
// [2, 4, 6] 看起來很簡便吧

this 在箭頭函數中的使用

在工做中常常會遇到 this 在一個對象方法中嵌套函數做用域的問題。express

var age = 2;
var kitty = {
    age: 1,
    grow: function() {
        setTimeout(function() {
            console.log(++this.age);
        }, 100)
    }
};
kitty.grow();
// 3

其實這是由於,在對象方法的嵌套函數中,this 會指向 global 對象,這被看作是 JavaScript 在設計上的一個重大缺陷,通常都會採用一些 hack 來解決它。編程

let kitty = {
    age: 1,
    grow: function() {
        const self = this;
        setTimeout(function() {
            console.log(++self.age);
        }, 100);
    }
}
// 或者
let kitty = {
    age: 1,
    grow: function() {
        setTimeout(function() {
            console.log(this.age);
        }.bind(this), 100)
    }
}

如今有了箭頭函數,能夠很輕鬆地解決這個問題。數組

let kitty = {
    age: 1,
    grow: function() {
        setTimeout(() => {
            console.log(this.age);
        }, 100)
    }
}

可是箭頭函數並非萬能的,任何事物都具備兩面性,語言的新特性經常被誤解、濫用,好比箭頭函數的使用就存在不少誤區。 你們能夠移步☞ES6箭頭函數使用注意點app

函數默認參數

ES6 出現之前,面對默認參數都會讓人感到很痛苦,不得不採用各類 hack 手段,好比說:values = values || []。如今一切都變得輕鬆不少。編程語言

function desc(name = 'liangyin', age = 18) {
    return name + '已經' + age + '歲了'
}
desc();
// liangyin已經18歲了

Rest 參數

當一個函數的最後一個參數有...這樣的前綴,它就會變成一個參數的數組。模塊化

function test(...args) {
    console.log(args);
}
test(1, 2, 3);
// [1,2,3]
function test2(name, ...args) {
    console.log(args);
}
test2('liangyin', 2, 3);
// [2,3]

它和 arguments 參數有以下區別:

  • Rest 參數只是沒有指定變量名稱的參數數組,而 arguments 是全部參數的集合。
  • arguments 對象並非一個真正的數組,而 Rest 參數是一個真正的數組,可使用各類數組方法,好比 sortmap等。

展開操做符

剛剛講到了 Rest操做符來實現函數參數的數組,其實這個操做符的能力不只如此。它被稱爲展開操做符,容許一個表達式在某處展開,在存在多個參數(用於函數調用),多個元素(用於數組字面量)或者多個變量(用於解構賦值)的地方就會出現這種狀況。

用於函數調用

以前在 JavaScript 中,想讓函數把一個數組依次做爲參數進行調用,通常會採起如下措施:

function test(x, y, z) {};
var args = [1, 2, 3];
test.apply(null, args);

有了 ES6 的展開運算符,能夠簡化這個過程:

function test(x, y, z) {};
let args = [1, 2, 3];
test(...args);

用於數組字面量

在以前的版本中,若是想建立含有某些元素的新數組,經常會用到 spliceconcatpush等方法:

var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var arr3 = arr1.concat(arr2);
console.log(arr3);
// [1,2,3,4,5,6]

使用展開運算符之後就簡便了不少:

let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let arr3 = [...arr1, ...arr2];
console.log(arr3);
// [1,2,3,4,5,6]

對象的展開運算符(ES7

數組的展開運算符簡單易用,那麼對象有沒有這個特性?

let uzi = {
    name: 'uzi',
    age: 50
};
uzi = {
    ...uzi,
    sex: 'male'
};
console.log(uzi);
// {name: "uzi", age: 50, sex: "male"}

這是 ES7 的提案之一,它可讓你以更簡潔的形式將一個對象可枚舉屬性複製到另一個對象上去。

模板字符串

ES6 以前的時代,字符串拼接老是一件使人很很很不爽的一件事,可是在ES6的時代,這個痛點終於被治癒了!!!

// 以前的作法
var name = 'uzi';
var a = 'My name is ' + uzi + '!';
// 多行字符串
var longStory = 'This is a long story,' + 'this is a long story,' + 'this is a long story.'
// 有了 ES6 以後咱們能夠這麼作
let name = 'uzi';
let a = `My name is ${name} !`;
let longStory = `This is a long story,
                this is a long story,
                this is a long story.`

解構賦值

解構語法能夠快速從數組或者對象中提取變量,能夠用一個表達式讀取整個結構。

解構數組

let number = ['one', 'two', 'three'];
let [one, two, three] = number;
console.log(`${one},${two},${three}`);
// one,two,three

解構對象

let uzi = {
    name: 'uzi',
    age: 20
};
let {
    name,
    age
} = uzi;
console.log(`${name},${age}`);
// uzi,20

解構賦值能夠看作一個語法糖,它受 Python 語言的啓發,提升效率之神器。

衆所周知,在 JavaScript 的世界裏是沒有傳統類的概念,它使用的是原型鏈的方式來完成繼承,可是聲明方式老是怪怪的(很大一部分人不遵照規則用小寫變量聲明一個類,這就致使類和普通方法難以區分)。
ES6 中提供了 class 這個語法糖,讓開發者模仿其餘語言類的聲明方式,看起來更加明確清晰。須要注意的是, class 並無帶來新的結構,只是原來原型鏈方式的一種語法糖。

class Animal {
    // 構造函數
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    shout() {
        return `My name is ${this.name}, age is ${this.age}`;
    }
    // 靜態方法
    static foo() {
        return 'this is static method';
    }
}

const cow = new Animal('uzi', 2);
cow.shout();
// "My name is uzi, age is 2"
Animal.foo();
// "this is static method"

class Dog extends Animal {
    constructor(name, age = 2, color = 'black') {
        // 在構造函數中直接調用 super 方法
        super(name, age);
        this.color = color;
    }
    shout() {
        // 非構造函數中不能直接使用 super 方法
        // 可是能夠採用 super. + 方法名調用父類方法
        return super.shout() + `, color is ${this.color}`;
    }
}

const uzisDog = new Dog('uzi');
uzisDog.shout();
// "My name is uzi, age is 2, color is black"

對象

Object.assign 方法用來將源對象的全部可枚舉屬性複製到目標對象.

let target = {
    a: 1
};

// 後邊的屬性值,覆蓋前面的屬性值
Object.assign(target, {
    b: 2,
    c: 3
}, {
    a: 4
});
console.log(target);
// {a: 4, b: 2, c: 3}

爲對象添加屬性

class add {
    constructor(obj) {
        Object.assign(this, obj);
    }
}

let p = new add({
    x: 1,
    y: 2
});
console.log(p);
// add {x: 1, y: 2}

爲對象添加方法

Object.assign(add.prototype, {
    getX() {
        return this.x;
    },
    setX(x) {
        this.x = x;
    }
});

let p = new add(1, 2);

console.log(p.getX()); // 1

克隆對象

function cloneObj(origin) {
    return Object.assign({}, origin);
}

SetMapArray.from

Set

Set裏面的成員的值都是惟一的,沒有重複的值,Set加入值時不會發生類型轉換,因此5和"5"是兩個不一樣的值。

// 數組去重
    function dedupe(array) {
        return Array.from(new Set(array));
    }

    console.log(dedupe([1, 2, 2, 3])); // 1, 2, 3

Map

Map相似於對象,也是鍵值對的集合,可是"鍵"的範圍不限於字符串,各類類型的值(包括對象)均可以當作鍵.

let m = new Map();

let o = {
    p: 'Hello World'
};

m.set(o, 'content');
m.get(o); // content

m.has(o); // true
m.delete(o); // true
m.has(o); // false

m.set(o, 'my content').set(true, 7).set('foo', 8);

console.log(m);
// Map(3) {{…} => "my content", true => 7, "foo" => 8}

// Map/數組/對象 三者之間的相互轉換
console.log([...m]);
// (3) [Array(2), Array(2), Array(2)]

Array.from

轉換Map

Map對象的鍵值對轉換成一個一維數組。

const map1 = new Map();
map1.set('k1', 1);
map1.set('k2', 2);
map1.set('k3', 3);
console.log(Array.from(map1))
// [Array(2), Array(2), Array(2)]

轉換Set

const set1 = new Set();
set1.add(1).add(2).add(3);
console.log(Array.from(set1));
// [1, 2, 3]

轉換字符串

能夠把ascii的字符串拆解成一個數據,也能夠準確的將unicode字符串拆解成數組。

console.log(Array.from('hello world'));
console.log(Array.from('\u767d\u8272\u7684\u6d77'));
// ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
// ["白", "色", "的", "海"]

類數組對象

一個類數組對象必需要有length,他們的元素屬性名必須是數值或者能夠轉換成數值的字符。

注意:屬性名錶明瞭數組的索引號,若是沒有這個索引號,轉出來的數組中對應的元素就爲空。

console.log(Array.from({
  0: '0',
  1: '1',
  3: '3',
  length:4
}));
// ["0", "1", undefined, "3"]

若是對象不帶length屬性,那麼轉出來就是空數組。

console.log(Array.from({
    0: 0,
    1: 1
}));
// []

對象的屬性名不能轉換成索引號時,轉出來也是空數組。

console.log(Array.from({
    a: '1',
    b: '2',
    length: 2
}));
// [undefined, undefined]

Array.from能夠接受三個參數

Array.from(arrayLike[, mapFn[, thisArg]])

arrayLike:被轉換的的對象。

mapFn:map函數。

thisArg:map函數中this指向的對象。

模塊

JavaScript 模塊化是一個很古老的話題,它的發展從側面反映了前端項目愈來愈複雜、愈來愈工程化。在 ES6 以前,JavaScript 沒有對模塊作出任何定義,知道 ES6 的出現,模塊這個概念才真正有了語言特性的支持,如今來看看它是如何被定義的。

// hello.js 文件
// 定義一個命名爲 hello 的函數
function hello() {
    console.log('Hello ES6');
}
// 使用 export 導出模塊
export {hello};


// main.js
// 使用 import 加載這個模塊
import {
    hello
} from './hello';
hello();
// Hello ES6

上面的代碼就完成了模塊的一個最簡單的例子,使用 importexport 關鍵字完成模塊的導入和導出。固然也能夠完成一個模塊的多個導出:

// hello.js
export const PI = 3.14;
export function hello() {
    console.log('Hello ES6');
}
export let person = {
    name: 'uzi'
};

// main.js
// 使用對象解構賦值加載這3個變量
import {
    PI,
    hello,
    person
} from './hello';

// 也能夠將這個模塊所有導出
import * as util from './hello';
console.log(util.PI);
// 3.14

還可使用 default 關鍵字來實現模塊的默認導出:

// hello.js
export default function() {
    console.log('Hello ES6');
}

// main.js
import hello from './hello';
hello();
// Hello ES6
相關文章
相關標籤/搜索