目次
それは典型的なAngularJSコントローラーです。 HTTP要求を実行し、JSONファイルからデータを取得し、現在のスコープに渡します。 TODOCTRL関数を実行しません。引数を渡す機会はありません。フレームワークはそうします。それで、これらの$スコープと$ http変数はどこから来たのでしょうか?それは非常にクールな機能であり、ブラックマジックに非常に似ています。それがどのように行われているか見てみましょう。
クレイジーな反応テンプレート
ホームページ ウェブフロントエンド jsチュートリアル JavaScriptの魔法を明らかにします

JavaScriptの魔法を明らかにします

Feb 21, 2025 am 09:38 AM

JavaScriptの魔法を明らかにします

毎日たくさんのツールを使用しています。さまざまなライブラリとフレームワークが私たちの毎日の仕事の一部です。ボンネットの下で何が起こっているのかわからなくても、すべてのプロジェクトのホイールを再発明したくないので、それらを使用します。この記事では、最も人気のあるライブラリで起こっている魔法のプロセスのいくつかを明らかにします。また、彼らの動作を再現できるかどうかも確認します

キーテイクアウト

    jqueryのようなJavaScriptライブラリは、ネストされた要素のような複雑なケースを正しく処理することにより、文字列から要素を作成するなど、DOM操作を簡素化します。
  • AngularJSの依存関係注入システムは、明示的な合格せずに依存関係を魔法のように管理します。インジェクターパターンを使用して、実行時に依存関係を動的に提供します。
  • ember.jsは、計算されたプロパティでJavaScriptオブジェクトを強化し、プロパティが機能のように動作できるようにし、依存関係が変更されたときに自動的に更新します。
  • ReactのJSX構文により、JavaScriptにHTMLを埋め込むことができます。HTMLは、ReactのJSXトランスによって処理され、動的UIコンポーネントを作成します。
  • この記事は、依存関係の注入と計算された特性のためのカスタムソリューションを示しており、開発者がプロ​​ジェクトで同様の機能をどのように実装できるかを示しています。
  • 人気のあるJavaScriptフレームワークの基礎となるメカニズムを理解することで、開発者がより効率的で保守可能なコードを作成できるようになります。
  • 文字列からdom要素を作成
  • シングルページアプリケーションの増加により、JavaScriptで多くのことを行っています。アプリケーションのロジックの大部分がブラウザに移動されました。ページ上の要素を生成または交換することは一般的なタスクです。以下に示すものと同様のコードは非常に一般的になりました。
  • 結果は、ドキュメントの本文に追加された新しい
    要素です。この単純な操作は、1行のjQueryで行われます。 jQueryがなければ、コードはもう少し複雑ですが、それほど多くはありません:

    一時的な
    要素を作成する独自のユーティリティメソッドStringtodomを定義しました。私たちはそのinnerhtmlプロパティを変更し、最終的に私たちは実際に必要なものである最初の子供を単に返しました。同じように機能しました。ただし、次のコードではさまざまな結果が見られます。

    視覚的には、ページに違いはありません。ただし、Chromeの開発者ツールで生成されたマークアップを確認すると、興味深い結果が得られます。

    <span>var text = $('<div>Simple text</div>');
    </span>
    <span>$('body').append(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    stringtodom関数は、実際の

    タグではなく、テキストノードのみを作成したようです。しかし、同時に、jQueryはなんとかそれをすることができました。問題は、HTML要素を含む文字列がブラウザのパーサーを介して実行されることです。そのパーサーは、正しいコンテキストに配置されていないタグを無視し、テキストノードのみを取得します。テーブルのないテーブルの列は、ブラウザには無効です。 jQueryは、正しいコンテキストを作成することで問題を正常に解決し、必要な部分のみを抽出します。ライブラリのコードを少し掘り下げると、このようなマップが表示されます:

    <span>var text = $('<div>Simple text</div>');
    </span>
    <span>$('body').append(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    特別な処理を必要とするすべての要素には、配列が割り当てられています。アイデアは、適切なDOM要素を構築し、必要なものを取得するためにネストのレベルに依存することです。たとえば、 要素の場合、 子供を持つテーブルを作成する必要があります。したがって、2つのレベルのネストがあります

    マップがあるため、最終的にどのようなタグが必要かを確認する必要があります。次のコードでは、

    のtrを抽出します

    残りは適切なコンテキストを見つけて、DOM要素を返しています。これは、関数stringtodom:
    <span>var stringToDom = function(str) {
    </span>  <span>var temp = document.createElement('div');
    </span>
      temp<span>.innerHTML = str;
    </span>  <span>return temp.childNodes[0];
    </span><span>}
    </span><span>var text = stringToDom('<div>Simple text</div>');
    </span>
    <span>document.querySelector('body').appendChild(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    の最終的なバリアントです

    文字列にタグがあるかどうかを確認していることに注意してください - 一致!= null。そうでない場合は、単にテキストノードを返します。一時的な
    の使用はまだありますが、今回はブラウザが有効なDOMツリーを作成できるように適切なタグを渡しています。最終的には、時間ループを使用することで、必要なタグに到達するまで深く深く進んでいます。
    <span>var tableRow = $('<tr><td>Simple text</td></tr>');
    </span><span>$('body').append(tableRow);
    </span>
    <span>var tableRow = stringToDom('<tr><td>Simple text</td></tr>');
    </span><span>document.querySelector('body').appendChild(tableRow);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ここに、実装を示すCodepenがあります:

    CodepenでKrasimir Tsonev(@krasimir)によるPen xlcgnを参照してください。

    素晴らしいAngularJS依存関係の注入を調査して続けましょう

    AngularJS依存性注入を明らかにします

    angularjsの使用を開始すると、双方向のデータバインディングに感銘を与えます。 2番目のことは、その魔法の依存噴射です。簡単な例を次に示します:

    それは典型的なAngularJSコントローラーです。 HTTP要求を実行し、JSONファイルからデータを取得し、現在のスコープに渡します。 TODOCTRL関数を実行しません。引数を渡す機会はありません。フレームワークはそうします。それで、これらの$スコープと$ http変数はどこから来たのでしょうか?それは非常にクールな機能であり、ブラックマジックに非常に似ています。それがどのように行われているか見てみましょう。

    システムにユーザーを表示するJavaScript関数があります。同じ関数は、生成されたHTMLを配置するためにDOM要素にアクセスし、データを取得するAJAXラッパーにアクセスする必要があります。例を簡素化するために、データとHTTPの要求を模倣します。

    <span>var text = $('<div>Simple text</div>');
    </span>
    <span>$('body').append(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    コンテンツホルダーとして

    タグを使用します。 AjaxWrapperはリクエストをシミュレートするオブジェクトであり、DataMockupはユーザーを含む配列です。使用する関数は次のとおりです
    <span>var stringToDom = function(str) {
    </span>  <span>var temp = document.createElement('div');
    </span>
      temp<span>.innerHTML = str;
    </span>  <span>return temp.childNodes[0];
    </span><span>}
    </span><span>var text = stringToDom('<div>Simple text</div>');
    </span>
    <span>document.querySelector('body').appendChild(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    そしてもちろん、displayUsers(body、ajaxwrapper)を実行すると、コンソールでリクエストされているページに3つの名前が表示されます。私たちの方法には、ボディとajaxwrapperの2つの依存関係があると言えます。したがって、アイデアは、議論を渡さずに関数を機能させることです。つまり、DisplayUsers()を呼び出すことで同じ結果を得る必要があります。これまでのところコードでそれを行うと、結果は次のとおりです。

    Ajaxパラメーターが定義されていないため、

    そしてそれは正常です。
    <span>var tableRow = $('<tr><td>Simple text</td></tr>');
    </span><span>$('body').append(tableRow);
    </span>
    <span>var tableRow = stringToDom('<tr><td>Simple text</td></tr>');
    </span><span>document.querySelector('body').appendChild(tableRow);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    依存関係注入のメカニズムを提供するフレームワークのほとんどには、通常は

    injector

    という名前のモジュールがあります。依存関係を使用するには、そこに登録する必要があります。その後、ある時点で、当社のリソースは、同じモジュールによってアプリケーションのロジックに提供されます。 インジェクターを作成してみましょう:

    2つの方法は必要です。最初のものである登録は、リソース(依存関係)を受け入れ、内部に保存します。 2番目のものは、注入のターゲット、つまり依存関係を持つ関数とパラメーターとして受信する必要がある関数を受け入れます。ここでの重要な瞬間は、インジェクターが関数を呼び出すべきではないことです。それが私たちの仕事であり、私たちはそれをコントロールできるはずです。 Resolveメソッドでできることは、ターゲットをラップして呼び出す閉鎖を返すことです。たとえば、

    <span>var wrapMap = {
    </span>  <span>option: [1, '<select multiple="multiple">', '</select>'],
    </span>  <span>legend: [1, '<fieldset>', '</fieldset>'],
    </span>  <span>area: [1, '<map>', '</map>'],
    </span>  <span>param: [1, '<object>', '</object>'],
    </span>  <span>thead: [1, '<table>', '</table>'],
    </span>  <span>tr: [2, '<table><tbody>', '</tbody></table>'],
    </span>  <span>col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
    </span>  <span>td: [3, '<table><tbody><tr>', '</tr></tbody></table>'],
    </span>  <span>_default: [1, '<div>', '</div>']
    </span><span>};
    </span>wrapMap<span>.optgroup = wrapMap.option;
    </span>wrapMap<span>.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
    </span>wrapMap<span>.th = wrapMap.td;</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    そのアプローチを使用して、必要な依存関係を持つ関数を呼び出す機会があります。同時に、アプリケーションのワークフローを変更していません。インジェクターはまだ独立した​​ものであり、ロジック関連の機能を保持していません。

    もちろん、displayUsers関数をResolveメソッドに渡すことは役に立ちません。
    <span>var match = <span>/&lt;<span>\s*\w.*?&gt;</span>/g</span>.exec(str);
    </span><span>var tag = match[0].replace(<span>/&lt;/g</span>, '').replace(<span>/&gt;/g</span>, '');</span>
    ログイン後にコピー
    ログイン後にコピー

    それでも同じエラーが発生します。次のステップは、合格したターゲットが必要とするものを見つけることです。その依存関係は何ですか?そして、これがAngularjsから採用できるトリッキーな部分です。繰り返しますが、フレームワークのコードを少し掘り下げて、これを見つけました:

    実装の詳細に似ているため、意図的にいくつかの部品をスキップしました。それが私たちにとって興味深いコードです。注釈関数は、Resolveメソッドのようなものです。渡されたターゲット関数を文字列に変換し、コメント(存在する場合)を削除し、引数を抽出します。それを使用して、結果を見てみましょう:
    <span>var stringToDom = function(str) {
    </span>  <span>var wrapMap = {
    </span>    <span>option: [1, '<select multiple="multiple">', '</select>'],
    </span>    <span>legend: [1, '<fieldset>', '</fieldset>'],
    </span>    <span>area: [1, '<map>', '</map>'],
    </span>    <span>param: [1, '<object>', '</object>'],
    </span>    <span>thead: [1, '<table>', '</table>'],
    </span>    <span>tr: [2, '<table><tbody>', '</tbody></table>'],
    </span>    <span>col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
    </span>    <span>td: [3, '<table><tbody><tr>', '</tr></tbody></table>'],
    </span>    <span>_default: [1, '<div>', '</div>']
    </span>  <span>};
    </span>  wrapMap<span>.optgroup = wrapMap.option;
    </span>  wrapMap<span>.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
    </span>  wrapMap<span>.th = wrapMap.td;
    </span>  <span>var element = document.createElement('div');
    </span>  <span>var match = <span>/<<span>\s*\w.*?></span>/g</span>.exec(str);
    </span>
      <span>if(match != null) {
    </span>    <span>var tag = match[0].replace(<span>/</g</span>, '').replace(<span>/>/g</span>, '');
    </span>    <span>var map = wrapMap[tag] || wrapMap._default, element;
    </span>    str <span>= map[1] + str + map[2];
    </span>    element<span>.innerHTML = str;
    </span>    <span>// Descend through wrappers to the right content
    </span>    <span>var j = map[0]+1;
    </span>    <span>while(j--) {
    </span>      element <span>= element.lastChild;
    </span>    <span>}
    </span>  <span>} else {
    </span>    <span>// if only text is passed
    </span>    element<span>.innerHTML = str;
    </span>    element <span>= element.lastChild;
    </span>  <span>}
    </span>  <span>return element;
    </span><span>}</span>
    ログイン後にコピー
    ログイン後にコピー

    ここにコンソールの出力があります:
    <span>function <span>TodoCtrl</span>($scope<span>, $http</span>) {
    </span>  $http<span>.get('users/users.json').success(function(data) {
    </span>    $scope<span>.users = data;
    </span>  <span>});
    </span><span>}</span>
    ログイン後にコピー
    ログイン後にコピー

    <span>var dataMockup = ['John', 'Steve', 'David'];
    </span><span>var body = document.querySelector('body');
    </span><span>var ajaxWrapper = {
    </span>  <span>get: function(path<span>, cb</span>) {
    </span>    <span>console.log(path + ' requested');
    </span>    <span>cb(dataMockup);
    </span>  <span>}
    </span><span>}</span>
    ログイン後にコピー

    argdeclアレイの2番目の要素を取得すると、必要な依存関係の名前が見つかります。名前を使用すると、インジェクターのストレージからリソースを配信できるため、まさにそれが必要なものです。これが私たちの目標をうまくカバーするバージョンです:

    <span>var text = $('<div>Simple text</div>');
    </span>
    <span>$('body').append(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    .split(/、?/g)を使用して文字列ドメル、ajaxを配列に変換していることに注意してください。その後、依存関係が登録されているかどうかを確認し、はいの場合はターゲット関数に渡すかどうかを確認します。インジェクターの外側のコードは次のようになります

    <span>var stringToDom = function(str) {
    </span>  <span>var temp = document.createElement('div');
    </span>
      temp<span>.innerHTML = str;
    </span>  <span>return temp.childNodes[0];
    </span><span>}
    </span><span>var text = stringToDom('<div>Simple text</div>');
    </span>
    <span>document.querySelector('body').appendChild(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    このような実装の利点は、多くの機能にDOM要素とAjaxラッパーを注入できることです。そのようなアプリケーションの構成を配布することもできます。クラスからクラスにオブジェクトを渡す必要はありません。それはただの登録と解決方法です。

    もちろん、私たちのインジェクターは完璧ではありません。たとえば、スコープ定義のサポートなど、改善の余地がまだあります。現在、ターゲット関数は新しく作成されたスコープで呼び出されますが、通常は独自のスコープを渡したいと思うでしょう。また、依存関係とともにカスタム引数を送信することもサポートする必要があります。

    削除後にコードを動作させたい場合、インジェクターはさらに複雑になります。私たちが知っているように、ミニファイヤーは関数、変数、さらにはメソッドの引数の名前を置き換えます。そして、私たちのロジックはこれらの名前に依存しているため、回避策について考える必要があります。考えられる解決策の1つは、Angularjsから再び登場することです:

    displayUsersのみの代わりに、実際の依存関係の名前を渡しています。
    <span>var tableRow = $('<tr><td>Simple text</td></tr>');
    </span><span>$('body').append(tableRow);
    </span>
    <span>var tableRow = stringToDom('<tr><td>Simple text</td></tr>');
    </span><span>document.querySelector('body').appendChild(tableRow);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    実際の例:

    CodepenでKrasimir Tsonev(@krasimir)によるペンBxdarを参照してください。 Emberの計算されたプロパティの採用

    Emberは、最近で最も人気のあるフレームワークの1つです。たくさんの便利な機能があります。特に興味深いものがあります - 計算されたプロパティ。要約すると、計算されたプロパティは、プロパティとして機能する関数です。 Emberのドキュメントから撮影した簡単な例を見てみましょう:

    FirstNameおよびLastNameプロパティを備えたクラスがあります。計算されたプロパティのフルネームは、その人のフルネームを含む連結文字列を返します。奇妙なことは、フルネームに適用された関数に対して.propertyメソッドを使用する部分です。私は個人的にそれを他のどこにも見ませんでした。そして、繰り返しになりますが、フレームワークのコードをすばやく見て、魔法が明らかになります:

    <span>var wrapMap = {
    </span>  <span>option: [1, '<select multiple="multiple">', '</select>'],
    </span>  <span>legend: [1, '<fieldset>', '</fieldset>'],
    </span>  <span>area: [1, '<map>', '</map>'],
    </span>  <span>param: [1, '<object>', '</object>'],
    </span>  <span>thead: [1, '<table>', '</table>'],
    </span>  <span>tr: [2, '<table><tbody>', '</tbody></table>'],
    </span>  <span>col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
    </span>  <span>td: [3, '<table><tbody><tr>', '</tr></tbody></table>'],
    </span>  <span>_default: [1, '<div>', '</div>']
    </span><span>};
    </span>wrapMap<span>.optgroup = wrapMap.option;
    </span>wrapMap<span>.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
    </span>wrapMap<span>.th = wrapMap.td;</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    ライブラリは、新しいプロパティを追加することにより、グローバル関数オブジェクトのプロトタイプを微調整します。クラスの定義中にロジックを実行するのは素晴らしいアプローチです。

    Emberは、GettersとSetterを使用して、オブジェクトのデータを使用して動作します。これにより、実際の変数に到達するために1つのレイヤーが1つあるため、計算されたプロパティの実装が簡素化されます。ただし、プレーンJavaScriptオブジェクトで計算されたプロパティを使用できれば、さらに興味深いでしょう。たとえば、

    のように
    <span>var text = $('<div>Simple text</div>');
    </span>
    <span>$('body').append(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    名前は通常のプロパティとして使用されますが、実際には、firstNameとlastNameを取得または設定する関数です。

    JavaScriptのビルドイン機能があり、そのアイデアを実現するのに役立ちます。次のスニペットをご覧ください:

    <span>var stringToDom = function(str) {
    </span>  <span>var temp = document.createElement('div');
    </span>
      temp<span>.innerHTML = str;
    </span>  <span>return temp.childNodes[0];
    </span><span>}
    </span><span>var text = stringToDom('<div>Simple text</div>');
    </span>
    <span>document.querySelector('body').appendChild(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    object.definePropertyメソッドは、スコープ、プロパティの名前、ゲッター、セッターを受け入れることができます。私たちがしなければならないのは、2つの方法の本体を書くことです。そして、それだけです。上記のコードを実行できるようになり、期待される結果が得られます。

    object.definePropertyはまさに必要なものですが、開発者に毎回それを書くことを強制したくありません。ポリフィルを提供したり、追加のロジックを実行したり、そのようなものを提供する必要がある場合があります。理想的なケースでは、Emberに似たインターフェイスを提供したいと考えています。クラス定義の一部は1つの関数のみです。このセクションでは、オブジェクトを処理し、何らかの形で名前関数を同じ名前のプロパティに変換するComputizeedというユーティリティ関数を書きます。
    <span>var tableRow = $('<tr><td>Simple text</td></tr>');
    </span><span>$('body').append(tableRow);
    </span>
    <span>var tableRow = stringToDom('<tr><td>Simple text</td></tr>');
    </span><span>document.querySelector('body').appendChild(tableRow);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    名前メソッドをセッターとして、同時にゲッターと同時に使用したいと考えています。これは、Emberの計算されたプロパティに似ています

    ここで、関数オブジェクトのプロトタイプに独自のロジックを追加しましょう:
    <span>var wrapMap = {
    </span>  <span>option: [1, '<select multiple="multiple">', '</select>'],
    </span>  <span>legend: [1, '<fieldset>', '</fieldset>'],
    </span>  <span>area: [1, '<map>', '</map>'],
    </span>  <span>param: [1, '<object>', '</object>'],
    </span>  <span>thead: [1, '<table>', '</table>'],
    </span>  <span>tr: [2, '<table><tbody>', '</tbody></table>'],
    </span>  <span>col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
    </span>  <span>td: [3, '<table><tbody><tr>', '</tr></tbody></table>'],
    </span>  <span>_default: [1, '<div>', '</div>']
    </span><span>};
    </span>wrapMap<span>.optgroup = wrapMap.option;
    </span>wrapMap<span>.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
    </span>wrapMap<span>.th = wrapMap.td;</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    上記の行を追加すると、すべての関数定義の最後に.computed()を追加できます。

    その結果、名前プロパティには機能が含まれなくなりましたが、古い関数で満たされたTrueおよびFUNCプロパティに等しいプロパティを計算したオブジェクトです。本当の魔法は、コンピューターヘルパーの実装で起こります。オブジェクトのすべてのプロパティを通過し、Object.definePropertyを使用します。

    <span>var match = <span>/&lt;<span>\s*\w.*?&gt;</span>/g</span>.exec(str);
    </span><span>var tag = match[0].replace(<span>/&lt;/g</span>, '').replace(<span>/&gt;/g</span>, '');</span>
    ログイン後にコピー
    ログイン後にコピー
    元のプロパティ名を削除していることに注意してください。一部のブラウザObject.DefinePropertyでは、まだ定義されていないプロパティでのみ動作します。

    .computed()関数を使用するユーザーオブジェクトの最終バージョンはあります。

    <span>var stringToDom = function(str) {
    </span>  <span>var wrapMap = {
    </span>    <span>option: [1, '<select multiple="multiple">', '</select>'],
    </span>    <span>legend: [1, '<fieldset>', '</fieldset>'],
    </span>    <span>area: [1, '<map>', '</map>'],
    </span>    <span>param: [1, '<object>', '</object>'],
    </span>    <span>thead: [1, '<table>', '</table>'],
    </span>    <span>tr: [2, '<table><tbody>', '</tbody></table>'],
    </span>    <span>col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
    </span>    <span>td: [3, '<table><tbody><tr>', '</tr></tbody></table>'],
    </span>    <span>_default: [1, '<div>', '</div>']
    </span>  <span>};
    </span>  wrapMap<span>.optgroup = wrapMap.option;
    </span>  wrapMap<span>.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
    </span>  wrapMap<span>.th = wrapMap.td;
    </span>  <span>var element = document.createElement('div');
    </span>  <span>var match = <span>/<<span>\s*\w.*?></span>/g</span>.exec(str);
    </span>
      <span>if(match != null) {
    </span>    <span>var tag = match[0].replace(<span>/</g</span>, '').replace(<span>/>/g</span>, '');
    </span>    <span>var map = wrapMap[tag] || wrapMap._default, element;
    </span>    str <span>= map[1] + str + map[2];
    </span>    element<span>.innerHTML = str;
    </span>    <span>// Descend through wrappers to the right content
    </span>    <span>var j = map[0]+1;
    </span>    <span>while(j--) {
    </span>      element <span>= element.lastChild;
    </span>    <span>}
    </span>  <span>} else {
    </span>    <span>// if only text is passed
    </span>    element<span>.innerHTML = str;
    </span>    element <span>= element.lastChild;
    </span>  <span>}
    </span>  <span>return element;
    </span><span>}</span>
    ログイン後にコピー
    ログイン後にコピー

    フルネームを返す関数は、FirstNameとLastNameを変更するために使用されます。それは、合格した引数のチェックと最初の議論の処理の背後にあるアイデアです。それが存在する場合、私たちはそれを分割し、通常のプロパティに値を適用します。

    すでに目的の使用法について言及しましたが、もう一度見てみましょう:
    <span>function <span>TodoCtrl</span>($scope<span>, $http</span>) {
    </span>  $http<span>.get('users/users.json').success(function(data) {
    </span>    $scope<span>.users = data;
    </span>  <span>});
    </span><span>}</span>
    ログイン後にコピー
    ログイン後にコピー

    次のCodepenは、実際の作業を示しています

    CodepenでKrasimir Tsonev(@krasimir)によるPen Ahpqoを参照してください。

    クレイジーな反応テンプレート

    おそらく、Facebookのフレームワークの反応について聞いたことがあるでしょう。それは、すべてがコンポーネントであるという考えを中心に構築されています。興味深いのは、コンポーネントの定義です。次の例を見てみましょう:

    <span>var text = $('<div>Simple text</div>');
    </span>
    <span>$('body').append(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    最初に考え始めるのは、これがJavaScriptであるということですが、それは無効なものです。レンダリング関数があり、おそらくエラーが発生します。ただし、このコードは、カスタムタイプ属性を備えた<script>タグに入れられることです。ブラウザはそれを処理しません。つまり、エラーから安全であることを意味します。 Reactには、有効なJavaScriptに書かれたコードを変換する独自のパーサーがあります。 Facebookの開発者は、XML Like Language <em> jsx と呼ばれていました。 JSXトランスは390Kで、約12000行のコードが含まれています。だから、それは少し複雑です。このセクションでは、シンプルなものを作成しますが、それでも非常に強力です。 ReactのスタイルでHTMLテンプレートを解析するJavaScriptクラス。 </script>

    Facebookが行ったアプローチは、JavaScriptコードとHTMLマークアップを混合することです。したがって、次のテンプレートがあるとしましょう

    およびそれを使用するコンポーネント:
    <span>var stringToDom = function(str) {
    </span>  <span>var temp = document.createElement('div');
    </span>
      temp<span>.innerHTML = str;
    </span>  <span>return temp.childNodes[0];
    </span><span>}
    </span><span>var text = stringToDom('<div>Simple text</div>');
    </span>
    <span>document.querySelector('body').appendChild(text);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    アイデアは、テンプレートのIDを指摘し、適用すべきデータを定義するということです。実装の最後の部分は、2つの要素をマージする実際のエンジンです。エンジンと呼んで、そのように起動しましょう:
    <span>var tableRow = $('<tr><td>Simple text</td></tr>');
    </span><span>$('body').append(tableRow);
    </span>
    <span>var tableRow = stringToDom('<tr><td>Simple text</td></tr>');
    </span><span>document.querySelector('body').appendChild(tableRow);</span>
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

以上がJavaScriptの魔法を明らかにしますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

JavaScriptエンジン:実装の比較 JavaScriptエンジン:実装の比較 Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

Python vs. JavaScript:学習曲線と使いやすさ Python vs. JavaScript:学習曲線と使いやすさ Apr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

C/CからJavaScriptへ:すべてがどのように機能するか C/CからJavaScriptへ:すべてがどのように機能するか Apr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptとWeb:コア機能とユースケース JavaScriptとWeb:コア機能とユースケース Apr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScript in Action:実際の例とプロジェクト JavaScript in Action:実際の例とプロジェクト Apr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptエンジンの理解:実装の詳細 JavaScriptエンジンの理解:実装の詳細 Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:コミュニティ、ライブラリ、リソース Python vs. JavaScript:コミュニティ、ライブラリ、リソース Apr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

Python vs. JavaScript:開発環境とツール Python vs. JavaScript:開発環境とツール Apr 26, 2025 am 12:09 AM

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

See all articles