這是我參與8月更文挑戰的第4天,活動詳情查看:8月更文挑戰前端
要知道,作前端開發,ES6 是必學的。這篇文章適合初步入門和複習,結合阮一峯老師的教程可以更深刻的學習 ES6。es6
目錄:面試
- 塊級做用域、塊級變量 let、塊級常量 const
- 箭頭函數
- 參數處理(默認參數/...)
- 模板字面量(模板字符串)
- 對象的擴展
- 解構賦值
- 模塊(import/export)
- 類(class/extends)
- Promise
- End 感謝閱讀
通常理解的塊:express
- 塊:由 {} 包括住
- if(){}:是一個塊
- for(){}:是一個塊
這些也可理解成塊:編程
- 一個函數:函數做用域
- script 標籤:全局做用域
var x = 1;
{
var x = 2;
}
console.log(x);
複製代碼
let x = 1;
{
let x = 2;
}
console.log(x);
複製代碼
背住
):var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {console.log(i);};
}
a[0](); // 10
a[1](); // 10
a[6](); // 10
/********************/
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {console.log(i);};
}
a[0](); // 0
a[1](); // 1
a[6](); // 6
複製代碼
使用 function 時也有塊級做用域:數組
foo('outside'); // TypeError: foo is not a function
{
function foo(location) {
console.log('foo is called ' + location);
}
foo('inside'); // 正常工做而且打印 'foo is called inside'
}
複製代碼
console.log(foo); //輸出 undefined,不會報錯
var foo = 2;
console.log(bar); //報錯 ReferenceError
let bar = 2;
複製代碼
在同一個做用域中用 let 重複定義一個變量將引發 TypeErrorpromise
if (x) {
let foo;
let foo; // TypeError thrown
}
複製代碼
// 下面錯誤,常量要求有一個初始值
const FOO;
// 下面正確,常量能夠定義成對象
const MY_OBJECT = {"key": "value"};
// 下面錯誤,改變常量會失敗
MY_OBJECT = {"OTHER_KEY": "value"};
// 對象屬性並不在保護的範圍內,下面會成功執行(對象自己發生變化)
MY_OBJECT.key = "otherValue";
// 定義一個常量
const MY_FAV = 20;
// 不能同名,會出錯
var MY_FAV = 20;
// 也會報錯
let MY_FAV = 20;
複製代碼
基礎語法:markdown
// 通常語法:
(參數1, 參數2, …, 參數N) => { 函數聲明 }
// 至關於:(參數1, 參數2, …, 參數N) =>{ return 表達式; }
(參數1, 參數2, …, 參數N) => 表達式(單一)
// 當只有一個參數時,圓括號是可選的:
(單一參數) => {函數聲明}
單一參數 => {函數聲明}
// 沒有參數的函數應該寫成一對圓括號
() => {函數聲明}
複製代碼
高級語法:編程語言
注意: 字面量通常指 [1, 2, 3] 或者 {name: "mdn"} 這種簡潔的構造方式ide
// 加括號的函數體返回對象字面表達式:
參數=> ({foo: bar})
// 支持剩餘參數和默認參數
(參數1, 參數2, ...rest) => {函數聲明}
(參數1 = 默認值1,參數2, …, 參數N = 默認值N) => {函數聲明}
// 一樣支持參數列表解構
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f(); // 6
複製代碼
例子:
箭頭函數比較適用於本來須要匿名函數的地方,好比用在數組內置方法map、filter、forEach、reduce的回調函數中
var elements = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
elements.map(function(element) {
return element.length;
}); // 返回數組:[8, 6, 7, 9]
// 上面的普通函數能夠改寫成以下的箭頭函數
elements.map((element) => {
return element.length;
}); // [8, 6, 7, 9]
複製代碼
重點注意:
this 對象的指向是可變的,可是在箭頭函數中,它是固定的。箭頭函數體內的 this 對象,就是定義時所在的對象,而不是使用時所在的對象。
在ES6之前,咱們想要給參數設置默認值得這麼作:
function multiply(a, b) {
// JavaScript 中函數的參數默認是 undefined
// 沒有值傳入或者 undefined 被傳入給 b 時給 b 一個默認值
b = (typeof b !== 'undefined') ? b : 1;
return a * b;
}
multiply(5, 2); // 10
multiply(5); // 5
複製代碼
如今學習了ES6以後就變得很簡單:
function multiply(a, b = 1) {
return a * b;
}
multiply(5, 2); // 10
multiply(5); // 5
複製代碼
注意參數的傳遞是從左到右的:
function f(x = 1, y) {
return [x, y];
}
f(); // [1, undefined]
f(2); // [2, undefined]
複製代碼
剩餘參數語法容許咱們將一個不定數量的參數表示爲一個數組。
語法:
function(a, b, ...theArgs) {
...
}
複製代碼
實例:
function fun1(...theArgs) {
alert(theArgs.length); // 可使用全部數組屬性方法
}
fun1(); // 彈出 "0", 由於 theArgs 沒有元素
fun1(5); // 彈出 "1", 由於 theArgs 只有一個元素
複製代碼
展開語法, 能夠在函數調用/數組構造時, 將數組表達式或者 string 在語法層面展開;還能夠在構造字面量對象時, 將對象表達式按 key-value 的方式展開。
注意: 字面量通常指 [1, 2, 3] 或者 {name: "mdn"} 這種簡潔的構造方式
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers));//6
/****下例表示能夠屢次使用****/
function myFunction(v, w, x, y, z) { }
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);
複製代碼
/****構造字面量數組或鏈接數組****/
var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];
// ["head", "shoulders", "knees", "and", "toes"]
var arr = [...parts, ...lyrics];
/****支持淺拷貝(一維數組)****/
var arr = [1, 2, 3];
var arr2 = [...arr];
arr2.push(4);
// arr2 此時變成 [1, 2, 3, 4]
// arr 不受影響
複製代碼
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// 淺拷貝
// 克隆後的對象: { foo: "bar", x: 42 }
var mergedObj = { ...obj1, ...obj2 };
// 合併後的對象: { foo: "baz", x: 42, y: 13 }
複製代碼
由反引號 `` 來代替單引號 '' 或者雙引號 "" 。
`string text`
複製代碼
再也不用 "+" 或 "\" 鏈接兩行字符串
`string text line 1 string text line 2`
console.log(`string text line 1 string text line 2`);
複製代碼
再也不用 "+" 鏈接表達式
`string text ${expression} string text`
var a = 5;
var b = 10;
console.log(`a + b is ${a + b}`);
複製代碼
標籤使咱們能夠用函數來解析模板字符串。
直接看例子:
var person = 'Mike';
var age = 28;
function myTag(strings, personExp, ageExp) {
var str0 = strings[0]; // "that "
var str1 = strings[1]; // " is a "
var ageStr;
if (ageExp > 99){
ageStr = 'centenarian';
} else {
ageStr = 'youngster';
}
return str0 + personExp + str1 + ageStr;
}
var output = myTag`that ${ person } is a ${ age }`;
console.log(output);
// that Mike is a youngster
複製代碼
在標籤函數的第一個參數中,存在一個特殊的屬性 raw ,咱們能夠經過它來訪問模板字符串的原始字符串,而不通過特殊字符的替換。
例子:
function tag(strings) {
console.log(strings.raw[0]);
}
tag`string text line 1 \n string text line 2`;
// logs "string text line 1 \n string text line 2"
複製代碼
通常狀況:
var name="pan";
var age=20;
var people = {
name: name,
age: age,
getName: function() {
console.log(this.name)
}
};
複製代碼
ES6簡化後:
var name="pan";
var age=20;
var people = {
name,
age,
getName(){
console.log(this.name)
}
};
複製代碼
var i = 0;
var a = {
["foo" + ++i]: i,
["foo" + ++i]: i,
["foo" + ++i]: i
};
console.log(a.foo1); // 1
console.log(a.foo2); // 2
console.log(a.foo3); // 3
複製代碼
當定義的 屬性:值 爲 proto:值 時,不會建立名爲 proto 的屬性。 但當值爲對象時,將更改原型(由於 proto 本來指向原型)。 因此不建議使用這個屬性名(避免更改 proto 的指向)。
解構賦值語法是一種 JavaScript 表達式,它使得將值從數組,或屬性從對象,提取到不一樣的變量中,成爲可能。
目的就是將數組中的值或對象中的屬性方便的提取到其餘變量中
var x, y;
[x, y] = [1, 2, 3];
console.log(x); // 1
console.log(y); // 2
// 或者:
var [x, y] = [1, 2, 3];
console.log(x); // 1
console.log(y); // 2
複製代碼
小技巧(不用臨時變量也能交換變量):
var a = 1;
var b = 3;
// 等價於[a,b]=[3,1]
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
複製代碼
var o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
複製代碼
注意:對象解構與數組解構有一個重要的不一樣點,數組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。
模塊功能主要由兩個命令構成:export 和 import。export 命令用於規定模塊的對外接口,import 命令用於輸入其餘模塊提供的功能。
一個模塊就是一個獨立的文件。該文件內部的全部變量,外部沒法獲取。若是你但願外部可以讀取模塊內部的某個變量,就必須使用 export 關鍵字輸出該變量。下面是一個 JS 文件,裏面使用 export 命令輸出變量。
// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export {firstName, lastName, year};
複製代碼
- 上面代碼是 profile.js 文件,保存了用戶信息,
- ES6 將其視爲一個模塊,裏面用 export 命令對外部輸出了三個變量。
- 除了這種普通變量,輸出的變量還能夠是一個函數。
- 另外,export 語句輸出的接口,與其對應的值是動態綁定關係,
- 即經過該接口,能夠取到模塊內部實時的值。
- 最後,export/import 命令不能在塊級做用域內,能夠在全局做用域任何位置。
import 語句只能在聲明瞭 type="module" 的 script 的標籤中使用。 動態導入:import(),它不須要依賴type="module" 的 script 標籤。 按照必定的條件或者按需加載模塊的時候,動態 import() 是很是有用的。 而靜態的 import 是初始化加載的最優選擇。
// main.js
import {firstName, lastName, year} from './profile.js';
function setName(element) {
element.textContent = firstName + ' ' + lastName;
}
複製代碼
注意:import 語句會執行所加載的模塊:
import './lodash.js';
// 執行lodash模塊,可是不輸入任何值
複製代碼
總體導入:
import * as myModule from './my-module.js'; // 不用加大括號 {}
// 將 my-module 裏面輸出的變量/函數,
// 輸入到 myModule 這個對象中做爲屬性/方法。
// 經過 myModule.屬性名 / myModule.方法() 來調用。
複製代碼
告別使用 import 命令的時候,用戶須要知道所要加載的變量名或函數名的現狀:
// 先用 export default 語法默認導出
// 既然是默認輸出,那麼一個模板只能使用一次
export default function foo() {
console.log('foo');
}
// 導入默認值
import customName from './default.js'; // 不用加大括號 {}
customName(); // 'foo'
複製代碼
ES6 中引入的 JavaScript 類實質上是 JavaScript 現有的基於原型的繼承的語法糖。類語法不會爲 JavaScript 引入新的面向對象的繼承模型。
class Rectangle {
constructor(height, width) { //構造方法
this.height = height;
this.width = width;
}
}
// 或者
let Rectangle = class {
constructor(height, width) { //構造方法
this.height = height;
this.width = width;
}
};
複製代碼
class Rectangle {
// constructor
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
get area() {
return this.calcArea()
}
// Method
calcArea() {
return this.height * this.width;
}
}
const square = new Rectangle(10, 10);
console.log(square.area); // 100
複製代碼
不能經過一個類實例調用靜態方法(這裏和 Java 語法有區別)
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static distance(a, b) { // static 語法
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.hypot(dx, dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
// 直接經過類名調用
console.log(Point.distance(p1, p2));
複製代碼
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
constructor(name) {
super(name); // 調用超類構造函數
}
speak() {
console.log(this.name + ' barks.');
}
}
var d = new Dog('Mitzie');
// 'Mitzie barks.'
d.speak();
複製代碼
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Lion extends Cat {
speak() {
super.speak();
console.log(this.name + ' roars.');
}
}
複製代碼
這部份內容是重難點,說是面試必考的知識點也不過度,由於它不易簡單的進行總結,因此我推薦讀到這裏的朋友去細讀 阮一峯Promise ,進行系統的學習這部份內容。
留下寶貴的一讚再走!