本のRobert C Martin Codeのソフトウェアエンジニアリングの原則は、JavaScriptで条件付けされています。これはスタイルの方法ではありません。これは、読みやすいプログラムの制作ガイドであり、Javaスクリプトで再利用可能で再作成されています。
ここのすべての原則に正確に従わなければならないわけではなく、それよりもさらに少ないものがグローバルに合意されるわけではありません。これらはガイドラインではありませんが、クリーンコード_による長年の集団経験のガイドラインです。
ソフトウェアエンジニアリングの生涯は50年以上であり、私たちはまだ多くのことを学んでいます。 「ソフトウェアエンジニアリングが古い場合、それ自体がエンジニアリングがあります」と、おそらくより困難なルールを守る必要があります。ここで、これらのガイドラインが、あなたとあなたのチームが作成するJavaScriptコードの品質を評価するためのテストとして機能します。
別のことは、これらの原則を知ることで、あなたを史上最高のプログラマーにすることはできません。長年にわたって彼らと協力しても、間違いを犯さないという意味ではありません。コードの各部分は、常に欠陥を削除するため、最初の光景から最終的な形状を得ることのない湿った粘土の作業など、最初のドラフトとして始まります。仲間と一緒にレビューします。したがって、改善が必要な最初のドラフトのために、自分自身を押さないでください。代わりにコードを克服してください!
悪い:
const yyyymmdstr = moment ( ) . format ( "YYYY/MM/DD" )良い:
const currentDate = moment ( ) . format ( "YYYY/MM/DD" )sop頂上に戻ります
悪い:
getUserInfo ( )
getClientData ( )
getCustomerRecord ( )良い:
getUser ( )sop頂上に戻ります
書く以上のコードを読みます。私たちが書くコードが読みやすく、調査することが重要です。私たちのプログラムを理解するために意味のある変数に名前を付けることではなく、読者にとってそれを困難にします。あなたの名前を検索させてください。 Buddy.jsやEslintなどのツールは、名前のない定数を決定するのに役立ちます。
悪い:
// What the heck is 86400000 for?
setTimeout ( blastOff , 86400000 )良い:
// Declare them as capitalized named constants.
const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000 //86400000;
setTimeout ( blastOff , MILLISECONDS_PER_DAY )sop頂上に戻ります
悪い:
const address = "One Infinite Loop, Cupertino 95014"
const cityZipCodeRegex = / ^[^,\]+[,\s]+(.+?)s*(d{5})?$ /
saveCityZipCode (
address . match ( cityZipCodeRegex ) [ 1 ] ,
address . match ( cityZipCodeRegex ) [ 2 ]
)良い:
const address = "One Infinite Loop, Cupertino 95014"
const cityZipCodeRegex = / ^[^,\]+[,\s]+(.+?)s*(d{5})?$ /
const [ _ , city , zipCode ] = address . match ( cityZipCodeRegex ) || [ ]
saveCityZipCode ( city , zipCode )sop頂上に戻ります
暗黙的よりも常に明確です。
悪い:
const locations = [ "Austin" , "New York" , "San Francisco" ]
locations . forEach ( ( l ) => {
doStuff ( )
doSomeOtherStuff ( )
// ...
// ...
// ...
// Wait, what is `l` for again?
dispatch ( l )
} )良い:
const locations = [ "Austin" , "New York" , "San Francisco" ]
locations . forEach ( ( location ) => {
doStuff ( )
doSomeOtherStuff ( )
// ...
// ...
// ...
dispatch ( location )
} )sop頂上に戻ります
名前クラス/オブジェクトが何かを教えてくれる場合は、変数名でこれを繰り返さないでください。
悪い:
const Car = {
carMake : "Honda" ,
carModel : "Accord" ,
carColor : "Blue" ,
}
function paintCar ( car , color ) {
car . carColor = color
}良い:
const Car = {
make : "Honda" ,
model : "Accord" ,
color : "Blue" ,
}
function paintCar ( car , color ) {
car . color = color
}sop頂上に戻ります
デフォルトの引数はオフラインのものです。あなたが彼らを私たちにするならば、あなたの関数はundefined引数のデフォルト値のみを提供することになります。他の「falsy」値はsu '' 、 "" false 、 null 、 0 、およびNaNは、デフォルト値によって腹を立てません。
悪い:
function createMicrobrewery ( name ) {
const breweryName = name || "Hipster Brew Co."
// ...
}良い:
function createMicrobrewery ( name = "Hipster Brew Co." ) {
// ...
}sop頂上に戻ります
ES5クラスの典型的な定義を構築して構築するために、読書クラスの相続財産を取得することは非常に困難です。遺伝が必要な場合(そして、必要ではないかもしれないことに注意してください)、ES2015/ES6クラスを好むでしょう。ただし、クラスの小さな機能を維持するようにしてください。そうすれば、より大きくて複雑な必要があることがわかります。
悪い:
const Animal = function ( age ) {
if ( ! ( this instanceof Animal ) ) {
throw new Error ( "Instantiate Animal with `new`" )
}
this . age = age
}
Animal . prototype . move = function move ( ) { }
const Mammal = function ( age , furColor ) {
if ( ! ( this instanceof Mammal ) ) {
throw new Error ( "Instantiate Mammal with `new`" )
}
Animal . call ( this , age )
this . furColor = furColor
}
Mammal . prototype = Object . create ( Animal . prototype )
Mammal . prototype . constructor = Mammal
Mammal . prototype . liveBirth = function liveBirth ( ) { }
const Human = function ( age , furColor , languageSpoken ) {
if ( ! ( this instanceof Human ) ) {
throw new Error ( "Instantiate Human with `new`" )
}
Mammal . call ( this , age , furColor )
this . languageSpoken = languageSpoken
}
Human . prototype = Object . create ( Mammal . prototype )
Human . prototype . constructor = Human
Human . prototype . speak = function speak ( ) { }良い:
class Animal {
constructor ( age ) {
this . age = age
}
move ( ) {
/* ... */
}
}
class Mammal extends Animal {
constructor ( age , furColor ) {
super ( age )
this . furColor = furColor
}
liveBirth ( ) {
/* ... */
}
}
class Human extends Mammal {
constructor ( age , furColor , languageSpoken ) {
super ( age , furColor )
this . languageSpoken = languageSpoken
}
speak ( ) {
/* ... */
}
}sop頂上に戻ります
このスタイルはJavaスクリプトで非常に便利であり、JqueyやLodashのような多くのライブラリで見ています。これにより、コードを表現でき、ゴシップが最も少なくなります。このため、シーケンスメソッドを使用して、コードがどれだけきれいかを見てみましょう。クラス機能では、各関数の最後にこれを返すだけで、追加のクラスメソッドを接続できます。
悪い:
class Car {
constructor ( make , model , color ) {
this . make = make
this . model = model
this . color = color
}
setMake ( make ) {
this . make = make
}
setModel ( model ) {
this . model = model
}
setColor ( color ) {
this . color = color
}
save ( ) {
console . log ( this . make , this . model , this . color )
}
}
const car = new Car ( "Ford" , "F-150" , "red" )
car . setColor ( "pink" )
car . save ( )良い:
class Car {
constructor ( make , model , color ) {
this . make = make
this . model = model
this . color = color
}
setMake ( make ) {
this . make = make
// NOTE: Returning this for chaining
return this
}
setModel ( model ) {
this . model = model
// NOTE: Returning this for chaining
return this
}
setColor ( color ) {
this . color = color
// NOTE: Returning this for chaining
return this
}
save ( ) {
console . log ( this . make , this . model , this . color )
// NOTE: Returning this for chaining
return this
}
}
const car = new Car ( "Ford" , "F-150" , "red" ) . setColor ( "pink" ) . save ( )sop頂上に戻ります
[デザインパターン](https://en.wikipedia.org/wiki/design_patterns)に記載されているように、ギャングオブフォーは、できる限り継承よりも構成を好むべきです。継承を使用するには、顔には多くの原因があり、構成の使用の顔の多くがあります。この原則の主なポイントは、あなたの心が相続のために設置された場合、構成があなたの問題をより良く解決できるかどうかを考えるようにしてください。場合によってはそれができます。
この後、「いつ継承するべきか」と疑問に思うかもしれません。これはあなたが解決したい問題に依存しますが、これは継承が構成よりも論理的である場合に適切なリストです。
あなたの継承は関係であり、「ではない」関係(「人間 - >動物の反対のユーザー - >ユーザーの詳細)があります。
基本クラスからコードを再利用できます(人間はすべての動物のように動くことができます)。
基本クラスを変更することにより、派生クラスに一般的な変更を加えたいと考えています。 (すべての動物が動くときにカロリーを変更します)。
悪い:
class Employee {
constructor ( name , email ) {
this . name = name
this . email = email
}
// ...
}
// Bad because Employees "have" tax data. EmployeeTaxData is not a type of Employee
class EmployeeTaxData extends Employee {
constructor ( ssn , salary ) {
super ( )
this . ssn = ssn
this . salary = salary
}
// ...
}良い:
class EmployeeTaxData {
constructor ( ssn , salary ) {
this . ssn = ssn
this . salary = salary
}
// ...
}
class Employee {
constructor ( name , email ) {
this . name = name
this . email = email
}
setTaxData ( ssn , salary ) {
this . taxData = new EmployeeTaxData ( ssn , salary )
}
// ...
}sop頂上に戻ります