グーグルのV8チームはこの瞬間を長い間待っていたと思います。 V8エンジン(最も人気のあるJavaScriptエンジン)の8番目のバージョンがリリースされました! この新しいバージョンには、いくつかの非常に優れたパフォーマンスの改善と、オプションの連鎖とnullish合体という2つの新しいクールなJavaScript言語機能が付属しています。

オプションの連鎖

これは待望の機能です。 ひどいAPIプロバイダーを使用しているとしましょう。 このAPIをCrocosAPIと呼びましょう。 CrocosAPIは、世界中のすべてのワニに関する情報を提供します(これは、「ゲーターがクロックスより優れている」ことを誰もが知っている不安定なAPIです)。

これは、ワニの生息地を取得するための私たちの機能です(一部のワニは淡水、汽水、および/または塩水に住んでいます)

const getWaterHabitat = async (crocName) => {
  // First we call our made up api
  const crocResponse = await fetch('http://api.crocosapi.io/croc/' + crocName);
  // We get the responses body
  const crocInfo = crocResponse.body;
  // We access the water property of the habitat property
  return crocInfo.habitat.water;
}

// Let's get the water habitat of a crocodile called Barry
const barrysWaterHabitat = getWaterHabitat('Barry');
// this returnsbarrysWaterHabitat == ['freshwater']

ここで、CrocosAPIの開発者が応答の構造を次のように変更することを決定したとしましょう。

{
  "personalInfo" : {
    "firstName" : "Barry"
  },
  "habitat": {
    "water": ["freshwater"],
  }
  // ... skipping
}

に:

{
  "personalInfo" : {
    "firstName" : "Barry"
    //  ...
  },
  // We changed 'habitat' to 'environment'
  "environment": {
    "water": ["freshwater"]
  }
  //...
}

今私たちが呼び出す場合 getWaterHabitat 私たちは得るだろう:

TypeError: Cannot read property 'water' of undefined

それは crocInfo.habitat もう存在しません。 今すぐアクセスする crocInfo、アクセスする必要があります crocInfo.environment.water. これは、CrocosAPIの開発者がバージョン管理について知らないという理由だけで、アプリ全体がクラッシュすることを意味します。 では、そのエラーを回避する方法は? もちろんオプションのチェーン!

const getWaterHabitat = async (crocName) => {
  const crocResponse = await fetch('http://api.crocosapi.io/croc/' + crocName)
  const crocInfo = crocResponse.body
  // We access the water key with optional chaining
  return crocInfo?.habitat?.water
}

const myCrocsName = 'Barry'
const barrysWaterHabitat = getWaterHabitat('Barry')
// barrysWaterHabitat == undefined

配列でオプションのインデックスを使用することもできます。

const crocAddress1City = crocInfo?.personalInfo?.addresses?.[0].city
// if  crocInfo.personalInfo.addresses = []
// crocAddress1City === undefined

…そして機能付き!

// It is hard to make a short example
const getSkinStyle = (option) => {
  const scales = {
    color: 'green',
    texture: 'shiny'
  }
  if (option == 'naked')
    return
  else 
    return scales
}

const crocInfo = {
  name: 'Barry', 
  waterHabitat : 'Freshwaters',
  getSkinStyle : getSkinStyle
}

const barrysSkinColor = crocInfo?.getSkinStyle?.('naked')?.color
// barrysSkinColor === undefined
const larrysSkinColor = crocInfo?.getSkinStyle?.('naked')?.color
// larrysSkinColor === 'green'

…そして動的なプロパティアクセスを使用します。 うわー、それは本当にホリデーシーズンです⛄🎄🎁(執筆時点)!

// habitatType can be "water" or "land"
const getHabitatProperty = (habitatType) => {
  return crocInfo?.habitat?.[habitatType]
}
getHabitatType('water')
// returns  ['freshwater']
getHabitatType('land')
// returns ['forest']

タイプエラーはもうありません。 undefined 価値!

迅速なPSAとして、適切なエラー処理を行わない言い訳として、オプションのチェーンに依存しないでください。 未定義の値のプロパティにアクセスすることで得られるTypeErrorの良いところは、次のとおりです。

  • アプリケーションの予期しない動作に気づきやすくなります
  • それは私たちにもっと良いフォールバックメカニズムを書くことを強制します

未定義の値のプロパティにアクセスしようとするときは、何らかのフォールバックまたは警告メカニズムが必要です。

ヌルの合体

??…いいえ、私は混乱していません、 ?? に参加する新しい短絡オペレーターです &&|| 家族。 React、Vue、Angularを書いた場合は、おそらくこのようなものをすでに書いているか、見たことがあるでしょう。

const name = props.name || 'CrocName Error';
const age = props.age || 'Invalid Age';
const isFemale = props.isFemale || true;
// pass name , age and isFemale to a view

このコードは、に保存されている値を割り当てます props.name それが偽物でなければ。 値が偽の場合、値 name 等しくなります CrocName Error.

しかし、まだ名前が付けられていないワニの場合、APIは空の文字列を返すとしましょう。 JavaScriptでは、空の文字列は偽物と見なされるため、次のようになります。

// Let's say we have an anonymous new born boy crocodile
const props  = {
  name: '',
  age: 0,
  isFemale: false
}

const name = props.name || 'CrocName Error';
// name === 'CrocName Error'

const age = props.age || 'Invalid Age';
// age === 'Invalid Age'

const isFemale = props.isFemale || true;
// isFemale === true

これらは私たちが期待していた結果ではありません! シナリオを分離したい props.name があります null また undefined 場合の価値 props.name 空の文字列です。 欲しい age 等しくする 0isFemale することが false. それはどこです ?? 救助に来る。

const name = '' ?? 'CrocName Error'
// name === '' 

const age = 0 ?? 'Invalid Age';
// age === 0

const isFemale = false ?? true;
// isFemale === false

// Yay it worked!

|| 左側の演算子が偽物であるかどうかをチェックします。 ?? それがそうであるかどうかだけをチェックします null また undefined. これがあなたのための小さなチートシートです:

// +0, -0, NaN, false, empty strings, null and undefined are all falsy
false ?? true;   // equals false
false || true;   // equals true

0 ?? 1;          // equals 0
0 || 1;          // equals 1

'' ?? 'default'; // equals ''
'' || 'default'; // equals 'default'

// null and undefined are falsy so in this case we  get the same results
null ?? [];      // equals []
null || [];      // equals []

undefined ?? []; // equals []
undefined || []; // equals []

演算子を混在させることもできます! かっこを使用することを忘れないでください。 これが何をするか考えてみてください:

const crocName = (props.name ?? 'CrocName Error') || 'Anonymous Croc';

いくつかの値の結果を見てみましょう。

  • props.name === 'Barry': crocName === 'Barry'
  • props.name === '' : crocName ==== 'Anonymous Croc'
  • props.name === undefined : crocName ==== 'CrocName Error'

ヌルの合体とオプションの連鎖が連携する

これらの2つの機能を一緒に使用するためのクールな方法を考えたかもしれません!

const getCrocName = async (crocId) => {
  // We try to access our unstable API's data
  const crocResponse = await fetch('http://api.crocosapi.io/croc/' + crocId)
  // If croc response or body is undefined 
  const crocInfo = crocResponse?.body ?? 'Croc API did not return a valid response'
  // if crocResponse equals {} then crocInfo == 'Croc API did not return a valid response'

  // checking if crocInfo, personal info or name is undefined/null or if name has a falsy value
  return (crocInfo?.personalInfo?.name ?? 'There was a problem loading the croc\'s name') || 'Anonymous Croc'
  // if crocInfo?.personalInfo?.name === '' we return 'Anonymous Croc'
  //  if crocInfo equals {} we return 'There was a problem loading the croc\'s name'
}

V8V8のパフォーマンス

今日、私たちはJavaScriptの速度に甘んじており、パフォーマンスの更新が繰り返されることでさらに甘やかされています。 繰り返しになりますが、V8のエンジニアは、エンジンのパフォーマンスとメモリを改善しました。 それがどのようになっているのかについてもっと知りたい場合は、リリース投稿をチェックしてください。 これらのアップデートで私が気に入っているのは、コードのパフォーマンスが向上することですが、新しいものを書く必要はありません。

小さなボーナス

Node.jdでV8v8を使用できるかどうかを確認するには、次のコマンドを実行できます node -p process.versions.v8 バージョンが8を超えているかどうかを確認します。 今のところ、Webやトランスパイラーでcore-jsのようなポリフィルを使用する必要があります。 Babelを使用している場合は、 @babel/plugin-proposal-optional-chaining, @babel/plugin-proposal-nullish-coalescing-operator 利用可能です。

楽しく幸せな休日を! 🎄🎉