blog

JavaScriptリボーン

ステータスの変更は、resolve 関数と reject 関数が実行されたときにトリガされます。 resolveがトリガーされてステータスが変更されると、対応する値が.thenの関数に渡されます。 こ...

Jul 20, 2020 · 6 min. read
シェア

JavaScriptとES6の自己要約、構文ルールの再深度理解

非同期

スコープがよく理解できていないと、thisが指すもの、クロージャ、ファンクション、その他の問題が適切に処理されないことに影響します!

JSは静的なスコープで、書かれている場所によって一度に1つのレイヤーを検索します。

jsの実行はスコープの連鎖に依存しています。

ファンクションスコープは以下のカテゴリーに分けられます。

グローバルスコープ

その名が示すように、グローバルスコープは

function test () { return new Promise((resolve, reject) => { setTimeout( () => { resolve('hahah, this is promise') //ステータスをfullfilledに変更する }, 3000) }) } test().then((res) => { console.log('this is res', res) return new Promise((resolve, reject) => { setTimeout( () => { resolve('this is the second') }, 2000) }) }).then ( (res) => { console.log(res) } )

グローバル属性はdeleteで削除することができ、この方法でも標準化されていません。

async...await

ローカル・スコープとも呼ばれますが、変数の有効領域が関数内でのみ有効であることから、関数スコープとも呼ばれます。

const one = Promise...
const two = Promise...
const three = Promise...
Promise.all([one,two,three]).then()

関数の { は壁のようなもので、壁の中の変数には壁の外からアクセスできますが、壁の外の変数には壁の中からアクセスできません。

しかし、壁の外から壁の中の変数にアクセスできるようにするには、戻り値やクロージャを使用します。

async function test () { return 12 } test.then((val)=>{console.log(item)})

しかし、なぜこれがクロージャなのでしょうか?関数のテストは、関数を返したため、理由の本質は、スコープ内に残っており、キーにコピーされ、キーを呼び出すことで、関数を実行することができます。関数の実行プロセスはまだ自分のスコープを覚えて本当に内部の関数テストですので、変数を探して関数のスコープを見つけるために、この関数に戻ります、これはクロージャ関数の原理です!

銘記

return 12 == return Promise.resolve(12)

これは先ほども紹介した特殊なケースですが、windowのグローバルオブジェクトにa属性を追加することで、関数内に出現していることが確認できても、グローバルにアクセスできるようにする設定方法です。これはwindowのプロパティなので、windowを追加しなくてもアクセスできます。

ブロックスコープ

グローバルスコープとローカルスコープを区別する関数だけでは十分微妙です。

let price = 92.3 console.log(Reflect.apply(price>100?Math.floor:Math.ceil,null,[price])

Promise.race

なぜvarで定義された変数はブロックスコープ効果がないのでしょうか?その理由は、変数の昇格のためです。変数がifで定義されていても、変数の昇格のため、ブラウザは次のような処理を実装するので、ifで定義されていても、外部の

let obj ={
 price: 134,
 name:'tanakasan'
}
let b = new Proxy(obj,{
 get (target,key) {
 if (target[key]>130){
 return 666
 }
 else {
 return target[key]
 }
 } 
 set (target,key,value) {
 target[key]=value
 }
})
console.log(b.price,b.name) //666 "tanakasan"
プロキシの第2パラメータで読み込むために追加された制限事項

ここでは、関数スコープの中に if ブロックが含まれており、この if ブロックをブロックスコープと呼ぶことができます。上で定義した方法では、関数スコープでブロックスコープにアクセスできる変数bは、ブロックスコープとして機能しません。事実上、関数スコープで変数をローカライズしていることになります。

//複雑な操作関数のデカップリングが可能である。
let validator = (target,key,value)=>{
 target[key]=value
}
set: validator

ブロック・スコープを実装するために、letとconstが導入され、ブロック・スコープ内で変数を定義することができるようになりました。

ダイナミックスコープ

動的スコープとは、そのスコープが指定する領域が動的に変化するものです。

let b = Proxy.revocable(...) console.log(b.proxy.price) b.revoke() //このプロキシを元に戻す

this.aは何も変更しませんが、出力される値は異なります。 この引用は、動的スコープであるbindによって、thisが参照するスコープを変更します。

賃貸と建設の追加

概要

lets で作成された変数には、ウィンドウからアクセスできません。

letは一度定義すると二度と作成できません。

letは変数のリフティングを行いません

コンスト

constは定数を作成しますが、それに演算を追加することができます。

割り当て前の宣言は禁止

トラバーサルメソッド

forは、最も基本的なトラバーサルメソッドであり、次にforループ、サポートcontinueとbreakこの種の操作です。

function * test () {
 for(let i = 0; i<10 ; i++ ) {
 yield alert(i)
 }
}
let one = test()
one.next()
one.next()
one.next()

これは、forループのメソッド拡張に過ぎず、配列の値を変更することなくトラバースします。

forEachはforループの長さを大幅に簡略化し、ループの条件を判断する必要がないため、ループは最初から最後まで、中断することなく続けなければなりません。

function * test () {
 let one = yield [1,2,3]
 console.log(one)
}
let b = test()
b.next(10)
b.next(20) //20

everysome

forEachのようなループは途中で中断できないので、中断できるようにeveryメソッドやsomeメソッドが提案されています。また、イテレーションは配列を変更しません。

それぞれ

everyはforEachと同じようにループしますが、ループを続けるには各ループがtrueを返す必要があり、戻り値がfalseになるとループは終了します。

let authors = {
 allAuthors: {
 fiction: [
 'Agatha Christie',
 'J. K. Rowling',
 'Dr. Seuss'
 ],
 scienceFiction: [
 'Neal Stephenson',
 'Arthur Clarke',
 'Isaac Asimov',
 'Robert Heinlein'
 ],
 fantasy: [
 'J. R. R. Tolkien',
 'J. K. Rowling',
 'Terry Pratchett'
 ]
 }
}
// この構造体を直接たどることはできない

いくつか

everyとよく似ていますが、各ループはfalseを返す必要があり、戻り値がtrueになるとループは終了します。

let authors = {
 allAuthors: {
 fiction: [
 'Agatha Christie',
 'J. K. Rowling',
 'Dr. Seuss'
 ],
 scienceFiction: [
 'Neal Stephenson',
 'Arthur Clarke',
 'Isaac Asimov',
 'Robert Heinlein'
 ],
 fantasy: [
 'J. R. R. Tolkien',
 'J. K. Rowling',
 'Terry Pratchett'
 ]
 }
 }
authors[Symbol.iterator] = function () {
 let author = this.allAuthors
 let key = Reflect.ownKeys(author)
 let val = []
 return {
 next(){
 if(!val.length){
 if(key.length){
 val = author[key[0]]
 key.shift()
 }
 }
 return {
 done: !val.length,
 value: val.shift()
 }
 }
 }
}
let q=[]
for(let v of authors) {
 q.push(v)
}
console.log(q)

で...

for--inは、オブジェクトをトラバースするためのトラバーサル手法の提案です。

の...

for--ofは、配列やオブジェクトのトラバーサルに加えて、トラバーサルを行います。

,import {one ,two as what} from './1.js' .js export { one, two}

Object.keys/valueのメソッドを通して、オブジェクトをトラバースし、対応するキーと値の配列を取得することができます。

戻り値は配列なので、配列用のメソッドをすべて適用できることに注意してください。

import {one ,two as what} from './1.js' .js export { one, two}

トラバーサブルでないオブジェクトをトラバーサブルにするには、以下のメソッドを使用し、for ... を使用します。 ループの

import one((任意の名前にできる)から'./2.js' .js export default one

ES10 ギーク・オペレーティング・オブジェクト

日常業務において、配列とオブジェクトの変換は日常的な操作です。

配列をオブジェクトに変換

モジュールファイル export {...} export default class People {} ファイルをインポートする import * as mod from '..ファイルパス' export リストシンボル内の関数には、mod.関数呼び出し ただし、エクスポート・デフォルトでは、Peopleクラスの名前を書き換えるので、Peopleクラスをクラスとして使いたい場合は はmod.default

オブジェクトから配列へ

const one = [1,[2,3],[4,[5]]]
console.log(one.flat(3)) //12, 3, 4, 5

この2つのAPIを組み合わせることで、オブジェクトに対して配列と同じ操作を行うこともできます。

地図

map の関数は forEach の関数と似ていますが、唯一の違いは map が新しい配列を返すことです。


からの擬似配列の処理

疑似配列とは?擬似配列は2つの基本的な点を満たさなければなりません。第一に、インデックスでソートされていること、第二に、長さ


ここで、from以降の引数は擬似的な配列条件であり、操作の各要素について、thisが指すのは

Array.prototype.of/fill



ここで、()内のパラメータには、パディング番号、開始位置、終了位置

配列のメソッド検索

フィルター

の配列が返されます。


見つける

filter は配列内のすべての値を繰り返し処理しなければならないので、 ある値が配列内に存在するかどうかを知りたい場合は非効率的です。そこで find メソッドを使うと、条件を満たす最初の値を返すことができます!返される値はひとつだけです。


findIndex

の条件値を満たす最初の位置を返します。


findのメソッドでもありますが、ES7では新しいものです。この関数は、配列に直接適用して、その要素が配列に含まれているかどうかを判定する包含関数と解釈できます。


要素が配列に入っているかどうかの判定を直接出力

ジェネレータ

なぜなら、クラスは原則的にコピーだからです。しかし、javascriptにはコピーの関係はありません。


いわゆる "クラス "の作成は、キーワードnewによって達成されます。newの瞬間に、変数oneと2は、属性typeとeatingを保持する独自のスペースを作成します。

同じ目標を達成するために、手順を簡略化した構文糖クラスがES6で導入されました。

プロトタイプチェーン

プロトタイプ・チェーンはリンクリストに似ており、接続の役割を果たします。

  • コンストラクタ
  • コンストラクタのプロトタイプ
  • 実例

プロトタイプ・チェーンは、以下の3つの分野を中心としています。

まず、各コンストラクタはそれ自身のプロトタイプを持ち、各コンストラクタのプロトタイプはコンストラクタを指すコンストラクタを持ちます。


すべてのコンストラクタは、作成された時点ですでにプロトタイプの原型を持っています。

次に分析すべきは、インスタンスとプロトタイプの関係です。

インスタンスごとの __proto___ 属性は、プロトタイプを接続する属性です。



ゲッターセッター

いわゆるゲッターとセッターは、クラスの値を修飾し、割り当てではなく、クラスによって作成された任意のインスタンスは、それ自体で自由に変更することができます。


ここで、年齢は実際には属性であり、修飾されているだけです。

クラスの静的メソッドと静的プロパティ

オブジェクトはインスタンスメソッドとスタティックメソッドの両方を持つことができます。


インスタンス・メソッドには、インスタンス上のプロパティからアクセスできます。インスタンス・メソッドを呼び出すには、インスタンス.メソッドを呼び出す必要があります。

静的メソッドはクラスに束縛され、インスタンスのプロパティにアクセスすることはできません。クラスが必要です。メソッド、静的メソッドの呼び出し

しかし、class.prototype.methodsプロトタイプ・メソッドは、インスタンスとコンストラクタの両方から呼び出され、共有されるメソッドです。


はんてん

サブクラスのコンストラクタにスーパー関数を追加し、その後にサブクラスのコンストラクタを追加します。


クラスのプロパティ記述子

特定のプロパティは、クラスのプロパティ記述子を通してその全体を見ることができます。


関数パラメータのデフォルト値

関数にパラメータを渡すことは非常に一般的な動作ですが、パラメータにデフォルト値を設定しなければならないことがあり、es5では判断が必要でした。


引数に代わる操作


...num は、残りの変数から渡された値を受け取ることができます。


渡されるパラメータが定義された配列の場合、...関数の正式なパラメータに、定義されたとおりの配列を代入することができます。Object.fromEntries\Object.entries

この」指差し問題

この "指さし問題では、推測で本当にすべてを理解しなければ、多くの人々を混乱させると言うことができます。実際、"これ "のポイントは非常に規則的です

呼び出しオブジェクトがあります

は this参照の最も一般的な問題で、呼び出すオブジェクトが明らかな場合、thisはそのオブジェクトに向けられます。


明示的に呼び出されない場合


、アロー機能

アロー関数のthisは、理解されているものと全く同じではありません。アロー関数のthis指定はアロー関数の thisへの参照は、アロー関数が作成された時の thisへの参照と同じです。言い換えると、アロー関数の thisは、そのアロー関数が作成された時の thisを継承します。


、オブジェクトの新規作成

newキーワードはクラスの生成によく使われますが、クラスの機能は、newがインスタンスを生成する際に発生する一連の操作によってのみ実現されます。

1.新しいオブジェクトの構築

2.インスタンス・オブジェクトのプロトタイプをコンストラクタのプロトタイプにバインドします。

3.インスタンス・オブジェクトに thisをバインドします。

4.構築されたオブジェクトを返します

リファレンスの喪失

this "を持つ関数が別の変数に代入されて呼び出されると、thisの参照は失われます。


今のところ、矢印関数 thisが何を指しているのかを見分ける方法は、その辞書スコープ(グローバルスコープか関数スコープか)を見ることです。

アプリケーション/コール/バインド


callとapplyはどちらも thisのポイントを変更しますが、違いはその後に続く引数にあります。callは複数の引数を続けることができ、applyは配列を続けます。

しかし、bindとapply/callの最大の違いは、thisをバインドするときに実行するかどうかです。apply/callはthisをバインドすると同時に、バインドされた関数が再度実行されます。

ES6におけるオブジェクト操作の更新

簡単な定義

キー値とキーが同じ名前の場合は、キー名のみを記述することができ、キー名として[変数]という形式も使用できます。


集合データ構造

セットに格納されたデータは重複せず、セット内の数字は順序がなく一意です。

重複した要素を含む配列をsetパラメータとして渡すと、重複を取り除いた配列が返されます。配列への展開

集合を配列に変換する方法:


マップデータ構造

キーと値のペアのデータ構造は辞書と呼ばれ、その重要な特徴は、インデックス化された値に基づいて追加、削除、および変更操作を実行することです。

増加:map.set(1,2) 最初の値がキー名、2番目の値がキー値

delete: map.delete(インデックス) check: map.get(インデックス)

文字列テンプレート

es5では、文字列と変数のスプライスを実現するために'',+を使って文字列のスプライスを行いますが、気をつけないと記号がないためにスプライスがおかしくなったり、フォーマットが理想的でなかったりします。


文字列テンプレートにスプライス変数を実装できるだけでなく、複雑な論理判定や改行の制御も可能です。


以上のことから、スプライシング機能だけでなく、スプライシング前の複雑な判定処理も実現できることがわかります。


最後に、文字列テンプレートによって、文字列の改行出力の効果を得ることができます。

ES6ホワイトアウト

数値の文字列をきれいに出力するために、不足するビットを埋めるために文字を使用します。例えば、以下の関数のように、ビットを埋めるために0を使用します。


しかし、この補完的なアプローチは柔軟性に欠け、複雑です。ES6には、この状況をうまく処理するためのAPIがあります。


padStartはヘッダ内のパディングを示し、最初のパラメータは値文字列のビット数、2番目のパラメータはパディングに必要な文字です。

課題の分解

分解代入は、配列やオブジェクトから値を取り出して代入するのに非常に便利です。実際、どのようなデータ型を分解して代入することができるのか、トラバース可能なデータオブジェクトを分解して代入することができます。

配列の分解代入


オブジェクトの脱構築的割り当てについて

オブジェクトの分解された割り当てについては、その割り当ての性質を知ることが重要で、それはキーの値に基づいて値を検索し、再割り当てすることです。

Read next

Vueソースコードのビルド処理

Vueのバージョンは2.6.11です。まず、ライブラリのソースコードを解析するには、そのライブラリのソースコードから解析する必要があります。 vueのソースコードでbuildコマンドを実行することが、実はrunningに相当することがわかります。 build.jsが多くの関連モジュールを導入していることがわかります。

Jul 20, 2020 · 4 min read