Javascript 1.8

JavaScript 1.8は、主に機能的な愛好家のために、大量のおいしい構文糖を提供します。 しかし、この美しさを知っている開発者はほとんどいません。 もちろん、残念ながら、Chromeでもこれらすべての利点をサポートしているわけではありません(IEについて何と言えますか?)、しかし、Firefox 3以降のみです。



最も完全な情報は、 MDNに関する記事に記載されています。



また、jQueryの作者であるJohn Resigによる小さなながらも興味深い記事を翻訳しました。この記事では、Expression Closures、Generator Expressions、__ iterator __、Array Reduceなどの新機能をいくつか紹介しています。



//    - document.addEventListener("click", function() false, true); //    for ( let i in 3 ) alert( i ); //    100 ,   [ 0 for ( i in 100 ) ]; //    10*10 [[ i == j ? 1 : 0 for ( i in 10 ) ] for ( j in 10 )];
      
      







この記事は2007年に作成されましたが、ロシア語への翻訳は見つかりませんでした。一般的に、このトピックに関する情報はロシア語で十分です。 例のコードはすべて、Firefox 3以降で正常に機能します。



JavaScript 1.8の進捗



JavaScript 1.8の開発の進捗状況をフォローしていない場合は、Firefox 3のナイトリービルドに既にあるものの概要を簡単に紹介します。

これまでのところ、最新バージョンには3つの主要な機能が追加されており、さらにいくつかの機能が追加される予定です。 この「ライト」バージョンの主な目標は、現在のJavaScript実装を目的のJavaScript 2仕様に近づけることです。



語彙的クロージャー(式クロージャー)



語彙的クロージャーは最近トランクに追加されており、関数型プログラミングの愛好家にとって間違いなく興味深いものになります。 実際、単純な関数を記述するためのエレガントなエントリであり、言語を典型的なラムダ表記のように見せます。

異なる言語のラムダ関数の構文を見てみましょう。



Python:
 lambda x: x * x
      
      





Smalltalk:
 [ :x | x * x ]
      
      





JavaScript 1.8:
 function(x) x * x
      
      





JavaScript 1.7以降:
 function(x) { return x * x; }
      
      







おそらく私のお気に入りの例は、イベントハンドラーのインストールです。

 document.addEventListener("click", function() false, true);
      
      





または、この表記とJavaScript 1.6の配列に使用されるいくつかの関数の組み合わせで:

 elems.some(function(elem) elem.type == "text");
      
      





これにより、エレガントなJS / DOMコードが得られます。



ジェネレーター式



これは、まったく新しい例です。 ここではいくつかの概念が説明されているため、前のものよりも複雑です。 具体的には、例にはJavaScript 1.7のほとんどの機能、特にイテレーター、ジェネレーター、配列ジェネレーターの知識が必要です。 この機能は、Pythonから借用したジェネレーター式に基づいています。

Brandanは、この機能を追跡するチケットに、このアドオンが提案する新しい構文を使用して書かれたエレガントで機能的な数独ソルバーを投稿しました。 このデモは、Pythonで書かれた同様のデモに基づいており、ジェネレータ式の使用方法を示しています。



この関数の意味をよりよく理解するために、Sudokuソルバーから取得したJavaScript 1.8コードの例を見てみましょう。

 dict([s, [u for (u in unitlist) if (u.contains(s))]] for (s in squares))
      
      





この式はdict()関数に依存しています。この関数は2xN行列を取り、それをキー/値のペアに変換します。 彼女のコードは次のとおりです。

 function dict(A) { let d = {} for (let e in A) d[e[0]] = e[1] return d }
      
      





この式の各要素を見て、何が起こっているのかをよりよく理解しましょう。

 [u for (u in unitlist) if (u.contains(s))]
      
      





式の最初の部分は、JavaScript 1.7から配列を生成する例です。 つまり、リストの各要素を調べます。

sを含むインデックスを持つ配列を作成します。

 [s, ...] for (s in squares)
      
      





式の2番目の部分は、配列生成の別の例です。 一見すると、これはJavaScript 1.7のもう1つの機能です。破壊的な割り当てですが、そうではありません。

破壊的な割り当ては、新しい値を配列の古い要素に割り当てると発生します。ここでは、この値を新しい配列に追加します。 その後、新しい2次元配列がdict関数に渡されます。

 dict([s, ...] for (s in squares))
      
      





これは魔法が隠されている場所です。 JavaScript 1.7では、次のようにdict()関数を呼び出すことができます。

 dict([[s, ...] for (s in squares)])
      
      





リスト生成の明示的な使用に注意してください。 追加生成の問題は、配列全体を構築するために完全に実行する必要があることです(配列は辞書/ハッシュに変換されます)。 ただし、もう1つ[...]がないと、式ジェネレータが定義されます。 これにより、JavaScript 1.8の行はJavaScript 1.7の次の行と同等になります。

 dict((function(){ for (s in squares) yield [s, ...] ; })())
      
      







ここでは、ジェネレーター式が遅延して配列を作成することがわかります。つまり、値はdict()関数で必要になるまで生成されません(結果として、操作が少なくなり、パフォーマンスが向上します)。



ジェネレータ式の別の例を次に示します。



 //  ,      function val_iter(obj) { return (obj[x] for (x in obj)); } //     for ( let key in obj ) { ... } //     for ( let value in val_iter(obj) ) { ... }
      
      







もちろん、val_iter()関数は、yieldを使用してJavaScript 1.7を使用して構築することもできます。



 function val_iter(obj) { for (let x in obj) yield obj[x]; }
      
      







ジェネレータ式は、メモリとCPUに貪欲なコードで特に役立ちます-たとえば、同じ数独ソルバで、必要なときにのみソリューションの結果を取得できるようになりました-事前に計算することはできません。



イテレーターを楽しむ





ところで、最近私はイテレーターとジェネレーターを扱いました-そして、一連の数値(たとえば、0-9)を単純に反復する機能がありませんでした。 ファイルを少し操作して、この機能を言語に追加できます。



 //      Number.prototype.__iterator__ = function() { for ( let i = 0; i < this; i++ ) yield i; }; //    for ( let i in 3 ) alert( i ); //    100 ,   [ 0 for ( i in 100 ) ] //    10*10 [[ i == j ? 1 : 0 for ( i in 10 ) ] for ( j in 10 )]
      
      







たぶん彼は虐殺されているかもしれませんが、私はこれを非常に喜んでいました。



配列削減



最後に考慮すべきことは、JavaScript 1.6 Array Extrasを使用した新しいArray.reduce / Array.prototype.reduceメソッドです。



この方法で配列にreduceを適用できます:

 someArray.reduce( fn [, initial] );
      
      







関数を使用すると、次のようになります。

 someArray.reduce(function(lastValue, curValue){ return lastValue + curValue; });
      
      







引数「lastValue」は、reduce関数のコールバックの結果です。 最初に呼び出したとき、lastValueはリストの最初の要素またはinitialの値と等しくなります。これを渡した場合、curValueの値はリストの次の要素と等しくなります



したがって、0から99までの数値の合計を検索する場合は、次のように実行できます(JavaScript 1.8および上記の数値反復子を使用)

 [x for ( x in 100 )].reduce(function(a,b) a+b);
      
      







エレガントですね。



複数のDOMノードを1つの配列にマージするようなことに対して、reduceを適用することもできます。

 nodes.reduce(function(a,b) a.concat(b.childNodes), []);
      
      







自分で試してみてください!



上記のすべてがFirefox 3の最新のナイトリービルドで機能するため、上記のいずれかを試してみたい場合は、以下を実行してください。

1. Firefox 3のナイトリービルドをダウンロードします

2.次のタグを含むページを作成します(追加されたばかりの属性 'version = 1.8'を使用):

 <script type="application/javascript;version=1.8"> ... your code ...</script>
      
      





それだけで十分です-お楽しみください!



All Articles