Pendekatan yang sebagian besar masuk akal untuk JavaScript
Catatan : panduan ini mengasumsikan Anda menggunakan Babel, dan mengharuskan Anda menggunakan babel-preset-airbnb atau yang setara. Ini juga mengasumsikan Anda memasang shims/polyfills di aplikasi Anda, dengan airbnb-browser-shims atau yang setara.
Panduan ini juga tersedia dalam bahasa lain. Lihat Terjemahan
Panduan Gaya Lainnya
1.1 Primitif : Saat Anda mengakses tipe primitif, Anda langsung mengerjakan nilainya.
string
number
boolean
null
undefined
symbol
bigint
const foo = 1 ;
let bar = foo ;
bar = 9 ;
console . log ( foo , bar ) ; // => 1, 9
1.2 Kompleks : Saat Anda mengakses tipe kompleks, Anda mengerjakan referensi ke nilainya.
object
array
function
const foo = [ 1 , 2 ] ;
const bar = foo ;
bar [ 0 ] = 9 ;
console . log ( foo [ 0 ] , bar [ 0 ] ) ; // => 9, 9
⬆ kembali ke atas
2.1 Gunakan const
untuk semua referensi Anda; hindari menggunakan var
. eslint: prefer-const
, no-const-assign
Mengapa? Hal ini memastikan bahwa Anda tidak dapat menetapkan ulang referensi Anda, yang dapat menyebabkan bug dan kode yang sulit dipahami.
// bad
var a = 1 ;
var b = 2 ;
// good
const a = 1 ;
const b = 2 ;
2.2 Jika Anda harus menetapkan ulang referensi, gunakan let
sebagai ganti var
. eslint: no-var
Mengapa?
let
memiliki cakupan blok, bukan cakupan fungsi sepertivar
.
// bad
var count = 1 ;
if ( true ) {
count += 1 ;
}
// good, use the let.
let count = 1 ;
if ( true ) {
count += 1 ;
}
2.3 Perhatikan bahwa let
dan const
memiliki cakupan blok, sedangkan var
memiliki cakupan fungsi.
// const and let only exist in the blocks they are defined in.
{
let a = 1 ;
const b = 1 ;
var c = 1 ;
}
console . log ( a ) ; // ReferenceError
console . log ( b ) ; // ReferenceError
console . log ( c ) ; // Prints 1
Pada kode di atas, Anda dapat melihat bahwa mereferensikan a
dan b
akan menghasilkan ReferrorError, sedangkan c
berisi nomor tersebut. Hal ini karena a
dan b
tercakup dalam blok, sedangkan c
tercakup dalam fungsi yang memuatnya.
⬆ kembali ke atas
3.1 Gunakan sintaks literal untuk pembuatan objek. eslint: no-new-object
// bad
const item = new Object ( ) ;
// good
const item = { } ;
3.2 Gunakan nama properti yang dihitung saat membuat objek dengan nama properti dinamis.
Mengapa? Mereka memungkinkan Anda untuk mendefinisikan semua properti suatu objek di satu tempat.
function getKey ( k ) {
return `a key named ${ k } ` ;
}
// bad
const obj = {
id : 5 ,
name : 'San Francisco' ,
} ;
obj [ getKey ( 'enabled' ) ] = true ;
// good
const obj = {
id : 5 ,
name : 'San Francisco' ,
[ getKey ( 'enabled' ) ] : true ,
} ;
3.3 Gunakan singkatan metode objek. eslint: object-shorthand
// bad
const atom = {
value : 1 ,
addValue : function ( value ) {
return atom . value + value ;
} ,
} ;
// good
const atom = {
value : 1 ,
addValue ( value ) {
return atom . value + value ;
} ,
} ;
3.4 Gunakan singkatan nilai properti. eslint: object-shorthand
Mengapa? Ini lebih pendek dan deskriptif.
const lukeSkywalker = 'Luke Skywalker' ;
// bad
const obj = {
lukeSkywalker : lukeSkywalker ,
} ;
// good
const obj = {
lukeSkywalker ,
} ;
3.5 Kelompokkan properti steno Anda di awal deklarasi objek Anda.
Mengapa? Lebih mudah untuk mengetahui properti mana yang menggunakan singkatan.
const anakinSkywalker = 'Anakin Skywalker' ;
const lukeSkywalker = 'Luke Skywalker' ;
// bad
const obj = {
episodeOne : 1 ,
twoJediWalkIntoACantina : 2 ,
lukeSkywalker ,
episodeThree : 3 ,
mayTheFourth : 4 ,
anakinSkywalker ,
} ;
// good
const obj = {
lukeSkywalker ,
anakinSkywalker ,
episodeOne : 1 ,
twoJediWalkIntoACantina : 2 ,
episodeThree : 3 ,
mayTheFourth : 4 ,
} ;
3.6 Hanya properti kutipan yang merupakan pengidentifikasi tidak valid. eslint: quote-props
Mengapa? Secara umum kami menganggapnya lebih mudah dibaca secara subyektif. Ini meningkatkan penyorotan sintaksis, dan juga lebih mudah dioptimalkan oleh banyak mesin JS.
// bad
const bad = {
'foo' : 3 ,
'bar' : 4 ,
'data-blah' : 5 ,
} ;
// good
const good = {
foo : 3 ,
bar : 4 ,
'data-blah' : 5 ,
} ;
3.7 Jangan memanggil metode Object.prototype
secara langsung, seperti hasOwnProperty
, propertyIsEnumerable
, dan isPrototypeOf
. eslint: no-prototype-builtins
Mengapa? Metode ini mungkin dibayangi oleh properti pada objek yang dimaksud - pertimbangkan
{ hasOwnProperty: false }
- atau, objek tersebut mungkin berupa objek null (Object.create(null)
). Di browser modern yang mendukung ES2022, atau dengan polyfill seperti https://npmjs.com/object.hasown,Object.hasOwn
juga dapat digunakan sebagai alternatifObject.prototype.hasOwnProperty.call
.
// bad
console . log ( object . hasOwnProperty ( key ) ) ;
// good
console . log ( Object . prototype . hasOwnProperty . call ( object , key ) ) ;
// better
const has = Object . prototype . hasOwnProperty ; // cache the lookup once, in module scope.
console . log ( has . call ( object , key ) ) ;
// best
console . log ( Object . hasOwn ( object , key ) ) ; // only supported in browsers that support ES2022
/* or */
import has from 'has' ; // https://www.npmjs.com/package/has
console . log ( has ( object , key ) ) ;
/* or */
console . log ( Object . hasOwn ( object , key ) ) ; // https://www.npmjs.com/package/object.hasown
3.8 Lebih memilih sintaks penyebaran objek daripada Object.assign
ke objek salinan dangkal. Gunakan sintaks parameter sisa objek untuk mendapatkan objek baru dengan properti tertentu dihilangkan. eslint: prefer-object-spread
// very bad
const original = { a : 1 , b : 2 } ;
const copy = Object . assign ( original , { c : 3 } ) ; // this mutates `original` ಠ_ಠ
delete copy . a ; // so does this
// bad
const original = { a : 1 , b : 2 } ;
const copy = Object . assign ( { } , original , { c : 3 } ) ; // copy => { a: 1, b: 2, c: 3 }
// good
const original = { a : 1 , b : 2 } ;
const copy = { ... original , c : 3 } ; // copy => { a: 1, b: 2, c: 3 }
const { a , ... noA } = copy ; // noA => { b: 2, c: 3 }
⬆ kembali ke atas
4.1 Gunakan sintaks literal untuk pembuatan array. eslint: no-array-constructor
// bad
const items = new Array ( ) ;
// good
const items = [ ] ;
4.2 Gunakan Array#push alih-alih penugasan langsung untuk menambahkan item ke array.
const someStack = [ ] ;
// bad
someStack [ someStack . length ] = 'abracadabra' ;
// good
someStack . push ( 'abracadabra' ) ;
4.3 Gunakan spread array ...
untuk menyalin array.
// bad
const len = items . length ;
const itemsCopy = [ ] ;
let i ;
for ( i = 0 ; i < len ; i += 1 ) {
itemsCopy [ i ] = items [ i ] ;
}
// good
const itemsCopy = [ ... items ] ;
4.4 Untuk mengonversi objek yang dapat diubah menjadi array, gunakan spread ...
alih-alih Array.from
const foo = document . querySelectorAll ( '.foo' ) ;
// good
const nodes = Array . from ( foo ) ;
// best
const nodes = [ ... foo ] ;
4.5 Gunakan Array.from
untuk mengonversi objek mirip array menjadi array.
const arrLike = { 0 : 'foo' , 1 : 'bar' , 2 : 'baz' , length : 3 } ;
// bad
const arr = Array . prototype . slice . call ( arrLike ) ;
// good
const arr = Array . from ( arrLike ) ;
4.6 Gunakan Array.from
alih-alih spread ...
untuk memetakan iterable, karena ini menghindari pembuatan array perantara.
// bad
const baz = [ ... foo ] . map ( bar ) ;
// good
const baz = Array . from ( foo , bar ) ;
4.7 Gunakan pernyataan return dalam callback metode array. Tidak apa-apa untuk menghilangkan pengembalian jika isi fungsi terdiri dari satu pernyataan yang mengembalikan ekspresi tanpa efek samping, mengikuti 8.2. eslint: array-callback-return
// good
[ 1 , 2 , 3 ] . map ( ( x ) => {
const y = x + 1 ;
return x * y ;
} ) ;
// good
[ 1 , 2 , 3 ] . map ( ( x ) => x + 1 ) ;
// bad - no returned value means `acc` becomes undefined after the first iteration
[ [ 0 , 1 ] , [ 2 , 3 ] , [ 4 , 5 ] ] . reduce ( ( acc , item , index ) => {
const flatten = acc . concat ( item ) ;
} ) ;
// good
[ [ 0 , 1 ] , [ 2 , 3 ] , [ 4 , 5 ] ] . reduce ( ( acc , item , index ) => {
const flatten = acc . concat ( item ) ;
return flatten ;
} ) ;
// bad
inbox . filter ( ( msg ) => {
const { subject , author } = msg ;
if ( subject === 'Mockingbird' ) {
return author === 'Harper Lee' ;
} else {
return false ;
}
} ) ;
// good
inbox . filter ( ( msg ) => {
const { subject , author } = msg ;
if ( subject === 'Mockingbird' ) {
return author === 'Harper Lee' ;
}
return false ;
} ) ;
4.8 Gunakan jeda baris setelah membuka kurung array dan sebelum menutup kurung array, jika array memiliki banyak baris
// bad
const arr = [
[ 0 , 1 ] , [ 2 , 3 ] , [ 4 , 5 ] ,
] ;
const objectInArray = [ {
id : 1 ,
} , {
id : 2 ,
} ] ;
const numberInArray = [
1 , 2 ,
] ;
// good
const arr = [ [ 0 , 1 ] , [ 2 , 3 ] , [ 4 , 5 ] ] ;
const objectInArray = [
{
id : 1 ,
} ,
{
id : 2 ,
} ,
] ;
const numberInArray = [
1 ,
2 ,
] ;
⬆ kembali ke atas
5.1 Gunakan penghancuran objek saat mengakses dan menggunakan beberapa properti suatu objek. eslint: prefer-destructuring
Mengapa? Destrukturisasi menyelamatkan Anda dari pembuatan referensi sementara untuk properti tersebut, dan dari akses berulang terhadap objek. Akses objek yang berulang menciptakan kode yang lebih berulang, membutuhkan lebih banyak pembacaan, dan menciptakan lebih banyak peluang untuk kesalahan. Penghancuran objek juga menyediakan satu situs definisi struktur objek yang digunakan dalam blok, daripada mengharuskan pembacaan keseluruhan blok untuk menentukan apa yang digunakan.
// bad
function getFullName ( user ) {
const firstName = user . firstName ;
const lastName = user . lastName ;
return ` ${ firstName } ${ lastName } ` ;
}
// good
function getFullName ( user ) {
const { firstName , lastName } = user ;
return ` ${ firstName } ${ lastName } ` ;
}
// best
function getFullName ( { firstName , lastName } ) {
return ` ${ firstName } ${ lastName } ` ;
}
5.2 Gunakan penghancuran array. eslint: prefer-destructuring
const arr = [ 1 , 2 , 3 , 4 ] ;
// bad
const first = arr [ 0 ] ;
const second = arr [ 1 ] ;
// good
const [ first , second ] = arr ;
5.3 Gunakan penghancuran objek untuk beberapa nilai kembalian, bukan penghancuran array.
Mengapa? Anda dapat menambahkan properti baru seiring waktu atau mengubah urutannya tanpa merusak situs panggilan.
// bad
function processInput ( input ) {
// then a miracle occurs
return [ left , right , top , bottom ] ;
}
// the caller needs to think about the order of return data
const [ left , __ , top ] = processInput ( input ) ;
// good
function processInput ( input ) {
// then a miracle occurs
return { left , right , top , bottom } ;
}
// the caller selects only the data they need
const { left , top } = processInput ( input ) ;
⬆ kembali ke atas
6.1 Gunakan tanda kutip tunggal ''
untuk string. eslint: quotes
// bad
const name = "Capt. Janeway" ;
// bad - template literals should contain interpolation or newlines
const name = `Capt. Janeway` ;
// good
const name = 'Capt. Janeway' ;
6.2 String yang menyebabkan baris melebihi 100 karakter tidak boleh ditulis dalam beberapa baris menggunakan penggabungan string.
Mengapa? String yang rusak sulit untuk dikerjakan dan membuat kode menjadi kurang mudah dicari.
// bad
const errorMessage = 'This is a super long error that was thrown because
of Batman. When you stop to think about how Batman had anything to do
with this, you would get nowhere
fast.' ;
// bad
const errorMessage = 'This is a super long error that was thrown because ' +
'of Batman. When you stop to think about how Batman had anything to do ' +
'with this, you would get nowhere fast.' ;
// good
const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.' ;
6.3 Saat membuat string secara terprogram, gunakan string templat alih-alih penggabungan. eslint: prefer-template
template-curly-spacing
Mengapa? String templat memberi Anda sintaks yang mudah dibaca dan ringkas dengan baris baru dan fitur interpolasi string yang tepat.
// bad
function sayHi ( name ) {
return 'How are you, ' + name + '?' ;
}
// bad
function sayHi ( name ) {
return [ 'How are you, ' , name , '?' ] . join ( ) ;
}
// bad
function sayHi ( name ) {
return `How are you, ${ name } ?` ;
}
// good
function sayHi ( name ) {
return `How are you, ${ name } ?` ;
}
eval()
pada sebuah string; itu membuka terlalu banyak kerentanan. eslint: no-eval
6.5 Jangan melakukan escape karakter dalam string secara berlebihan. eslint: no-useless-escape
Mengapa? Garis miring terbalik