摘要:對象解構對象解構語法在賦值語句的左側使用了對象字面量,例如代碼中,的值被存儲到本地變量中,的值則存儲到變量中。當使用解構賦值語句時,如果所指定的本地變量在對象中沒有找到同名屬性,那么該變量會被賦值為。
現在ES6在很多項目中大量使用。最近我也花時間看了一下《Understanding ECMAScript6》的中文電子書。在這里總結了一些在實際開發中常用的新特性。
塊級作用域在ES6之前,JS只有一種變量聲明方式——使用 var 關鍵字聲明的變量。這種聲明變量的方式,無論其實際聲明位置在何處,都會被視為聲明于所在函數的頂部(如果聲明不在任意函數內,則視為在全局作用域的頂部)。這就是所謂的變量提升 ( hoisting )。
ES6 引入了塊級作用域,讓變量的生命周期更加可控。
塊級聲明也就是讓所聲明的變量在指定塊的作用域外無法被訪問。塊級作用域(又被稱為詞法作用域)在如下情況被創建:
在一個函數內部
在一個代碼塊(由一對花括號包裹)內部
let聲明let聲明會將變量的作用域限制在當前代碼塊中。由于 let 聲明并不會被提升到當前代碼塊的頂部,因此你需要手動將 let 聲明放置到頂部,以便讓變量在整個代碼塊內部可用。例如:
function getValue(condition) { if (condition) { let value = "blue"; // 其他代碼 return value; } else { // value 在此處不可用 return null; } // value 在此處不可用 }
注意事項
如果一個標識符已經在代碼塊內部被定義,那么在此代碼塊內使用同一個標識符進行 let 聲明就會導致拋出錯誤。例如:
var count = 30; let count = 40; // 語法錯誤
另一方面,在嵌套的作用域內使用 let 聲明一個同名的新變量,則不會拋出錯誤,以下代碼對此進行了演示:
var count = 30; // 不會拋出錯誤 if (condition) { let count = 40; // 其他代碼 }常量聲明
在 ES6 中里也可以使用 const 語法進行聲明。使用 const 聲明的變量會被認為是常量( constant )。const 用法與 let 類似,但有一個重要的區別,const 聲明的變量的值在被設置完成后就不能再被改變。正因為如此,所有的 const 變量都需要在聲明時進行初始化。
const maxItems = 30; // 有效的常量 const name; // 語法錯誤:未進行初始化 const minItems = 5; minItems = 6; //拋出錯誤模板字符串
模板字符串(template string)是增強版的字符串,使用反引號( ` )來包裹普通字符串。它可以當作普通字符串使用,也可以用來定義多行字符串,或者在字符串中嵌入變量。
// 普通字符串 let message = `Hello world!`; console.log(message); // Hello world! //在字符串中包含反引號,只需使用反斜杠( )轉義即可 let message = ``Hello` world!`; console.log(message); // `Hello` world! // 多行字符串(只需在想要的位置包含換行即可) let message = `Multiline string`; console.log(message); // "Multiline // string" console.log(message.length); // 16 //反引號之內的所有空白符都是字符串的一部分,因此需要留意縮進。 let message = `Multiline string`; console.log(message); // "Multiline // string" console.log(message.length); // 31 // 字符串中嵌入變量 var name = "Bob", time = "today"; console.log(`Hello ${name}, how are you ${time}?`) // Hello Bob, how are you today?替換位
模板字符串替換位的標識是 ${} 。大括號內部可以放入任意的JavaScript表達式,比如:變量名、運算、函數調用,以及引用對象屬性。
//普通變量名 var name = "Nicholas"; var message = `Hello, ${name}.`; console.log(message); // Hello, Nicholas. //計算 var x = 1; var y = 2; console.log(`${x} + ${y} = ${x + y}`) // 1 + 2 = 3 console.log(`${x} + ${y * 2} = ${x + y * 2}`) // 1 + 4 = 5 //函數調用 function fn() { return "Hello World"; } console.log(`foo ${fn()} bar`) // foo Hello World bar //對象屬性 var obj = {x: 1, y: 2}; console.log(`${obj.x + obj.y}`)函數 函數參數的默認值
在 ES5 或更早的版本中,我們可能會使用下述模式來創建帶有參數默認值的函數:
function add(x, y) { x = x || 20; y = y || 30; return x + y; } console.log(add()); // 50
這種寫法有一個缺點:如果參數x或者y賦值了,但是對應的布爾值為false,則該賦值不起作用。
在這種情況下,更安全的替代方法是使用typeof來檢測參數的類型,示例如下:
function add(x, y) { x = (typeof x !== "undefined") ? x : 20; y = (typeof y !== "undefined") ? x : 30; //... }
下面來看看ES6函數參數默認值的寫法:
function add(x = 20, y = 30) { return x + y; }
可以看到,ES6 的寫法比 ES5 簡潔許多,而且非常自然。
rest參數和擴展運算符關于這兩部分內容可以看這里
箭頭函數ES6 最有意思的一個新部分就是箭頭函數( arrow function )。箭頭函數使用“箭頭”(=>)來定義。
先來看看箭頭函數與傳統的函數寫法的區別:
// ES6 var f = () => 5; // ES5 var f = function () { return 5 }; // ES6 var sum = (num1, num2) => num1 + num2; // ES5 var sum = function(num1, num2) { return num1 + num2; };
如果箭頭函數的代碼塊部分多于一條語句,就要使用大括號將它們括起來,并且使用return語句返回。
const foo = () => { const a = 20; const b = 30; return a + b; }
箭頭函數的一個用處是簡化回調函數。
// ES5 [1,2,3].map(function (x) { return x * x; }); // ES6 [1,2,3].map(x => x * x);
箭頭函數可以替換函數表達式,但是不能替換函數聲明
在使用箭頭函數時要注意如下幾點:
不能更改this :this的值在函數內部不能被修改,在函數的整個生命周期內其值會
保持不變。
沒有arguments對象:既然箭頭函數沒有arguments綁定,你必須依賴于具名參數或
剩余參數來訪問函數的參數。
不能被使用new調用: 箭頭函數沒有[[Construct]]方法,因此不能被用為構造函
數,使用new調用箭頭函數會拋出錯誤。
沒有原型: 既然不能對箭頭函數使用new,那么它也不需要原型,也就是沒有
prototype屬性。
// 屬性的簡寫 function f(x, y) { return {x, y}; } // 等同于 function f(x, y) { return {x: x, y: y}; } f(1, 2) // Object {x: 1, y: 2} // 方法的簡寫 var o = { method() { return "Hello!"; } }; // 等同于 var o = { method: function() { return "Hello!"; } };需計算屬性名
JavaScript語言定義對象的屬性,有兩種方法。
var person = {}, lastName = "last name"; // 方法一 person["first name"] = "Nicholas"; // 方法二 person[lastName] = "Zakas"; console.log(person["first name"]); // "Nicholas" console.log(person[lastName]); // "Zakas"
但是,如果使用字面量方式定義對象(使用大括號),在ES5中只能使用方法一定義屬性。
var person = { "first name": "Nicholas" }; console.log(person["first name"]); // "Nicholas"
在ES6中,需計算屬性名是對象字面量語法的一部分,它用的也是方括號表示法。
var lastName = "last name"; var person = { "first name": "Nicholas", [lastName]: "Zakas" }; console.log(person["first name"]); // "Nicholas" console.log(person[lastName]); // "Zakas" // 方括號內也可以是表達式 var suffix = " name"; var person = { ["first" + suffix]: "Nicholas", ["last" + suffix]: "Zakas" }; console.log(person["first name"]); // "Nicholas" console.log(person["last name"]); // "Zakas" // 也可以用來表示方法名 var obj = { ["h" + "ello"]() { console.log("hi"); } }; obj.hello() // hi解構賦值
解構賦值也是ES6中非常常用的一個特性。
按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構(Destructuring)。
對象解構語法在賦值語句的左側使用了對象字面量,例如:
let node = { type: "Identifier", name: "foo" }; let { type, name } = node; console.log(type); // "Identifier" console.log(name); // "foo"
代碼中,node.type的值被存儲到type本地變量中,node.name的值則存儲到name變量中。
當使用解構賦值語句時,如果所指定的本地變量在對象中沒有找到同名屬性,那么該變量會被賦值為undefined。例如:
let node = { type: "Identifier", name: "foo" }; let { type, name, value } = node; console.log(type); // "Identifier" console.log(name); // "foo" console.log(value); // undefined
我們可以選擇性地定義一個默認值,以便在指定屬性不存在時使用該值。就像這樣:
let node = { type: "Identifier", name: "foo" }; let { type, name, value = true } = node; console.log(type); // "Identifier" console.log(name); // "foo" console.log(value); // true
上面的示例都使用了對象中的屬性名作為本地變量的名稱。但ES6允許我們在給本地變量賦值時使用一個不同的名稱。就像這樣:
let node = { type: "Identifier", name: "foo" }; let { type: localType, name: localName } = node; console.log(localType); // "Identifier" console.log(localName); // "foo" // 我們也可以給變量別名加默認值 let node = { type: "Identifier" }; let { type: localType, name: localName = "bar" } = node; console.log(localType); // "Identifier" console.log(localName); // "bar"數組結構
數組解構的語法看起來與對象解構非常相似,只是將對象字面量替換成了數組字面量。直接看例子:
let colors = [ "red", "green", "blue" ]; let [ firstColor, secondColor ] = colors; console.log(firstColor); // "red" console.log(secondColor); // "green" // 也可以在解構模式中忽略一些項 let colors = [ "red", "green", "blue" ]; let [ , , thirdColor ] = colors; console.log(thirdColor); // "blue" // 也可以添加默認值 let colors = [ "red" ]; let [ firstColor, secondColor = "green" ] = colors; console.log(firstColor); // "red" console.log(secondColor); // "green"字符串結構
字符串也可以進行結構賦值。
const [a, b, c, d, e] = "hello"; console.log(a) // "h" console.log(b) // "e" console.log(c) // "l" console.log(d) // "l" console.log(e) // "o"參數結構
function add([x, y]){ return x + y; } add([1, 2]); // 3 // 參數解構也可以有默認 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]模塊
模塊功能主要由兩個命令構成:export和import。export命令用于規定模塊的對外接口,import命令用于輸入其他模塊提供的功能。
export 命令// 導出數據 export var color = "red"; export let name = "Nicholas"; export const magicNumber = 7; // 導出函數 export function sum(num1, num2) { return num1 + num1; } // 導出類 export class Rectangle { constructor(length, width) { this.length = length; this.width = width; } } // export還可以像下面這樣寫,放在大括號內統一導出 export var color = "red"; export let name = "Nicholas"; export const magicNumber = 7; export {color, name, magicNumber}; // 重命名導出 function sum(num1, num2) { return num1 + num1; } export {sum as add} // 這里sum函數被作為add導出import 命令
// 導入單個 import { color } from "./example.js"; // 導入多個 import { color, name, sum } from "./example.js"; // 重命名導入 import { color as redColor } from "./example.js"; // 整體導入 import * as example from "./example.js";導出/導入默認值
導出默認值要使用default關鍵字
// 導出默認值一共有三種寫法 // 第一種 export default function(num1, num2) { return num1 + num2; } // 第二種 function sum(num1, num2) { return num1 + num2; } export default sum; // 第三種 function sum(num1, num2) { return num1 + num2; } export { sum as default };
導入默認值得方式也有所不同
import sum from "./example.js"; // 與前面不同的是,這里沒有了大括號。 console.log(sum(1, 2)); // 3后記
上面只是總結得只是一部分ES6的常用特性,其實還有Promise,Class等,因篇幅原因,這些可能留到以后再寫。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87176.html
摘要:一般來說,聲明式編程關注于發生了啥,而命令式則同時關注與咋發生的。聲明式編程可以較好地解決這個問題,剛才提到的比較麻煩的元素選擇這個動作可以交托給框架或者庫區處理,這樣就能讓開發者專注于發生了啥,這里推薦一波與。 本文翻譯自FreeCodeCamp的from-zero-to-front-end-hero-part。 繼續譯者的廢話,這篇文章是前端攻略-從路人甲到英雄無敵的下半部分,在...
摘要:最近重構了一個項目,引入了部分用法,最大的感受是讓這門語言變得更加嚴謹,更加方便。通過該方法獲得位置后還得比較一次才能判斷是否存在。再來看看的寫法使用數組來初始化一個,構造器能確保不重復地使用這些值。下面提供鏈接,供有興趣的朋友參考。 最近重構了一個SPA項目,引入了部分ES6用法,最大的感受是ES6讓javascript這門語言變得更加嚴謹,更加方便。本篇將結合實戰經驗,對最常用的部...
摘要:經常游蕩在的我總能發現許多好問題和好答案。盡管網絡上有著各式各樣的關于該主題的指導,但涉及到在各種情景下的最佳實踐,或者較好實踐的方面還是不夠清晰。我寄希望于針對我這篇裹腳布式問題的回復可以改變這一現狀。我感覺因此收益的絕對不止是我一個人。 經常游蕩在 SO 的我總能發現許多好問題和好答案。它們的好不僅僅在于知識的價值,更可貴之處在于如何表達:如何提問/如何回答。不久前我在 SF...
摘要:因為箭頭函數沒有構造方法。因為不能一個箭頭函數,所以也沒必要有了。的值在這個箭頭函數的整個生命周期里面都不變。你必須通過命名參數和剩余參數去獲取箭頭函數的參數。非箭頭函數在非嚴格模式下面可以有重名參數。 例行聲明:接下來的文字內容全部來自 Understanding ECMAScript 6,作者是Nicholas C.Zakas,也就是大名鼎鼎的Professional JavaSc...
摘要:在生成器中使用語句生成器也是函數,所以它也可以使用語句。只是由于生成器本身的特性,其內部的的行為會和一般函數有些差別。 前面2篇系列文章講解了迭代器和生成器的最常用,最基礎的用法;這篇來討論迭代器和生成器的一些稍稍高級一點的用法: 1: 給迭代器的next()方法傳參 2: 從迭代器中拋出錯誤 3: 在生成器中使用return語句 4: 委托生成器(組合生成器或者生成器組合?) 1: ...
閱讀 3615·2021-11-22 09:34
閱讀 3186·2021-11-15 11:38
閱讀 3039·2021-10-27 14:16
閱讀 1233·2021-10-18 13:35
閱讀 2424·2021-09-30 09:48
閱讀 3429·2021-09-29 09:34
閱讀 1626·2019-08-30 15:54
閱讀 1818·2019-08-26 11:57