フロントエンドの上級者向けコースでは、JavaScript のストレージ機能の使い方を学習します。

フロントエンドの上級者向けコースでは、JavaScript のストレージ機能の使い方を学習します。

序文

どの SaaS 企業も、独自のローコード プラットフォームを持つ必要があります。ビジュアル ローコード フロントエンド開発のプロセスでは、多くの興味深い技術要件が見つかります。これらの要件を解決するプロセスでは、多くの場合、多くの利益が得られます。今日は、Dooring - javascript 関数ストレージの開発プロセスで遭遇したフロントエンドの技術的問題を共有しましょう。

背景

フロントエンド ページを構築するには、次の 3 つの要素が必要であることは誰もが知っています。

  • 要素 (UI)
  • データ
  • イベント/インタラクション

データドリブンビューの時代では、これら 3 つの要素の関係は、多くの場合、次のようになります。

ビジュアル構築プラットフォームの設計アイデアは、多くの場合、上記のプロセスに基づいています。ユーザーがビューを作成して対話するためのエディター環境を提供する必要があります。ユーザーが保存する最終製品は、次のようになります。

{
    "name": "ドアリングフォーム",
    "背景色": "#666",
    "share_url": "http://xxx.cn",
    "マウントイベント": [
        {
            "id": "123",
            "関数": () => {
                // 初期化ロジック GamepadHapticActuator();
            },
            "ソースデータ": []
        }
    ]、
    "体": [
        {
            "名前": "ヘッダー",
            "イベント": [
                {
                    "id": "123",
                    「タイプ」:「クリック」、
                    "関数": () => {
                        // コンポーネントのカスタムインタラクションロジック showModal();
                    }
                }
            ]
        }
    ]
}

質問は、JSON 文字列 (JSON.stringify シリアル化を通じて) を保存できるが、関数を一緒に保存するにはどうすればよいかということです。関数を保存した後、ページがレンダリングされるときに js がこの関数を正常に実行するようにするにはどうすればよいでしょうか。

実施計画の考え方

js オブジェクトを json に変換するには JSON.stringify を使用できることをご存じでしょうが、次のような制限もあります。

  1. 値に toJSON() メソッドがある場合、toJson() はどの値がシリアル化されるかを定義します。
  2. 配列以外のオブジェクトのプロパティは、シリアル化された文字列内で特定の順序で表示されるとは限りません。
  3. ブール値、数値、文字列のラップされたオブジェクトは、シリアル化時に自動的に対応する元の値に変換されます。
  4. 未定義、任意の関数、およびシンボルの値は、シリアル化中に無視されるか (配列以外のオブジェクトのプロパティ値に表示される場合)、null に変換されます (配列に表示される場合)。関数とundefinedを別々に変換すると、JSON.stringify(function(){})やJSON.stringify(undefined)のようにundefinedが返されます。
  5. キーとしてシンボルを持つすべてのプロパティは、replacer パラメータで必須であっても完全に無視されます。
  6. Date は toJSON() を呼び出して文字列に変換します (Date.toISOString() と同じ)。そのため、文字列として扱われます。
  7. NaN および Infinity 形式の値および null は null として扱われます。
  8. Map/Set/WeakMap/WeakSetを含む他のタイプのオブジェクトは、列挙可能なプロパティのみをシリアル化します。

項目 4 を見ると、シリアル化するオブジェクトに関数が含まれている場合、その関数は無視されることがわかります。したがって、JSON.stringify を使用して関数を保存できないのは常識ですが、他に方法はあるのでしょうか。

まず関数を文字列に変換し、次に JSON.stringify でシリアル化してバックエンドに保存し、最後にコンポーネントが使用されるときに eval または Function を使用して文字列を関数に変換することが考えられます。一般的なプロセスは次のとおりです。

はい、理想は美しいですが、現実は_______です。

次に、キーリンク func2string と string2func がどのように実装されているかを分析しましょう。

js ストレージ機能ソリューション設計

JSON API に詳しい方は、JSON.stringify が 3 つのパラメータをサポートし、2 番目のパラメータ replacer が関数または配列になる可能性があることをご存知かもしれません。関数としては、キーと値という 2 つのパラメーターがあり、どちらもシリアル化されています。 関数は、以下に示すように、JSON 文字列で値を返す必要があります。

  • 数値が返された場合は、対応する文字列に変換され、属性値として JSON 文字列に追加されます。
  • 文字列が返された場合、その文字列はプロパティ値としてJSON文字列に追加されます。
  • ブール値が返される場合、プロパティ値として「true」または「false」が JSON 文字列に追加されます。
  • その他のオブジェクトが返される場合、そのオブジェクトは各プロパティの replacer メソッドを呼び出して、JSON 文字列に再帰的にシリアル化されます。オブジェクトが関数である場合を除き、その場合には JSON 文字列にシリアル化されません。
  • undefined が返された場合、プロパティ値は JSON 文字列に出力されません。

したがって、値の型が関数であるデータを 2 番目の関数パラメータに変換できます。次のように:

定数文字列化 = (obj) => {
    JSON.stringify(obj, (k, v) => { を返す
      if(typeof v === '関数') {
          `${v}` を返す
      }
      リターンv
    })
}

この方法では、関数をバックエンドに保存できるようです。次に、関数文字列を使用して json を逆シリアル化する方法を見てみましょう。

関数を文字列に変換したので、逆解析するときにどの文字列を関数に変換する必要があるかを知る必要があります。関数に対して何もしない場合は、手動で識別する必要がある場合があります。

人肉認識の欠点は、関数特性を持つ文字列を抽出するために正規表現を使用する必要があることですが、関数の書き方は多種多様であり、多くの状況を考慮する必要があります。関数特性を持つ文字列が必ず関数であるという保証はありません。

そこで、複雑な正規表現を書かずに関数を抽出するより簡単な方法に変更しました。この方法では、関数がシリアル化されるときに識別子を挿入して、次のように、どの文字列を関数として解析する必要があるかを知ることができます。

文字列化: 関数(obj: any, space: number | string, error: (err: Error | unknown) => {}) {
        試す {
            JSON.stringify(obj, (k, v) => { を返す
                if(typeof v === '関数') {
                    `${this.FUNC_PREFIX}${v}` を返します
                }
                リターンv
            }、 空間)
        } キャッチ(エラー) {
            エラー && エラー(err)
        }
}

this.FUNC_PREFIX は、JSON.parse を使用するときに関数をすばやく解析できるように定義した識別子です。JSON.parse は、JSON.stringify の 2 番目のパラメータに似た 2 番目のパラメータもサポートしています。次のように変換できます。

解析: 関数(jsonStr: 文字列、エラー: (err: エラー | 不明) => {}) {
        試す {
            JSON.parse(jsonStr, (キー, 値) を返します => {
                if(値 && 値のタイプ === '文字列') {
                    戻り値.indexOf(this.FUNC_PREFIX) > -1 ? 新しい Function(`return ${value.replace(this.FUNC_PREFIX, '')}`)() : 値
                }
                戻り値
            })
        } キャッチ(エラー) {
            エラー && エラー(err)
        }
    }

新しい関数は文字列を js 関数に変換できます。文字列パラメータのみを受け入れます。オプションのパラメータはメソッドの入力パラメータであり、必須のパラメータはメソッド本体の内容です。わかりやすい例:

上記コードの関数本体の内容は次のとおりです。

新しい関数(`return ${value.replace(this.FUNC_PREFIX, '')}`)()

return を使う理由は、元の関数をそのまま戻すためです。eval も使えますが、世論としては慎重に使った方が良いでしょう。

上記のソリューションでは、フロントエンドストレージ機能はすでに実現されていますが、よりエンジニアリング性と堅牢性を高めるには、より多くのユーザーがすぐにライブラリを使用できるように、多くの追加処理と最適化が必要です。

やっと

より多くの人がこの関数を直接使用できるようにするために、完全な JSON シリアル化ソリューションをクラス ライブラリにカプセル化しました。

サポート機能は次のとおりです。

  • stringify はネイティブ JSON に基づくシリアル化関数とエラーコールバックをサポートします。stringify
  • parseはネイティブJSON.parseに基づくデシリアライズ関数とエラーコールバックをサポートします。
  • funcParse は、js オブジェクト内の関数をワンクリックでシリアル化し、js オブジェクトの型を変更せずに維持します。

インストール方法は以下の通りです。

# または npm install xijs
糸を追加 xijs

使用:

'xijs' から { parser } をインポートします。

定数a = {
    x: 12,
    b: 関数() {
      警告(1)
    }
 }
 
 定数 json = parser.stringify(a);
 定数 obj = parser.parse(json);
 //メソッドobj.b()を呼び出します。

要約する

これで、JavaScript を使用して関数を保存する方法に関するこの記事は終了です。JavaScript を使用して関数を保存する方法に関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • JS 配列の高度な例 [いくつかの配列関数の使用法]
  • 高度な JS 関数継承の使用例の分析
  • 高度な JS 関数プロトタイプの使用例の分析
  • JavaScript の分割関数と結合関数の高度な使用方法のヒント
  • JavaScript 関数の高度な説明

<<:  CSSのclip-pathプロパティを使用して不規則なグラフィックを表示する

>>:  テキストエリアタグはサイズ変更できず、マウスでドラッグすることもできません

推薦する

ユニアプリとミニプログラム(画像とテキスト)を下請けする方法を教えます

目次1. ミニプログラム下請け2. Uniapp 下請けアプレット下請けの手順: 1. manife...

Vue で配列をクリアするいくつかの方法 (要約)

目次1. はじめに2. データを消去するいくつかの方法2.1 ref() の使用2.2 スライスの使...

Vue のすべてのカプセル化方法の簡単な概要

目次1. カプセル化API 2. グローバルツールコンポーネントを登録する3. グローバル関数をカプ...

JavaScript の document.activeELement フォーカス要素の紹介

目次1. デフォルトの焦点はボディにあります2. テキストボックスのフォーカスを手動で取得する3. ...

CentOS 7 に Percona Server+MySQL をインストールする

1. 環境の説明(1) CentOS-7-x86_64、カーネルバージョン uname -r は、 ...

モバイルデバイスでインラインスクロールを実装するための4つのソリューションの詳細な説明

ニーズの発見領域の一部のみスクロールでき、残りの部分は移動できない場合、どのような方法を使用しますか...

jQueryはバウンドボールゲームを実装します

この記事では、バウンドボールゲームを実装するためのjQueryの具体的なコードを参考までに共有します...

Windows 10 の仮想マシンに Mac システムをインストールするグラフィック チュートリアル

1. 仮想マシンバージョン15.5.1をダウンロードする公式サイトから直接最新バージョンをダウンロー...

Dockerでnginxをデプロイし、設定ファイルを変更する方法

Dockerでnginxをデプロイするのはとても簡単ですたった 1 行のコマンド: docker 実...

Windows 10 で MySQL をダウンロードするための詳細なチュートリアル

MySQL のバージョンは、Enterprise Edition と Community Editi...

GDBデバッグMySQL実戦ソースコードコンパイルとインストール

ソースコードをダウンロード git クローン https://github.com/mysql/my...

Element PlusはAffixを実装します

目次1. コンポーネントの紹介2. ソースコード分析2.1 テンプレート2.2 スクリプト2.3 実...

Dockerコンテナ間で通信する3つの方法

Docker コンテナは互いに分離されており、相互にアクセスできないことは誰もが知っていますが、依存...

Dockerコンテナのディスクがいっぱいになった場合の状況のまとめ

序文この記事では、最近私が遭遇した 2 つの状況について説明します。今後、新たな発見があれば追加して...