2017年5月10日
JavaScriptは近年非常に進歩しています。 2017年にJavaScriptを学習していて、ES6に触れていない場合は、JavaScriptを読み書きする簡単な方法を見逃しています。
あなたはまだJavaScriptのマスターではない場合は心配しないでください。 あなたはES6があなたに与える追加のボーナスを利用するためにJavaScriptで素晴らしいことをする必要はありません。 この記事では、開発者として毎日使用している8つのES6機能を共有して、新しい構文を簡単に理解できるようにしたいと思います。
ES6の機能のリスト
まず、ES6はJavaScriptの巨大な更新です。 Luke Hobanのおかげで、新機能に興味がある場合は、次の機能の大きなリストがあります:
- 矢印
- クラス
- 拡張オブジェクトリテラル
- テンプレート文字列
- デストラクチャリング
- デフォルト+rest+spread
- Let+const
- イテレータ+for…of
- イテレータ+for…of
- イテレータ+for…of
- イテレータ+for…of
- イテレータ+for…of
- イテレータ+for…of
- イテレータ+for…2224>
- ジェネレータ
- Unicode
- モジュール
- モジュールローダー
- マップ+セット+weakmap+Weakset
- プロキシ
- シンボル
- サブクラス可能なビルトイン
- サブクラス可能なビルトイン
- promises
- Math+Number+String+Array+Object Api
- バイナリおよびオクタルリテラル
- reflect api
- Tail 呼び出し
この大きな機能リストがES6からあなたを怖がらせないようにしてください。 あなたはすぐにすべてを知る必要はありません。 私はあなたと私が日常的に使用するこれらの機能の八つを共有するつもりです。 彼らは:
- Letとconst
- 矢印関数
- デフォルトパラメータ
- 破壊
- 残りのパラメータとスプレッド演算子
- 拡張オブジェクトリテラル
- テンプレートリテラル
- 約束
以下のセクションの8つの機能を介して。 今のところ、病気の最初の5つの機能を通過します。 私は数週間の次のカップルに沿って行くように私は残りを追加します。
ところで、ES6のブラウザサポートは素晴らしいです。 最新のブラウザ(Edge、およびFF、Chrome、Safariの最新バージョン)用にコードを作成すると、ほとんどすべてがネイティブにサポートされます。
ES6を書きたいのであれば、Webpackのような派手なツールは必要ありません。 ブラウザのサポートが不足している場合は、いつでもコミュニティによって作成されたポリフィルにフォールバックすることができます。 ちょうどそれらをgoogle:)
それで、最初の機能に飛び込みましょう。Es5(古いJavaScript)では、var
キーワードを使用して変数を宣言するのに慣れています。 ES6では、このvar
キーワードをlet
とconst
に置き換えることができます。
最初にlet
とvar
の違いを見て、let
とconst
が優れている理由を理解しましょう。
let vs var
私たちはそれに精通しているので、最初にvar
について話しましょう。
まず、var
キーワードで変数を宣言できます。 宣言されると、この変数は現在のスコープ内の任意の場所で使用できます。
var me = 'Zell'console.log(me) // Zell
上記の例では、me
をグローバル変数として宣言しました。 このグローバルme
変数は、次のような関数でも使用できます:
var me = 'Zell'function sayMe () { console.log(me)}sayMe() // Zell
しかし、その逆は真実ではありません。 関数内で変数を宣言すると、関数外では使用できません。
function sayMe() { var me = 'Zell' console.log(me)}sayMe() // Zellconsole.log(me) // Uncaught ReferenceError: me is not defined
だから、var
は関数スコープであると言うことができます。 これは、関数内でvar
で変数が作成されるたびに、関数内にのみ存在することを意味します。
変数が関数の外部で作成された場合、その変数は外部スコープに存在します。
var me = 'Zell' // global scopefunction sayMe () { var me = 'Sleepy head' // local scope console.log(me)}sayMe() // Sleepy headconsole.log(me) // Zell
let
, 一方、ブロックスコープです。 これは、変数がlet
で作成されるたびに、そのブロック内にのみ存在することを意味します。
しかし、待って、ブロックは何ですか?
JavaScriptのブロックは、中括弧のペア内の任意のものです。 以下はブロックの例です。
{ // new scope block}if (true) { // new scope block}while (true) { // new scope block}function () { // new block scope}
ブロックスコープ変数と関数スコープ変数の違いは巨大です。 関数スコープの変数を使用すると、意図せずに変数を誤って上書きする可能性があります。 ここに例があります:
var me = 'Zell'if (true) { var me = 'Sleepy head'}console.log(me) // 'Sleepy head'
この例では、if
ブロックを実行するとme
がSleepy head
になることがわかります。 この例では、おそらく同じ名前の変数を宣言することはないので、問題は発生しません。
しかし、for
ループの状況でvar
で作業する人は、変数のスコープが設定されているため、奇妙なことに遭遇する可能性があります。 変数i
を4回ログに記録し、setTimeout
関数を使用してi
を再度ログに記録する次のコードを考えてみましょう。
for (var i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
このコードは何を期待しますか? 実際に起こることは次のとおりです
どのようにi
がタイムアウト関数内で4回5
になったのですか? まあ、var
は関数スコープであるため、i
の値はtimeout関数が実行される前でさえ4
になりました。
後で実行されるsetTimeout
内の正しいi
値を取得するには、setTimeout
が実行される前にi
値がfor
ループによって変更されないように、logLater
などの別の関数を作成する必要:
function logLater (i) { setTimeout(function () { console.log(i) })}for (var i = 1; i < 5; i++) { console.log(i) logLater(i)};
(ちなみに、これはクロージャと呼ばれます)。
良いニュースは、私がちょうどあなたがlet
で起こらないことを示したforループの例のような関数スコープの奇妙さです。 以前に書いたのと同じタイムアウトの例をこのように書くことができ、追加の関数を書くことなくすぐに動作します:
for (let i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
ご覧のように、ブロックスコープの変数は、関数スコープの変数を持つ一般的な落とし穴を削除することで、開発をはるかに簡単にします。 人生を簡単にするために、これからJavaScript変数を宣言するときはいつでもlet
をvar
よりも使用することをお勧めします。 (ES6はすでに新しいJavaScriptです)。
今、私たちはlet
が何をしているのか知っています。let
とconst
の違いに移りましょう。
let vs const
let
のように、const
もブロックスコープです。 違いは、const
は一度宣言された後に再割り当てできないことです。
const name = 'Zell'name = 'Sleepy head' // TypeError: Assignment to constant variable.let name1 = 'Zell'name1 = 'Sleepy head'console.log(name1) // 'Sleepy head'
const
は再割り当てできないため、変数が変更されないために適しています。
私のウェブサイト上でモーダルを起動するボタンがあるとしましょう。 私はボタンが一つしかないことを知っています、そしてそれは変わらないでしょう。 この場合、const
を使用できます。
const modalLauncher = document.querySelector('.jsModalLauncher')
変数を宣言するとき、変数が再割り当てされないという余分なキューを受け取るので、可能な限りconst
よりもlet
を常に好みます。 次に、他のすべての状況でlet
を使用します。
次に、矢印関数について話しましょう。
矢印関数
矢印関数は、ES6コードのどこにでも表示される太い矢印(=>
)で示されます。 これは匿名関数を作るための省略形です。 これらは、function
キーワードが使用されている場所であればどこでも使用できます。 例えば:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
矢印機能はかなりクールです。 それらはコードを短くするのに役立ち、エラーを隠す余地が少なくなります。 また、構文に慣れたら理解しやすいコードを書くのにも役立ちます。
矢印関数の核心に飛び込み、それらを認識して使用することを学びましょう。
矢印関数の核心
まず、関数の作成について話しましょう。 JavaScriptでは、おそらくこの方法で関数を作成するのに慣れています:
function namedFunction() { // Do something}// using the functionnamedFunction()
関数を作成する2番目の方法があります。 無名関数を作成して変数に割り当てることができます。 無名関数を作成するには、その名前を関数宣言から除外します。
var namedFunction = function() { // Do something}
関数を作成する第三の方法は、別の関数またはメソッドへの引数として直接作成することです。 この3番目のユースケースは、匿名関数の最も一般的なユースケースです。 ここに例があります:
// Using an anonymous function in a callbackbutton.addEventListener('click', function() { // Do something})
ES6矢印関数は匿名関数の省略形であるため、匿名関数を作成する任意の場所で矢印関数を置き換えることができます。
ここでは、それがどのように見えるかです:
// Normal Functionconst namedFunction = function (arg1, arg2) { /* do your stuff */}// Arrow Functionconst namedFunction2 = (arg1, arg2) => {/* do your stuff */}// Normal function in a callbackbutton.addEventListener('click', function () { // Do something})// Arrow function in a callbackbutton.addEventListener('click', () => { // Do something})
ここの類似性を参照してください? 基本的には、function
キーワードを削除し、わずかに異なる場所で=>
に置き換えます。
しかし、矢印関数の大したことは何ですか? 私たちはfunction
を=>
に置き換えるだけではありませんか?
まあ、function
を=>
に置き換えるだけではないことがわかります。 矢印関数の構文は、次の2つの要因に応じて変更できます:
- 暗黙的な戻り値を使用するかどうかにかかわらず、必要な引数の数
- 。
最初の要素は、arrow関数に指定された引数の数です。 引数を1つだけ指定する場合は、引数を囲む括弧を削除できます。 引数を必要としない場合は、アンダースコア(_
)の代わりに括弧(()
)を使用できます。
以下はすべて有効な矢印関数です。
const zeroArgs = () => {/* do something */}const zeroWithUnderscore = _ => {/* do something */}const oneArg = arg1 => {/* do something */}const oneArgWithParenthesis = (arg1) => {/* do something */}const manyArgs = (arg1, arg2) => {/* do something */}
矢印関数の第二の要因は、暗黙的な戻り値を希望するかどうかです。 矢印関数は、既定では、コードが1行のみを占め、ブロックで囲まれていない場合、自動的にreturn
キーワードを作成します。
だから、これら二つは同等です:
const sum1 = (num1, num2) => num1 + num2const sum2 = (num1, num2) => { return num1 + num2 }
これら二つの要因は、あなたが上で見たmoreThan20
のような短いコードを書くことができる理由です:
let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)
要約すると、矢印関数はかなりクールです。 彼らはに慣れるために少し時間がかかるので、それを試してみると、あなたはかなりすぐにどこでもそれを使用することになります。
しかし、矢印関数FTW bandwagonにジャンプする前に、多くの混乱を引き起こすES6矢印関数の別の重要な機能、つまり語彙this
についてお知らせしたいと思います。
字句this
this
は一意のキーワードであり、その値は呼び出される方法に応じて変化します。 任意の関数の外部で呼び出されると、this
はブラウザのWindow
オブジェクトにデフォルト設定されます。
console.log(this) // Window
this
が単純な関数呼び出しで呼び出された場合、this
はグローバルオブジェクトに設定されます。 ブラウザの場合、this
は常にWindow
になります。
function hello () { console.log(this)}hello() // Window
JavaScriptは、単純な関数呼び出し内で常にthis
をwindowオブジェクトに設定します。 これは、setTimeout
のような関数内のthis
値が常にWindow
である理由を説明しています。
this
がオブジェクトメソッドで呼び出されると、this
はオブジェクト自体になります:
let o = { sayThis: function() { console.log(this) }}o.sayThis() // o
関数がコンストラクタとして呼び出されると、this
は新しく構築されたオブジェクトを参照します。
function Person (age) { this.age = age}let greg = new Person(22)let thomas = new Person(24)console.log(greg) // this.age = 22console.log(thomas) // this.age = 24
イベントリスナーで使用される場合、this
はイベントを発生させた要素に設定されます。
let button = document.querySelector('button')button.addEventListener('click', function() { console.log(this) // button})
上記の状況でわかるように、this
の値はそれを呼び出す関数によって設定されます。 すべての関数は、それ自身のthis
値を定義します。
fat arrow関数では、関数がどのように呼び出されても、this
は新しい値にバインドされることはありません。 this
は、周囲のコードと常に同じthis
値になります。 (ちなみに、語彙的な意味は、私が推測するには、語彙的なthis
がその名前をどのようにして得たかです)。
わかりました、それは混乱しているように聞こえるので、いくつかの実際の例を見てみましょう。
まず、オブジェクトメソッドを宣言するために矢印関数を使用することはありません。this
でオブジェクトを参照することはできないためです。
let o = { // Don't do this notThis: () => { console.log(this) // Window this.objectThis() // Uncaught TypeError: this.objectThis is not a function }, // Do this objectThis: function () { console.log(this) // o } // Or this, which is a new shorthand objectThis2 () { console.log(this) // o }}
次に、this
がイベントリスナーをアタッチした要素にバインドされなくなるため、矢印関数を使用してイベントリスナーを作成したくない場合があります。
しかし、あなたはいつでも正しいthis
コンテキストをevent.currentTarget
で得ることができます。 だから私はそうしないかもしれないと言ったのです。
button.addEventListener('click', function () { console.log(this) // button})button.addEventListener('click', e => { console.log(this) // Window console.log(event.currentTarget) // button})
第三に、あなたはそれを望んでいないthis
バインディングが変更された場所で字句this
を使用することができます。 例はtimeout関数なので、this
、that
、またはself
ナンセンスを処理する必要はありません。
let o = { // Old way oldDoSthAfterThree: function () { let that = this setTimeout(function () { console.log(this) // Window console.log(that) // o }) }, // Arrow function way doSthAfterThree: function () { setTimeout(() => { console.log(this) // o }, 3000) }}
このユースケースは、時間が経過した後にクラスを追加または削除する必要がある場合に特に役立ちます:
let o = { button: document.querySelector('button') endAnimation: function () { this.button.classList.add('is-closing') setTimeout(() => { this.button.classList.remove('is-closing') this.button.classList.remove('is-open') }, 3000) }}
最後に、上記のmoreThan20
の例のように、fat arrow関数を他の場所で自由に使用して、コードをより簡潔かつ短くすることができます:
let array = let moreThan20 = array.filter(num => num > 20)
先に進みましょう。
デフォルトパラメータ
ES6のデフォルトパラメータ…まあ、私たちは関数を定義するときにデフォルトパラメータを指定する方法を提供します。 例を見てみましょう、あなたはそれがどのように役立つかがわかります。
チームのプレイヤーの名前を発表する関数を作成しているとしましょう。 この関数をES5で記述すると、次のようになります:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
一見すると、このコードは正常に見えます。 しかし、どのチームとも関係のない選手を発表しなければならなかった場合はどうなりますか?
teamName
を残した場合、現在のコードは恥ずかしいほど失敗します:
announcePlayer('Zell', 'Liew')// Zell Liew, undefined
私はかなりundefinedがチーム😉ではないと確信しています。
プレイヤーが非関連であれば、Zell Liew, unaffiliated
を発表する方がZell Liew, undefined
の方が理にかなっています。 同意しないのか?
announcePlayer
にZell Liew, unaffiliated
を通知するには、unaffiliated
文字列を次のように渡す方法があります。teamName
:
announcePlayer('Zell', 'Liew', 'unaffiliated')// Zell Liew, unaffiliated
これは機能しますが、unaffiliated
をannouncePlayer
にリファクタリングすることで、teamName
が定義されているかどうかを確認することで、より良いことができます。
ES5バージョンでは、コードを次のようにリファクタリングできます:
function announcePlayer (firstName, lastName, teamName) { if (!teamName) { teamName = 'unaffiliated' } console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Zell', 'Liew')// Zell Liew, unaffiliatedannouncePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
または、三項演算子を使用している場合は、より簡潔なバージョンを選択することもできます:
function announcePlayer (firstName, lastName, teamName) { var team = teamName ? teamName : 'unaffiliated' console.log(firstName + ' ' + lastName + ', ' + team)}
ES6では、デフォルトのパラメータを使用して、パラメータを定義するたびに等号(=
)を追加できます。 これを行うと、パラメータが未定義のときにES6は自動的にその値にデフォルト設定されます。したがって、以下のこのコードでは、teamName
が未定義の場合、デフォルトでは
になりますunaffiliated
:
const announcePlayer = (firstName, lastName, teamName = 'unaffiliated') => { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Zell', 'Liew')// Zell Liew, unaffiliatedannouncePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors
かなりクールですね? 🙂
もう一つ。 デフォルト値を呼び出したい場合は、undefined
を手動で渡すことができます。 このマニュアルでは、undefined
を渡すと、デフォルトのパラメータが関数の最後の引数ではない場合に役立ちます。
announcePlayer('Zell', 'Liew', undefined)// Zell Liew, unaffiliated
デフォルトパラメータについて知る必要があるのはこれだけです。 それはシンプルで非常に便利です:)
Destructuring
Destructuringは、配列やオブジェクトから値を取得する便利な方法です。 配列の破壊とオブジェクトの間には小さな違いがありますので、それらについて別々に話しましょう。
破壊オブジェクト
次のオブジェクトがあるとしましょう:
const Zell = { firstName: 'Zell', lastName: 'Liew'}
Zell
からfirstName
とlastName
を取得するには、2つの変数を作成し、次のように各変数を値に代入する必要がありました:
let firstName = Zell.firstName // Zelllet lastName = Zell.lastName // Liew
デストラクチャリングを使用すると、これらの変数を作成して1行のコードで割り当てることができます。 オブジェクトを破壊する方法は次のとおりです:
let { firstName, lastName } = Zellconsole.log(firstName) // Zellconsole.log(lastName) // Liew
ここで何があったか見て? 変数の宣言中に中括弧({}
)を追加することで、前述の変数を作成してから、それぞれZell.firstName
をfirstName
に、Zell.lastName
をlastName
に割り当てるようにJavaScriptに指示しています。
これはボンネットの下で何が起こっているのですか:
// What you writelet { firstName, lastName } = Zell// ES6 does this automaticallylet firstName = Zell.firstNamelet lastName = Zell.lastName
現在、変数名が既に使用されている場合、変数を再度宣言することはできません(特にlet
またはconst
を使用する場合)。
以下は動作しません:
let name = 'Zell Liew'let course = { name: 'JS Fundamentals for Frontend Developers' // ... other properties}let { name } = course // Uncaught SyntaxError: Identifier 'name' has already been declared
上記のような状況に遭遇した場合は、コロン(:
)で分割しながら変数の名前を変更することができます。以下のこの例では、courseName
変数を作成し、それにcourse.name
を割り当てています。
let { name: courseName } = courseconsole.log(courseName) // JS Fundamentals for Frontend Developers// What ES6 does under the hood:let courseName = course.name
もう一つ。
オブジェクト内に含まれていない変数を破壊しようとしても心配しないでください。 それはちょうどundefined
を返します。
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package } = courseconsole.log(package) // undefined
しかし、待って、それだけではありません。 デフォルトのパラメータを覚えていますか?
構造化された変数のデフォルトパラメータを記述することもできます。 構文は、関数を定義するときと同じです。
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package = 'full course' } = courseconsole.log(package) // full course
デフォルトを指定しながら変数の名前を変更することもできます。 二つを組み合わせるだけです。 最初は少し面白いように見えますが、頻繁に使用すると慣れるでしょう:
let course = { name: 'JS Fundamentals for Frontend Developers'}let { package: packageName = 'full course' } = courseconsole.log(packageName) // full course
それはオブジェクトを破壊するためのものです。 先に進み、配列の破壊について話しましょう。
構造化配列
構造化配列と構造化オブジェクトは似ています。 中括弧({}
)の代わりに角括弧()を使用します。
配列を破壊するとき,
- 最初の変数は配列の最初の項目です。
- あなたの第二の変数は、配列内の第二の項目です。
- など…
let = console.log(one) // 1console.log(two) // 2
指定された配列内のアイテムの数を超えるほど多くの変数を破壊することは可能です。 これが起こると、余分な破壊された変数はundefined
になります。
let = console.log(one) // 1console.log(two) // 2console.log(three) // undefined
配列を分割するとき、必要な変数だけを分割することがよくあります。 配列の残りの部分が必要な場合は、次のようにrest演算子(...
)を使用できます:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93console.log(rest) //
rest演算子の詳細については、次のセクションで説明します。 しかし、今のところ、破壊された配列で得られるユニークな能力、つまり変数の交換について話しましょう。
変数を破壊された配列と交換
2つの変数、a
とb
があるとしましょう。
let a = 2let b = 3
これらの変数を交換したいと思っていました。 だからa = 3
とb = 2
。 ES5では、スワップを完了するために一時的な3番目の変数を使用する必要があります:
let a = 2let b = 3let temp// swappingtemp = a // temp is now 2a = b // a is now 3b = temp // b is now 2
これは機能しますが、ロジックはあいまいで混乱する可能性があり、特に第三の変数の導入により混乱する可能性があります。
今、あなたはそれを破壊された配列でES6の方法を行う方法を見てください:
let a = 2let b = 3; // semicolon required because next line begins with a square bracket// Swapping with destructured arrays = console.log(a) // 3console.log(b) // 2
💥💥💥. 変数を交換する以前の方法に比べてはるかに簡単です! 🙂
次に、関数内の配列とオブジェクトの破壊について話しましょう。
関数を宣言しながら配列とオブジェクトを破壊する
破壊についてのクールなことは、あなたがどこでもそれらを使用できるということです。 文字通り。 関数内のオブジェクトや配列を破壊することもできます。
スコアの配列を受け取り、上位3つのスコアを持つオブジェクトを返す関数があるとしましょう。 この関数は、配列を破壊するときに行ったことに似ています。
// Note: You don't need arrow functions to use any other ES6 featuresfunction topThree (scores) { let = scores return { first: first, second: second, third: third }}
この関数を書く別の方法は、関数を宣言している間にscores
を破壊することです。 この場合、記述するコードの行が1つ少なくなります。 同時に、私たちは配列を取っていることを知っています。
function topThree () { return { first: first, second: second, third: third }}
超かっこいいですよね? 😄.
さて、ここであなたのための簡単な小さなクイズです。 関数を宣言しながら、デフォルトのパラメータと破壊を組み合わせることができるので、次のことは何を言いますか?
function sayMyName ({ firstName = 'Zell', lastName = 'Liew'} = {}) { console.log(firstName + ' ' + lastName)}
これはトリッキーなものです。 私たちは一緒にいくつかの機能を組み合わせています。
まず、この関数が一つの引数であるオブジェクトを取ることがわかります。 このオブジェクトは省略可能で、定義されていない場合のデフォルトは{}
です。
次に、指定されたオブジェクトからfirstName
とlastName
変数を破壊しようとします。 これらのプロパティが見つかった場合は、それらを使用します。最後に、指定されたオブジェクトでfirstName
またはlastName
が未定義の場合、それをそれぞれZell
およびLiew
に設定します。
したがって、この関数は次の結果を生成します:
sayMyName() // Zell LiewsayMyName({firstName: 'Zell'}) // Zell LiewsayMyName({firstName: 'Vincy', lastName: 'Zhang'}) // Vincy Zhang
関数宣言ehで破壊とデフォルトのパラメータを組み合わせるのはかなりクールですか? 😄. 私はこれが大好きです。
次に、休息と広がりを見てみましょう。
restパラメータとspread演算子
restパラメータとspread演算子は同じように見えます。 それらは両方とも三つの点(...
)で表されています。
彼らが何をするかは、彼らが何のために使用されているかによって異なります。 それが彼らの名前が違う理由です。 そこで、restパラメータとspread演算子を別々に見てみましょう。
restパラメータ
は緩く翻訳され、restパラメータは残りのものを取り出して配列にパックすることを意味します。 引数のコンマ区切りのリストを配列に変換します。
動作中のrestパラメータを見てみましょう。 引数をまとめた関数add
があるとします:
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // 55
ES5では、未知の数の変数を取り込む関数を処理する必要があるときはいつでも、arguments
変数に依存していました。 このarguments
変数は配列のようなSymbol
です。
function sum () { console.log(arguments)}sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
この引数の合計を計算する1つの方法は、それをArray.prototype.slice.call(arguments)
で配列に変換し、forEach
やreduce
ような配列メソッドで各数値をループすることです。
私はあなたが自分でforEach
を行うことができると確信しているので、ここにreduce
の例があります:
// ES5 wayfunction sum () { let argsArray = Array.prototype.slice.call(arguments) return argsArray.reduce(function(sum, current) { return sum + current }, 0)}
ES6restパラメータを使用すると、すべてのコンマ区切りの引数を配列にまっすぐにパックできます。
// ES6 wayconst sum = (...args) => args.reduce((sum, current) => sum + current, 0)// ES6 way if we didn't shortcut it with so many arrow functionsfunction sum (...args) { return args.reduce((sum, current) => sum + current, 0)}
🙂.
ここで、destructuringセクションの前半でrestパラメータに簡単に遭遇しました。 そこでは、スコアの配列を上位3つのスコアに分割しようとしました:
let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93
残りのスコアが必要な場合は、残りのスコアをrestパラメーターを使用して配列にパックすることで、そうすることができます。
let scores = let = scoresconsole.log(restOfScores) //
混乱したことがある場合は、これを覚えておいてください。restパラメータはすべてを配列にパックします。 これは、関数のパラメータと配列の分割中に表示されます。
次はスプレッドに移りましょう。
スプレッド演算子
スプレッド演算子はrestパラメータとは逆の動作をします。 大まかに言えば、配列を取り、それを(ジャムのように)コンマで区切られた引数のリストに広げます。
let array = // These two are exactly the sameconsole.log(...array) // one two threeconsole.log('one', 'two', 'three') // one two three
spread演算子は、読みやすく理解しやすい方法で配列を連結するのに役立つことがよくあります。
たとえば、次の配列を連結したいとします:
let array1 = let array2 = let array3 =
これら2つの配列を連結するES5の方法は、Array.concat
メソッドを使用することです。 次のように、複数のArray.concat
をチェーンして任意の数の配列を連結することができます:ES6spread演算子を使用すると、次のように配列を新しい配列に広げることができます。:
// ES6 waylet combinedArray = console.log(combinedArray) //
spread演算子を使用して、配列を変更せずに配列から項目を削除することもできます。 この方法はReduxで一般的に使用されています。 私は非常にあなたがそれがどのように動作するかを見ることに興味があるなら、ダンAbramovによってこのビデオを見ることをお勧めします。
それはスプレッドのためです:)
強化されたオブジェクトリテラル
オブジェクトは、JavaScriptを書いているので、あなたにとって馴染みのあるものでなければなりません。 あなたがそれらについて知らない場合に備えて、彼らはこのようなものに見えます:
const anObject = { property1: 'value1', property2: 'value2', property3: 'value3',}
ES6強化されたオブジェクトリテラルは、あなたが知っていると愛するオブジェクトに三つの甘いアッ 彼らは:
- プロパティ値の省略形
- メソッドの省略形
- 計算されたプロパティ名を使用する機能
それぞれを見てみましょう。 私はこれが速いことを約束します:)
プロパティ値の省略形
オブジェクトプロパティと同じ名前の変数を割り当てることがあることに気づ このようなものは:さて、プロパティ(fullName
)と値(fullName
)なので、これをより短い方法で書くことができませんか?
(ああ、あなたはガキを台無しに)。
ここに良いニュースがあります。 あなたはできます! 🙂
ES6は、プロパティ値の省略形を持つオブジェクトを拡張します。 つまり、変数名がプロパティ名と一致する場合にのみ変数を書き込むことができます。 ES6は残りの世話をします。
ここでは、それがどのように見えるかです:
const fullName = 'Zell Liew'// ES6 wayconst Zell = { fullName}// Underneath the hood, ES6 does this:const Zell = { fullName: fullName}
かなりきちんとした、えっ? 今、私達は書くべきより少ない単語を有し、私達はすべて幸せな家に帰る。
私が踊っている間、上に移動し、より多くの速記の良さに移動してください。 私はすぐにあなたに参加します。
メソッドの省略形
メソッドは、プロパティに関連付けられている関数です。 彼らは関数であるため、特別な名前が付けられています:)
これはメソッドの例です:
const anObject = { aMethod: function () { console.log("I'm a method!~~")}}
ES6では、省略形でメソッドを書くことができます。 メソッド宣言から: function
を削除することができ、以前のように動作します:
const anObject = { // ES6 way aShorthandMethod (arg1, arg2) {}, // ES5 way aLonghandMethod: function (arg1, arg2) {},}
このアップグレードでは、オブジェクトはすでに短縮メソッドを取得しているため、オブジェクトを定義するときに矢印関数を使用しないでください。 あなたはthis
コンテキストを破るでしょう(理由を覚えていない場合は矢印関数を参照してください)。
const dontDoThis = { // Noooo. Don't do this arrowFunction: () => {}}
それはオブジェクトメソッドの省略形でそれです。 のは、我々はオブジェクトのために得る最終的なアップグレードに移動してみましょう。
計算されたオブジェクトのプロパティ名
オブジェクトを作成するときに動的プロパティ名が必要な場合があります。 古いJavaScriptの方法では、オブジェクトを作成してから、次のようにプロパティをinに割り当てる必要があります:
// ES5const newPropertyName = 'smile'// Create an object firstconst anObject = { aProperty: 'a value' }// Then assign the propertyanObject = ':D'// Adding a slightly different property and assigning itanObject = 'XD'// Result// {// aProperty: 'a value',// 'bigger smile': 'XD'// smile: ':D',// }
ES6では、もはやこのラウンドアバウトの方法を行う必要はありません。 オブジェクトの作成時に動的プロパティ名を直接割り当てることができます。 重要なのは、動的プロパティを角括弧で囲むことです:
const newPropertyName = 'smile'// ES6 way.const anObject = { aProperty: 'a value', // Dynamic property names! : ':D', : 'XD',}// Result// {// aProperty: 'a value',// 'bigger smile': 'XD'// smile: ':D',// }
シュワイート! そうでしょ? 🙂
それは拡張オブジェクトリテラルのためのものです。 早くなると言ってなかった? 🙂
テンプレートリテラル:のは、私は絶対に愛する別の素晴らしい機能に移りましょう。
テンプレートリテラル
JavaScriptで文字列を処理することは非常に不格好な経験です。 以前にdefault parametersでannouncePlayer
関数を作成したときに、あなた自身でそれを経験しました。 そこでは、空の文字列でスペースを作成し、それらをプラスで結合しました:
function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}
ES6では、テンプレートリテラルのおかげでこの問題は解消されます! (仕様では、以前はテンプレート文字列と呼ばれていました)。
ES6でテンプレートリテラルを作成するには、文字列をバッククォート(`
)で囲みます。 Backticks内では、JavaScriptを通常使用できる特別なプレースホルダー(${}
)にアクセスできます。
ここでは、アクションでどのように見えるかです:
const firstName = 'Zell'const lastName = 'Liew'const teamName = 'unaffiliated'const theString = `${firstName} ${lastName}, ${teamName}`console.log(theString)// Zell Liew, unaffiliated
見たか? 私たちは、テンプレートリテラルですべてをグループ化することができます! テンプレートリテラル内では、通常のように英語です。 テンプレートエンジンを使用しているかのように:)
テンプレートリテラルの最良の部分は、複数行の文字列を簡単に作成できることです。 これは箱から出して動作します:
const multi = `One upon a time,In a land far far away,there lived a witich,who could change night into day`
これらの文字列を使用して、必要に応じてJavaScriptでHTML要素を作成することがきちんとしています。 (注:これはHTML要素を作成する最良の方法ではないかもしれませんが、それらを1つずつ作成するよりも優れています!).
const container = document.createElement('div')const aListOfItems = `<ul> <li>Point number one</li> <li>Point number two</li> <li>Point number three</li> <li>Point number four</li> </ul>`container.innerHTML = aListOfItemsdocument.body.append(container)
CodePenのzell Liew(@zellwk)による複数行の文字列を使用してより複雑なHTML要素を作成するペンを参照してください。
テンプレートリテラルのもう一つの機能はタグと呼ばれます。 タグは、任意の文字列を置換したい場合に、テンプレートリテラルを操作できる関数です。
ここでは、それがどのように見えるかです:
const animal = 'lamb'// This a tagconst tagFunction = () => { // Do something here}// This tagFunction allows you to manipulate the template literal.const string = tagFunction `Mary had a little ${animal}`
正直言って、テンプレートタグはクールに見えますが、私はまだそれらのユースケースを持っていませんでした。 テンプレートタグの詳細を知りたい場合は、MDNのこのリファレンスを読むことをお勧めします。
それはテンプレートリテラルのためのものです。
それは私が定期的に使用するほぼすべての素晴らしいES6機能です。 ES6は素晴らしいです。 あなたの時間を少し取ってそれらについて学ぶことは間違いなく価値があるので、他の人が何を書いているのかを理解することができます。