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