JavaScriptずTypeScript知っおおくべき11のコンパクトな構成

クリヌンで効率的なコヌドず、䜜成者だけが理解できるコヌドの間には、非垞に现かい線がありたす。そしお最悪の郚分は、この線を明確に定矩するこずが䞍可胜であるずいうこずです。それを探しおいる䞀郚のプログラマヌは、他のプログラマヌよりもはるかに先に進む準備ができおいたす。したがっお、すべおの人に理解されるこずが保蚌されるような方法で特定のコヌドを䜜成する必芁がある堎合、そのようなコヌドでは通垞、3倀挔算子や1行矢印関数などのあらゆる皮類のコンパクトな構造を䜿甚しないようにしたす。



しかし、真実、䞍快な真実は、これらのコンパクトなデザむンがしばしば非垞に圹立぀ずいうこずです。そしお、それらは同時に、非垞に単玔です。これは、それらが䜿甚されるコヌドに興味がある人は誰でもそれらを習埗し、そのようなコヌドを理解できるこずを意味したす。







この投皿では、JavaScriptやTypeScriptに芋られる、非垞に䟿利な堎合によっおは䞍可解なコンパクトな構造をいく぀か芋おいきたす。それらを研究した埌、あなたはそれらを自分で䜿うこずができたす、あるいは少なくずもあなたはそれらを䜿うそれらのプログラマヌのコヌドを理解するこずができたす。



1.オペレヌタヌ??



倀をチェックするためのオペレヌタnullずundefinednullish合䜓挔算子は2぀の疑問笊のように芋えたす??。このような名前のこれが最も人気のあるオペレヌタヌであるずは信じがたいです。本圓ですか



この挔算子の意味は、巊偎のオペランドの倀がnullたたはに等しい堎合、右偎のオペランドの倀を返すこずですundefined。これはその名前にはっきりず反映されおいたせんが、たあ、それは䜕ですか䜿甚方法は次のずおりです。



function myFn(variable1, variable2) {
  let var2 = variable2 ?? "default value"
  return variable1 + var2
}

myFn("this has ", "no default value") // "this has no default value"
myFn("this has no ") // "this has no default value"
myFn("this has no ", 0) // "this has no 0"


ここには、オペレヌタヌの䜜業を敎理するために䜿甚されるメカニズムず非垞によく䌌たメカニズムが含たれおいたす||。匏の巊偎がnullたたはundefinedに等しい堎合、匏の右偎が返されたす。それ以倖の堎合は、巊偎が返されたす。その結果、挔算子は??倉数に䜕かを割り圓おるこずができる状況での䜿甚に最適ですが、nullたたはこの倉数に該圓する堎合は、いく぀かの察策を講じる必芁がありたすundefined。



2.挔算子?? =



倉数に倀を割り圓おるために䜿甚される挔算子は、倀がある堎合、nullたたはundefined論理ヌルの割り圓お挔算子2぀の疑問笊の埌に等しい蚘号??=が続くように芋える堎合にのみ䜿甚されたす。䞊蚘の挔算子の拡匵ず考えおください??。



を䜿甚しお曞き盎された前のコヌドスニペットを芋おみたしょう??=。



function myFn(variable1, variable2) {
  variable2 ??= "default value"
  return variable1 + variable2
}

myFn("this has ", "no default value") // "this has no default value"
myFn("this has no ") // "this has no default value"
myFn("this has no ", 0) // "this has no 0"


挔算子を??=䜿甚するず、関数パラメヌタの倀を確認できたすvariable2。に等しいnullかundefined、の堎合、新しい倀が曞き蟌たれたす。それ以倖の堎合、パラメヌタヌ倀は倉曎されたせん。



デザむンに??=慣れおいない人には、デザむンが理解できないように芋える堎合があるこずに泚意しおください。したがっお、これを䜿甚する堎合は、コヌドの適切な堎所に説明付きの短い解説を远加するこずをお勧めしたす。



3.TypeScriptコンストラクタヌの省略された宣蚀



この機胜はTypeScriptに固有です。したがっお、JavaScriptの玔粋さの擁護者である堎合、倚くのこずを芋逃しおいたす。 もちろん冗談ですが、これは通垞のJSには圓おはたりたせん。



ご存知のように、クラスを宣蚀するずきは、通垞、アクセス修食子を䜿甚しおすべおのプロパティを䞀芧衚瀺し、クラスコンストラクタヌでこれらのプロパティに倀を割り圓おたす。ただし、コンストラクタヌが非垞に単玔で、コンストラクタヌに枡されたパラメヌタヌの倀がプロパティに単玔に曞き蟌たれる堎合は、通垞よりもコンパクトな構造を䜿甚できたす。



これはそれがどのように芋えるかです



// ...
class Person {
  
  private first_name: string;
  private last_name: string;
  private age: number;
  private is_married: boolean;
  
  constructor(fname:string, lname:string, age:number, married:boolean) {
    this.first_name = fname;
    this.last_name = lname;
    this.age = age;
    this.is_married = married;
  }
}

// ,   ...
class Person {

  constructor( private first_name: string,
               private last_name: string,
               private age: number,
               private is_married: boolean){}
}


コンストラクタヌを䜜成するずきに䞊蚘のアプロヌチを䜿甚するず、時間を節玄できたす。特に、倚くのプロパティを持぀クラスになるず。



ここで重芁なこず{}は、コンストラクタヌの説明の盎埌に远加するこずを忘れないでください。これは関数本䜓の衚珟であるためです。コンパむラはそのような蚘述に遭遇した埌、すべおを理解し、残りはそれ自䜓で行いたす。実際、TSコヌドの最初ず2番目のフラグメントの䞡方が最終的に同じJavaScriptコヌドに倉換されるずいう事実に぀いお話しおいたす。



4.䞉元挔算子



䞉元挔算子は、読みやすい構造です。この挔算子はif
else、䜙分な文字を取り陀き、耇数行の構成を1行の構成に倉えるこずができるため、短い呜什の代わりによく䜿甚されたす。



//   if
else
let isEven = ""
if(variable % 2 == 0) {
  isEven = "yes"
} else {
  isEven = "no"
}

//  
let isEven = (variable % 2 == 0) ? "yes" : "no"


䞉元挔算子の構造では、最初は論理匏、2番目はreturn論理匏が真のreturn堎合に倀を返すコマンドのようなもの、3番目も論理匏が停の堎合に倀を返すコマンドのようなものです。䞉元挔算子は䟋のように倀の割り圓おの右偎で最もよく䜿甚されたすが、どの関数が呌び出されるか、たたはどの匕数で同じものが呌び出されるかを関数を呌び出すメカニズムずしお、自埋的に䜿甚するこずもできたす。同じ関数は、論理匏の倀によっお決定されたす。これはそれがどのように芋えるかです



let variable = true;

(variable) ? console.log("It's TRUE") : console.log("It's FALSE")


ステヌトメントの構造は前の䟋ず同じに芋えるこずに泚意しおください。䞉元挔算子を䜿甚するこずの欠点は、将来、その郚分の1぀論理匏の真の倀を参照する郚分、たたはその停の倀を参照する郚分を拡匵する必芁がある堎合、通垞の呜什に進む必芁があるこずを意味したすif
else。



5.オペレヌタヌが䜿甚する短い蚈算サむクルを䜿甚する||



JavaScriptおよびTypeScriptでもでは、論理OR挔算子||は簡略蚈算モデルを実装したす。぀たり、ずしお評䟡された最初の匏を返しtrue、残りの匏はチェックしたせん。



次の文がある堎合、この手段は、ずいうif衚珟は、expression1停の倀に還元が含たれおいるfalse、およびexpression2-真に還元true、のみexpression1ず蚈算されたすexpression2。匏espression3ずexpression4は評䟡されたせん。



if( expression1 || expression2 || expression3 || expression4)


if倉数に倀を割り圓おる ステヌトメントの倖で、この機䌚を利甚できたす。これにより、特に、関数パラメヌタで衚される倀などがfalseであるこずが刀明した堎合たずえば、equal undefinedに、デフォルト倀を倉数に曞き蟌むこずができたす。



function myFn(variable1, variable2) {
  let var2 = variable2 || "default value"
  return variable1 + var2
}

myFn("this has ", " no default value") // "this has no default value"
myFn("this has no ") // "this has no default value"


この䟋は、挔算子||を䜿甚しお、関数の2番目のパラメヌタヌの倀たたはデフォルト倀のいずれかを倉数に曞き蟌む方法を瀺しおいたす。ただし、この䟋をよく芋るず、小さな問題がありたす。実際にはvariable2、0たたは空の文字列にvar2倀がある堎合、0ず空の文字列の䞡方がに倉換されるため、デフォルト倀が曞き蟌たれたすfalse。



したがっお、すべおのfalse倀をデフォルト倀に眮き換える必芁がない堎合は、あたり知られおいない挔算子を䜿甚できたす??。



6.ダブルビットワむズ挔算子〜



JavaScript開発者は通垞、ビット単䜍の挔算子の䜿甚に特に熱心ではありたせん。最近、数字のバむナリ衚珟を気にするのは誰ですかただし、これらの挔算子はビットレベルで動䜜するため、察応するアクションを、たずえば䞀郚のメ゜ッドよりもはるかに高速に実行したす。



ビット単䜍の挔算子NOT~に぀いお説明するず、数倀を取り、それを32ビットの敎数に倉換しお「䜙分な」ビットを砎棄し、この数倀のビットを反転したす。これにより、倀が倀にx倉換されたす-(x+1)。なぜ私たちはそのような数字の倉換に興味があるのですかたた、2回䜿甚するず、メ゜ッド呌び出しず同じ結果が埗られるずいう事実Math.floor。



let x = 3.8
let y = ~x // x   -(3 + 1),    ,    
let z = ~y //  y ( -4)  -(-4 + 1)   -  3

//   :

let flooredX = ~~x //      


~䟋の最埌の行に ある2぀のアむコンに泚目しおください。奇劙に芋えるかもしれたせんが、倚くの浮動小数点数を敎数に倉換する必芁がある堎合、この手法は非垞に䟿利です。



7.オブゞェクトのプロパティに倀を割り圓おる



ES6暙準の機胜により、オブゞェクトを䜜成するプロセス、特に、オブゞェクトのプロパティに倀を割り圓おるプロセスが簡玠化されたす。これらのプロパティず同じ名前の倉数に基づいおプロパティ倀が割り圓おられおいる堎合、それらの名前を繰り返す必芁はありたせん。以前は必芁でした。



TypeScriptで蚘述された䟋を次に瀺したす。



let name:string = "Fernando";
let age:number = 36;
let id:number = 1;

type User = {
  name: string,
  age: number,
  id: number
}

// 
let myUser: User = {
  name: name,
  age: age,
  id: id
}

// 
let myNewUser: User = {
  name,
  age,
  id
}


ご芧のずおり、オブゞェクトプロパティに倀を割り圓おる新しいアプロヌチにより、よりコンパクトでシンプルなコヌドを蚘述できたす。そしお、そのようなコヌドは、叀い芏則に埓っお曞かれたコヌドこの蚘事で説明されおいる他のコンパクトな構造を䜿甚しお曞かれたコヌドに぀いおは蚀えたせんよりも読むのが難しくありたせん。



8.矢印関数からの倀の暗黙的な戻り



単䞀行の矢印関数が、単䞀行で実行された蚈算の結果を返すこずをご存知ですか



このメカニズムを䜿甚するず、䞍芁な匏を取り陀くこずができたすreturn。この手法は、filterやなどの配列メ゜ッドに枡される矢印関数でよく䜿甚されmapたす。TypeScriptの䟋を次に瀺したす。



let myArr:number[] = [1,2,3,4,5,6,7,8,9,10]

//  :
let oddNumbers:number[] = myArr.filter( (n:number) => {
  return n % 2 == 0
})

let double:number[] = myArr.map( (n:number) => {
  return n * 2;
})

//  :
let oddNumbers2:number[] = myArr.filter( (n:number) => n % 2 == 0 )

let double2:number[] = myArr.map( (n:number) =>  n * 2 )


この手法を適甚するこずは、必ずしもコヌドをより耇雑にするこずを意味するわけではありたせん。このような構成は、コヌドを少しクリヌンアップしお、䞍芁なスペヌスや䜙分な行を取り陀くための良い方法です。もちろん、このアプロヌチの欠点は、そのような短い関数の本䜓を拡匵する必芁がある堎合、再び䞭括匧の䜿甚に戻らなければならないこずです。



ここで考慮しなければならない唯䞀の特城は、ここで考慮される短い矢印関数の唯䞀の行に含たれおいるのは匏でなければならないずいうこずです぀たり、関数から返される結果を生成する必芁がありたす。そうしないず、そのような蚭蚈は機胜しなくなりたす。たずえば、䞊蚘の1行の関数は次のように蚘述できたせん。



const m = _ => if(2) console.log("true"else console.log("false")


次のセクションでは、匕き続き1行の矢印関数に぀いお説明したすが、次に、䞭括匧なしでは䜜成できない関数に぀いお説明したす。



9.デフォルト倀を持぀こずができる関数パラメヌタヌ



ES6では、デフォルトの機胜パラメヌタヌに割り圓おられる倀を指定する機胜が導入されたした。以前は、JavaScriptにはそのような機胜がありたせんでした。したがっお、パラメヌタに同様の倀を割り圓おる必芁がある状況では、削枛された挔算子蚈算のモデルのようなものに頌る必芁がありたした||。



しかし、今では同じ問題を非垞に簡単に解決できたす。



//    2  
//     ,   
function myFunc(a, b, c = 2, d = "") {
  //   ...
}


シンプルなメカニズムですね。しかし、実際には、すべおが䞀芋したずころよりもさらに興味深いものです。重芁なのは、デフォルト倀は、関数呌び出しを含め、䜕でもかたいたせん。この関数は、関数の呌び出し時に察応するパラメヌタヌが枡されない堎合に呌び出されたす。これにより、必芁な関数パラメヌタパタヌンを簡単に実装できたす。



const mandatory = _ => {
  throw new Error("This parameter is mandatory, don't ignore it!")
}

function myFunc(a, b, c = 2, d = mandatory()) {
  //    ...
}

// !
myFunc(1,2,3,4)

// 
myFunc(1,2,3)


ここでは、実際には、䞭括匧なしでは実行できない、䜜成時の同じ1行の矢印関数です。重芁なのは、関数mandatoryが呜什を䜿甚するずいうこずthrowです。泚意しおください-「衚珟」ではなく「指瀺」。しかし、これは、関数に必芁なパラメヌタヌを装備する機胜の最高䟡栌ではないず思いたす。



10。!!を䜿甚しお任意の倀をブヌル型にキャストしたす。



このメカニズムは、䞊蚘の構造ず同じ原理で機胜したす~~。぀たり、任意の倀を論理型にキャストするには、2぀の論理挔算子NOT!!を䜿甚できるずいう事実に぀いお話したす。



!!23 // TRUE
!!"" // FALSE
!!0 // FALSE
!!{} // TRUE


1人のオペレヌタヌが!すでにこのタスクのほずんどを解決しおいたす。぀たり、倀をブヌル型に倉換しおから、反察の倀を返したす。そしお、2番目の挔算子!は起こったこずを受け取り、その反察を返したす。その結果、元の倀がブヌル型に倉換されたす。



この短い構造は、さたざたな状況で圹立ちたす。たず、倉数に実際のブヌル倀が割り圓おられおいるこずを確認する必芁がある堎合たずえば、タむプのTypeScript倉数に぀いお話しおいる堎合boolean。次に、===たたはず䜕かの厳密な比范を䜿甚を実行する必芁があるtrue堎合false。



11.構文の砎壊ず拡散



このセクションのタむトルで蚀及されおいるメカニズムに぀いおは、話し合うこずができたす。重芁なのは、正しく䜿甚すれば、非垞に興味深い結果に぀ながる可胜性があるずいうこずです。しかし、ここではあたり深くは行きたせん。それらを䜿甚しおいく぀かの問題の解決を単玔化する方法を説明したす。



▍砎壊オブゞェクト



オブゞェクトプロパティの耇数の倀を通垞の倉数に曞き蟌むずいう課題に盎面したこずがありたすかこのタスクは非垞に䞀般的です。たずえば、これらの倀を操䜜する必芁がある堎合たずえば、倀を倉曎するこずによっお、同時に元のオブゞェクトに保存されおいるものに圱響を䞎えたせん。



オブゞェクトの非構造化を䜿甚するず、最小限のコヌドを䜿甚しお同様の問題を解決できたす。



const myObj = {
  name: "Fernando",
  age: 37,
  country: "Spain"
}

// :
const name = myObj.name;
const age = myObj.age;
const country = myObj.country;

// 
const {name, age, country} = myObj;


TypeScriptを䜿甚したこずのある人なら誰でも、この構文を説明で芋たこずがあるでしょうimport。これにより、プロゞェクトの名前名を倚くの䞍芁な関数で汚染するこずなく、個々のラむブラリメ゜ッドをむンポヌトできたす。



import { get } from 'lodash'


たずえば、この呜什では、ラむブラリからlodashメ゜ッドのみをむンポヌトできたすget。同時に、このラむブラリの他のメ゜ッドはプロゞェクトの名前名に分類されたせん。そしお、その䞭にはたくさんありたす。



▍構文を広げ、既存のものに基づいお新しいオブゞェクトず配列を䜜成する



Spread 構文を䜿甚するず、既存のものに基づいお新しい配列ずオブゞェクトを䜜成するタスクを簡玠化できたす。これで、このタスクは、文字通り1行のコヌドを蚘述し、特別なメ゜ッドを䜿甚せずに解決できたす。次に䟋を瀺したす。



const arr1 = [1,2,3,4]
const arr2 = [5,6,7]

const finalArr = [...arr1, ...arr2] // [1,2,3,4,5,6,7]

const partialObj1 = {
  name: "fernando"
}
const partialObj2 = {
  age:37
}

const fullObj = { ...partialObj1, ...partialObj2 } // {name: "fernando", age: 37}


このアプロヌチを䜿甚しおオブゞェクトをマヌゞするず、それらのプロパティが同じ名前で䞊曞きされるこずに泚意しおください。これはアレむには適甚されたせん。特に、マヌゞされる配列の倀が同じである堎合、それらはすべお結果の配列になりたす。繰り返しを取り陀く必芁がある堎合は、デヌタ構造を䜿甚するこずに頌るこずができたすSet。



▍砎壊ず拡散構文の組み合わせ



砎棄は、spread構文ず組み合わせお䜿甚​​できたす。これにより、興味深い効果を埗るこずができたす。たずえば、配列の最初の芁玠を削陀し、残りはそのたたにしおおきたすリストの最初ず最埌の芁玠の䞀般的な䟋のように、その実装はPythonや他の蚀語で芋぀けるこずができたす。たた、たずえば、オブゞェクトからいく぀かのプロパティを抜出し、残りはそのたたにしおおくこずもできたす。䟋を考えおみたしょう



const myList = [1,2,3,4,5,6,7]
const myObj = {
  name: "Fernando",
  age: 37,
  country: "Spain",
  gender: "M"
}

const [head, ...tail] = myList

const {name, age, ...others} = myObj

console.log(head) //1
console.log(tail) //[2,3,4,5,6,7]
console.log(name) //Fernando
console.log(age) //37
console.log(others) //{country: "Spain", gender: "M"}


割り圓おステヌトメントの巊偎に䜿甚されおいる3぀のドットは、最埌の項目に適甚する必芁があるこずに泚意しおください。最初にスプレッド構文を䜿甚しおから、個々の倉数を蚘述するこずはできたせん。



const [...values, lastItem] = [1,2,3,4]


このコヌドは機胜したせん。



結果



今日お話ししたものず同様のデザむンが他にもたくさんありたす。しかし、それらを䜿甚するず、コヌドがコンパクトになるほど、䜿甚されおいる省略された構造に慣れおいない人にずっおは読みにくくなるこずを芚えおおく䟡倀がありたす。そしお、そのような構成を䜿甚する目的は、コヌドを瞮小したり、高速化したりするこずではありたせん。この目暙は、コヌドから䞍芁な構造を削陀し、このコヌドを読む人の生掻を楜にするこずだけです。



したがっお、すべおの人を満足させるために、コンパクトな構成ず通垞の読み取り可胜なコヌドの間の健党なバランスを維持するこずをお勧めしたす。コヌドを読んでいるのはあなただけではないこずを垞に芚えおおく䟡倀がありたす。



JavaScriptおよびTypeScriptコヌドで䜿甚するコンパクトな構造は䜕ですか










All Articles