ES6常用語法總結

来源:http://www.cnblogs.com/liangyin/archive/2017/11/12/7820704.html
-Advertisement-
Play Games

、`const`關鍵字 在 之前, 中變數預設是全局性的,只存在函數級作用域,聲明函數曾經是創造作用域的唯一方法。這點和其他編程語言存在差異,其他語言大多數都存在塊級作用域。所以在 中,新提出的 和 關鍵字使這個缺陷得到了修複。 同時還引入的概念 ,用來定義一個常量,一旦定義以後不可以修改,如果是引 ...


letconst關鍵字

ES6 之前,JavaScript 中變數預設是全局性的,只存在函數級作用域,聲明函數曾經是創造作用域的唯一方法。這點和其他編程語言存在差異,其他語言大多數都存在塊級作用域。所以在 ES6 中,新提出的 letconst 關鍵字使這個缺陷得到了修複。

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

同時還引入的概念 const,用來定義一個常量,一旦定義以後不可以修改,如果是引用類型,那麼可以修改其引用屬性,不可以修改其引用。

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 定義的變數使用大寫形式

函數

箭頭函數

箭頭函數是一種更簡單的函數聲明方式,可以把它看作是一種語法糖,箭頭函數永遠是匿名的

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 在一個對象方法中嵌套函數作用域的問題。

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箭頭函數使用註意點

函數預設參數

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

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • package com.swift; public class Maopao { //冒泡法 public static void main(String[] args) { int[] arr= {28,2,38,1,390,17,10,9,323}; for(int i=0;iarr[j+1])... ...
  • 2.3 複合類型 2.3.1 引用 引用就是為對象起了個別名,引用類型引用另外一種類型。通過將聲明符寫成&d的形式來定義引用類型,其中d是聲明的變數名。 int ival =1024; int &refVal= ival; // refVal 指向ival (是ival 的另一個名字) 2.3.2 ...
  • 1.創建project django-admin.py startproject myblog 2.創建app python manage.py startapp blog 3. 創建資料庫表 或 更改資料庫表或欄位 Python manage.py makemigrations blog Pyth ...
  • 本文來是從 java web輕量級開發麵試教程從摘錄的。 為什麼要從諸多的Java書籍里選擇這本?為什麼在當前網路信息量如此大的情況下還要買這本書,而不是自己通過查閱網路資料學習?我已經會開發Java Web程式了,有沒有必要買這本書? 筆者有12年的Java經驗,目前是某大型公司的架構師,知道軟體 ...
  • DTOJ 2704:數字互換 解題報告 2017.11.11 第一版 ——由翱翔的逗比w原創 題目信息: 題目描述 輸入兩個數作為交換數,輸出已交換順序後的兩個值。 輸入兩個數作為交換數,輸出已交換順序後的兩個值。 輸入 兩個整數,空格隔開 兩個整數,空格隔開 輸出 交換後的兩個整數,空格隔開 交換 ...
  • #include #define uint unsigned int #define uchar unsigned char sbit wei=P2^7; sbit duan=P2^6; sbit key1=P3^4; sbit key2=P3^5; sbit key3=P3^6; uchar co... ...
  • 本文主要針對Mac的jdk的安裝、環境變數配置、jdk卸載方面進行方法總結。 ...
  • 前言 - 思考還是 socket 寫過一點點, 總感覺很彆扭. 例如 read, recv, recvfrom 這些為啥這麼奇葩. 這是 linux 的設計嗎. 這種強糅合的 read 代碼, '帶壞'了多少人. 想起很久以前看過的 <<UNIX痛恨者手冊>>, 外加上常寫點跨平臺 庫. 不得不思考 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...