摘要:讓你的代碼更簡(jiǎn)短,更整潔,更易讀的小技巧寫在文章前面這篇文章翻譯自文章就代碼整潔方面對(duì)進(jìn)行了總結(jié)。如果你正在使用的代碼使用的語(yǔ)法,這個(gè)是你需要注意的事情。更多還提供了我們很多很多其他的方式來(lái)使我們的代碼更簡(jiǎn)潔,更易讀,以及更穩(wěn)定。
讓你的代碼更簡(jiǎn)短,更整潔,更易讀的ES6小技巧 寫在文章前面
這篇文章翻譯自ES6 tips and tricks to make your code cleaner, shorter, and easier to read!. 文章就代碼整潔方面對(duì)es6進(jìn)行了總結(jié)。如有錯(cuò)誤歡迎指出。
template literals 模板字符串模板字符串使字符串的使用變得比以前更簡(jiǎn)單了,他們以反引號(hào)開始(`),并且能過(guò)使用${變量}來(lái)插入變量。我們來(lái)比較一下下面兩行代碼。
var fName = "Peter", sName = "Smith", age = 43, job= "photographer"; var a = "Hi, I"m " + fName + " " + sName + ", I"m " + age + " and work as a " + job + "."; var b = `Hi, I"m ${ fName } ${ sName }, I"m ${ age } and work as a ${ job }.`;
一切都變得很美好了是不是,代碼更易讀了是不是?你可以在大括號(hào)內(nèi)放入任何東西:變量,等式,或者函數(shù)的調(diào)用。 我將會(huì)在后面的整個(gè)文章的示例中使用這些方式。
塊級(jí)作用域語(yǔ)法JavaScript是使用函數(shù)作用域的,這就是為什么我們是為什么我們?cè)絹?lái)越頻繁的使用匿名的立即執(zhí)行函數(shù)表達(dá)式(iife)來(lái)實(shí)現(xiàn)整個(gè)JavaScript文件的封裝。我們這么做是為了把所有的變量隔離在文件內(nèi)從而避免變量沖突。
現(xiàn)在我們有了塊級(jí)作用域和兩個(gè)嶄新的塊級(jí)作用域的變量聲明
let declaration let命令這個(gè)命令和var很相似但卻又有著顯著的不同。因?yàn)樗怯袎K級(jí)作用域的,聲明一個(gè)相同名字的新變量可以完全不影響外部的變量。
var a = "car" ; { let a = 5; console.log(a) // 5 } console.log(a) // car
因?yàn)樗潜幌拗圃趬K級(jí)作用域的,他解決了那道非常經(jīng)典的面試題:“下面這個(gè)代碼的輸出是什么,如何修改讓他運(yùn)行之后成為你想的那個(gè)樣子?”
for (var i = 1; i < 5; i++){ setTimeout(() => { console.log(i); }, 1000); }
這個(gè)例子中,輸出是“5 5 5 5 5”因?yàn)樽兞?b>i在每次迭代中都會(huì)改變。
如果我們把var變?yōu)?b>let,一切都變了。 現(xiàn)在,每次循環(huán)都會(huì)創(chuàng)建一個(gè)全新的塊級(jí)作用域吧i限制在當(dāng)前的循環(huán),他可以理解為這樣:
{let i = 1; setTimeout(() => { console.log(i) }, 1000)} {let i = 2; setTimeout(() => { console.log(i) }, 1000)} {let i = 3; setTimeout(() => { console.log(i) }, 1000)} {let i = 4; setTimeout(() => { console.log(i) }, 1000)} {let i = 5; setTimeout(() => { console.log(i) }, 1000)}
var 和 let的另外一個(gè)區(qū)別是 let 不會(huì)像 var一樣被變量提升
{ console.log(a); // undefined console.log(b); // ReferenceError var a = "car"; let b = 5; }
因?yàn)樗懈鼮榫窒薜淖饔糜颍约案鼙活A(yù)測(cè)的行為,因此一些人甚至認(rèn)為你應(yīng)該使用let來(lái)代替var, 除非當(dāng)你真的特別需要變量提升或者更寬松的作用域范圍,你再使用var
Const
在以前,如果你想在JavaScript中聲明一個(gè)常量, 習(xí)慣性的做法是使用全大寫來(lái)命名。然鵝,這不是真的去保護(hù)了這個(gè)變量不能被更改---只是讓其他的開發(fā)者知道,這是一個(gè)常量,它不應(yīng)該被更改。
現(xiàn)在我們有了const命令.
const沒有讓變量完全不可變,只是鎖定他的賦值,當(dāng)你有一個(gè)復(fù)雜的變量(數(shù)組或者對(duì)象)的時(shí)候,值還是可以被修改的。
{ const d = [1, 2, 3, 4]; const dave = { name: "David Jones", age: 32}; d.push(5); dave.job = "salesman"; console.log(d); // [1, 2, 3, 4, 5] console.log(dave); // { age: 32, job: "salesman", name: "David Jones"} }Problem with block scoping functions函數(shù)塊級(jí)作用域化帶來(lái)的問(wèn)題
函數(shù)的聲明也可以限制在塊級(jí)作用域中。
{ bar(); // works function bar() { /* do something */ } } bar(); // doesn"t work
但是當(dāng)你在一個(gè)if語(yǔ)句中聲明一個(gè)函數(shù)的時(shí)候問(wèn)題來(lái)了。
想一下這種情況:
if ( something) { function baz() { console.log("I passed") } } else { function baz() { console.log("I didn"t pass") } } baz();
在ES6之前,這兩個(gè)函數(shù)聲明都被變量提升,而且結(jié)果一定是I didn"t pass 不論條件中的something是什么。但現(xiàn)在我們會(huì)得到輸出ReferenceError, 因?yàn)?baz一直被限定在塊級(jí)作用域內(nèi)。
Spread 擴(kuò)展運(yùn)算符ES6介紹了...操作符,這個(gè)操作符指的就是‘?dāng)U展運(yùn)算符‘。他的主要用途有兩個(gè):1. 將一個(gè)數(shù)組或者對(duì)象放到一個(gè)新的數(shù)組或者對(duì)象中 2. 將數(shù)組中的多個(gè)參數(shù)合并在一起
第一個(gè)用途可能是你將會(huì)使用的最多的。所以我們先來(lái)看他。
let a = [3, 4, 5]; let b = [1, 2, ...a, 6]; console.log(b); // [1, 2, 3, 4, 5, 6]
如果我們想把一個(gè)數(shù)組內(nèi)的一組參數(shù)傳遞給函數(shù),這個(gè)時(shí)候擴(kuò)展運(yùn)算符就十分的有用了。
function foo(a, b, c) { console.log(`a=${a}, b=${b}, c=${c}`) } let data = [5, 15, 2]; foo( ...data); // a=5, b=15, c=2
一個(gè)對(duì)象也可以擴(kuò)展的,它會(huì)把每個(gè)鍵值對(duì)寫入新的對(duì)象中。( 對(duì)象擴(kuò)展已經(jīng)在提議的第四階段,而且將會(huì)在es2018中正式出現(xiàn) 。但這種特性目前只被chrome60及以后的版本,F(xiàn)irefox55及以后,node 6.4.0及以后的版本所支持)【譯者注:在2ality博客中的es2018一文中得知,在剛剛結(jié)束的TC39會(huì)議中,ECMA2018的特性被敲定了。】
let car = { type: "vehicle ", wheels: 4}; let fordGt = { make: "Ford", ...car, model: "GT"}; console.log(fordGt); // {make: "Ford", model: "GT", type: "vehicle", wheels: 4}
擴(kuò)展運(yùn)算符的另一個(gè)特點(diǎn)是,他可以生成一個(gè)新的數(shù)組或者對(duì)象. 下面的這個(gè)例子,就是b就是新建的數(shù)組,但c只是引用同一個(gè)數(shù)組。
let a = [1, 2, 3]; let b = [ ...a ]; let c = a; b.push(4); console.log(a); // [1, 2, 3] console.log(b); // [1, 2, 3, 4] 不同的數(shù)組 c.push(5); console.log(a); // [1, 2, 3, 5] console.log(c); // [1, 2, 3, 5] 同一個(gè)數(shù)組
第二個(gè)用法是把變量聚集到一個(gè)數(shù)組里面。當(dāng)你不知道一個(gè)函數(shù)到底有多少的傳參的時(shí)候會(huì)這個(gè)方法會(huì)變得非常的有用。
function foo(...args) { console.log(args); } foo( "car", 54, "tree"); // [ "car", 54, "tree" ]Default Parameter 參數(shù)默認(rèn)值
函數(shù)現(xiàn)在可以使用默認(rèn)的參數(shù)值來(lái)定義了。不傳參或者未定義值都被初始化為默認(rèn)值。但是需要注意的是,null和false都會(huì)被強(qiáng)轉(zhuǎn)為0.
function foo( a = 5, b = 10) { console.log( a + b); } foo(); // 15 foo( 7, 12 ); // 19 foo( undefined, 8 ); // 13 foo( 8 ); // 18 foo( null ); // 10 as null is coerced to 0
默認(rèn)值的類型可以不僅僅是值類型---還可以是表達(dá)式或者函數(shù)。
function foo( a ) { return a * 4; } function bar( x = 2, y = x + 4, z = foo(x)) { console.log([ x, y, z ]); } bar(); // [ 2, 6, 8 ] bar( 1, 2, 3 ); //[ 1, 2, 3 ] bar( 10, undefined, 3 ); // [ 10, 14, 3 ]Destructuring解構(gòu)
解構(gòu)是拆開等號(hào)左邊的數(shù)組或者對(duì)象的過(guò)程。這個(gè)數(shù)組或者對(duì)象可以來(lái)自一個(gè)變量,一個(gè)函數(shù),或者一個(gè)等式
let [ a, b, c ] = [ 6, 2, 9]; console.log(`a=${a}, b=${b}, c=${c}`); //a=6, b=2, c=9 function foo() { return ["car", "dog", 6 ]; } let [ x, y, z ] = foo(); console.log(`x=${x}, y=${y}, z=${z}`); // x=car, y=dog, z=6
對(duì)象類型的結(jié)構(gòu),可以在花括號(hào)內(nèi)列出對(duì)象的鍵來(lái)提取鍵值對(duì)。
function bar() { return {a: 1, b: 2, c: 3}; } let { a, c } = bar(); console.log(a); // 1 console.log(c); // 3 console.log(b); // undefined
有時(shí),你可能想提取出值然后費(fèi)賠給新的變量,這個(gè)可以通過(guò)在等號(hào)左側(cè)使用一個(gè)“key:variable”(鍵:變量名)來(lái)完成。
function baz() { return { x: "car", y: "London", z: { name: "John", age: 21} }; } let { x: vehicle, y: city, z: { name: driver } } = baz(); console.log( `I"m going to ${city} with ${driver} in their ${vehicle}.` ); // I"m going to London with John in their car.
此外,對(duì)象的結(jié)構(gòu)允許給多個(gè)變量賦值。
let { x: first, x: second } = { x: 4 }; console.log( first, second ); // 4, 4對(duì)象字面量和屬性的簡(jiǎn)潔表達(dá)法
當(dāng)你從許多參數(shù)創(chuàng)建對(duì)象字面量的時(shí)候,ES6允許你在鍵與變量名字相同的情況下省略該鍵。
let a = 4, b = 7; let c = { a: a, b: b }; let concise = { a, b }; console.log(c, concise) // {a: 4, b: 7}, {a: 4, b: 7}
這個(gè)還可以與解構(gòu)一起用來(lái)使你的代碼更干凈整潔。
function foo() { return { name: "Anna", age: 56, job: { company: "Tesco", title: "Manager" } }; } // pre ES6 let a = foo(), name = a.name, age = a.age, company = a.job.company; // ES6 destructuring and concise parameters let { name, age, job: {company}} = foo();
簡(jiǎn)潔表示法還可以用于解構(gòu)對(duì)象并把它傳入函數(shù)。方法1和2是你在es6之前要怎么做, 方法三是使用解構(gòu)和簡(jiǎn)潔表達(dá)法。
let person = { name: "Anna", age: 56, job: { company: "Tesco", title: "Manager" } }; // method 1 function old1( person) { var yearOfBirth = 2018 - person.age; console.log( `${ person.name } works at ${ person.job.company } and was born in ${ yearOfBirth }.`); } // method 2 function old1( person) { var age = person.age, yearOfBirth = 2018 - age, name = person.name, company = person.job.company; console.log( `${ name } works at ${ company } and was born in ${ yearOfBirth }.`); } // method 3 function es6({ age, name, job: {company}}) { var yearOfBirth = 2018 - age; console.log( `${ name } works at ${ company } and was born in ${ yearOfBirth }.`); }
通過(guò)使用ES6,我們能提取出age,name,和 company,而不需要任何其他的變量聲明。
動(dòng)態(tài)屬性名稱ES6添加了使用動(dòng)態(tài)分配的鍵創(chuàng)建或添加屬性的功能。
let city= "sheffield_"; let a = { [ city + "population" ]: 350000 }; a[ city + "county" ] = "South Yorkshire"; console.log(a); // {sheffield_population: 350000, sheffield_county: "South Yorkshire" }箭頭函數(shù)
箭頭函數(shù)有兩個(gè)比較重要的特點(diǎn): 他們的結(jié)構(gòu)以及他們的this 指向
他們比傳統(tǒng)的函數(shù)有更簡(jiǎn)單的結(jié)構(gòu)因?yàn)樗麄儾恍枰P(guān)鍵字function 而且他們可以自動(dòng)返回在箭頭后面的一部分,無(wú)論箭頭后面的是什么。
var foo = function( a, b ) { return a * b; } let bar = ( a, b ) => a * b;
如果函數(shù)有多于一個(gè)的計(jì)算式,可以使用花括號(hào)來(lái)包起來(lái),然后函數(shù)返回塊作用域返回的任何內(nèi)容。
箭頭函數(shù)一個(gè)最重要的用途之一就是應(yīng)用在數(shù)組的相關(guān)函數(shù)中,像.map,.forEach,.sort等等。
let arr = [ 5, 6, 7, 8, "a" ]; let b = arr.map( item => item + 3 ); console.log(b); // [ 8, 9, 10, 11, "a3" ]
在擁有一個(gè)更短的表達(dá)方式的同時(shí),箭頭函數(shù)還修復(fù)了有關(guān)于this綁定行為經(jīng)常出現(xiàn)的問(wèn)題。ES6之前解決這個(gè)問(wèn)題通常是使用一個(gè)self變量來(lái)存儲(chǔ)這個(gè)指向。
var clickController = { doSomething: function (..) { var self = this; btn.addEventListener( "click", function() { self.doSomething(..) }, False ); } };
這個(gè)this的賦值是一定要做的,因?yàn)閠his的綁定是動(dòng)態(tài)的。這就意味著this在eventlistener內(nèi)部和在doSomething內(nèi)部指的并不是同一個(gè)東西。
在箭頭函數(shù)內(nèi)部,this的綁定是語(yǔ)義上的就是指當(dāng)前的,而不是動(dòng)態(tài)的。這也是箭頭函數(shù)的主要設(shè)計(jì)特點(diǎn)。
雖然這種詞法上的this很棒,但是有些時(shí)候,他卻不是我們想要的那樣。
let a = { oneThing: ( a ) => { let b = a * 2; this.otherThing(b); }, otherThing: ( b ) => {....} }; a.oneThing(6);
當(dāng)我們使用a.oneThing(6), 這個(gè)this.otherThing(6) 會(huì)拋出引用失敗的錯(cuò)誤,因?yàn)?b>this沒有指向?qū)ο?b>a,而是指向了環(huán)境作用域。如果你正在使用ES6的代碼使用ES6的語(yǔ)法,這個(gè)是你需要注意的事情。
for...of loops (for...of循環(huán))ES6新添加了一種方式來(lái)迭代數(shù)組中的每個(gè)值,這個(gè)方式是與已經(jīng)存在的for...in的通過(guò)索引的循環(huán)方式不同。
let a = ["a", "b", "c", "d" ]; // ES6 for ( var val of a ) { console.log( val ); } // "a" "b" "c" "d" // pre-ES6 for ( var idx in a ) { console.log( idx ); } // 0 1 2 3
使用新的for ... of循環(huán),在每個(gè)循環(huán)內(nèi)部保存了一個(gè)let val = a[idx]。
數(shù)組,字符串,generator以及從collection 在標(biāo)準(zhǔn)JavaScript中都是可迭代的。普通的對(duì)象無(wú)法正常的使用for...of來(lái)迭代,除非你自己定義一個(gè)迭代器。
Number Literals 數(shù)字字面量ES5代碼很好處理了十進(jìn)制和十六進(jìn)制的數(shù)字格式,但并未指定八進(jìn)制的格式。實(shí)際上,八進(jìn)制在嚴(yán)格模式中是被禁止使用的。
ES6 添加了一個(gè)全新的格式,在最開始的0后面添加一個(gè)o來(lái)聲明一個(gè)八進(jìn)制的數(shù)。與此同時(shí),在es6中還添加了二進(jìn)制格式。
Number( 29 ) // 29 Number( 035 ) // 35 in old octal form. Number( 0o35 ) // 29 in new octal form Number( 0x1d ) // 29 in hexadecimal Number( 0b11101 ) // 29 in binary form更多
ES6還提供了我們很多很多其他的方式來(lái)使我們的代碼更簡(jiǎn)潔,更易讀,以及更穩(wěn)定。我的目標(biāo)時(shí)寫一篇這篇文章的延續(xù),來(lái)包括一些ES6中不太知名的部分。
如果你已經(jīng)等不及了,可以讀一讀Kyle Simpson的YOU DONT KNOW JAVASCRIPT ON ES6,或者看一下這個(gè)超贊的小網(wǎng)站
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/107386.html
摘要:模板字符串?dāng)U展操作符操作符,有兩個(gè)主要用處復(fù)制一個(gè)新的數(shù)組或?qū)ο蟀讯鄠€(gè)參數(shù)賦值給一個(gè)數(shù)組變量把一個(gè)數(shù)組變量賦值給多個(gè)參數(shù)是一個(gè)新的數(shù)組,內(nèi)容和一樣合并對(duì)象屬性,后邊的屬性會(huì)覆蓋前邊的,可用于修改對(duì)象的某個(gè)屬性值輸出默認(rèn)參數(shù)給方法添加默認(rèn)參 模板字符串 let name = siri, age = 18, job = front-end engineer let oldStr = Hi,...
摘要:概述在代碼整潔之道中提到的軟件工程原則,同樣適用于。我們?cè)谲浖こ谭矫娴募夹g(shù)發(fā)展剛剛超過(guò)年,我們?nèi)匀辉趯W(xué)習(xí)很多東西。不好好一個(gè)函數(shù)只做一件事目前這是軟件工程中最重要的原則。 概述 showImg(https://segmentfault.com/img/remote/1460000008066597?w=500&h=471); Robert C. Martin 在《代碼整潔之道》 中提...
摘要:之所以寫這篇文章,就是為了告訴你如何寫出干凈整潔的代碼,能夠讓你的網(wǎng)頁(yè)在許多設(shè)備上都能快速正常的加載運(yùn)行。在這個(gè)過(guò)程中,你能夠?qū)W會(huì)如何搭建易于維護(hù)和的網(wǎng)站以及。無(wú)論如何,盡量避免同時(shí)在和,或者和添加。 個(gè)人翻譯,歡迎轉(zhuǎn)載! 英文原文:https://samdutton.wordpress.com/2015/04/02/high-performance-html/ 第一次翻...
摘要:之所以寫這篇文章,就是為了告訴你如何寫出干凈整潔的代碼,能夠讓你的網(wǎng)頁(yè)在許多設(shè)備上都能快速正常的加載運(yùn)行。在這個(gè)過(guò)程中,你能夠?qū)W會(huì)如何搭建易于維護(hù)和的網(wǎng)站以及。無(wú)論如何,盡量避免同時(shí)在和,或者和添加。 個(gè)人翻譯,歡迎轉(zhuǎn)載! 英文原文:https://samdutton.wordpress.com/2015/04/02/high-performance-html/ 第一次翻...
閱讀 2269·2021-11-23 09:51
閱讀 5656·2021-09-22 15:39
閱讀 3343·2021-09-02 15:15
閱讀 3492·2019-08-30 15:54
閱讀 2354·2019-08-30 15:53
閱讀 1397·2019-08-30 14:04
閱讀 2445·2019-08-29 18:33
閱讀 2364·2019-08-29 13:08