JavaScript序論

This guide is based on the Quick guide to somewhat advanced JavaScript tour of some OO features by Sergio Pereira.
このガイドはセルジオ・ペレイラによる「多少高度なJavaScriptクイック・ガイド(オブジェクト指向の機能のいくつかのツアー)」に基づきます。

ちょっと・・・ そんなことができるなんて知らなかったよ

If you are a web developer and come from the same place I do, you have probably used quite a bit of Javascript in your web pages, mostly as UI glue.
Until recently, I knew that Javascript had more OO capabilities than I was employing, but I did not feel like I needed to use it. As the browsers started to support a more standardized featureset of Javascript and the DOM, it became viable to write more complex and functional code to run on the client. That helped giving birth to the AJAX phenomena.
あなたがウェブ開発者であり、私がたどってきた道を同じ道を来たのならば、あなたはたぶん、あなたのWebページで(大抵は、ユーザーインターフェースの結合方法として)たくさんのJavascriptを使ってきたでしょう。
私は、JavaScriptが、私が使っていたより多くのオブジェクト指向の機能を持っていることは知っていましたが、最近までは、それを使う必要性を感じませんでした。いくつかのブラウザが、JavascriptとDOMの、より規格化された機能セットをサポートし始めて、クライアントサイドで機動するより複雑で、機能的なコードを書くことが実行可能になりました。それは、AJAX現象を生みだすことに寄与しました。
As we all start to learn what it takes to write our cool, AJAX applications, we begin to notice that the Javascript we used to know was really just the tip of the iceberg. We now see Javascript being used beyond simple UI chores like input validation and frivolous tasks. The client code now is far more advanced and layered, much like a real desktop application or a client-server thick client. We see class libraries, object models, hierarchies, patterns, and many other things we got used to seeing only in our server side code.
自分自身のかっこいAJAXのアプリケーションを書くために必要なものを学び始めた時、私達は、自分達の知っていたJavascriptが本当に氷山の一角であったことに気づきはじめます。私達は現在、インプット認証やささいな機能の簡単なユーザーインターフェースの用途を越えて使われているJavascriptを見ます。クライアントコードは現在、本当のデスクトップアプリケーションの様に進化し、クライアントサーバーにクライアントを多層に重ねて行くことができます。私達は、クラスライブラリ、オブジェクト・モデル、ヒエラルキー、パターン、そして、サーバーサイドのコードの中だけで見ることをなれてしまった多くのものを目にします。
In many ways we can say that suddenly the bar was put much higher than before. It takes a heck lot more proficiency to write applications for the new Web and we need to improve our Javascript skills to get there. If you try to use many of the existing javascript libraries out there, like PPrototype.js, Scriptaculous, moo.fx, Behaviour, YUI, etc you'll eventually find yourself reading the JS code. Maybe because you want to learn how they do it, or because you're curious, or more often because that's the only way to figure out how to use it, since documentation does not seem to be highly regarded with most of these libraries. Whatever the case may be, you'll face some kung-fu techniques that will be foreign and scary if you haven't seen anything like that before.
The purpose of this article is precisely explaining the types of constructs that many of us are not familiar with yet.
多くの点で、突然、バーが前よりずっと高くなったと言えます。新しいWebアプリケーションを書くための地獄の特訓が必要となり、熟練するためには私達のJavascriptスキルを改善する必要がでてきました。もし、あなたが、Prototype.js, Scriptaculous, moo.fx, Behaviour, YUI, といった、多く既存するjavascriptライブラリを使おうとするならば、結局自身がJSコードを読んでいることに気付くとおもいます。それは、おそらく、これらのライブラリがどのような振る舞いをしているかを学習したいう理由だったり、興味があるという理由だったり、もしくは、もっとも多い理由だと思いますが、これらのライブラリをどのようにつかうかを理解する唯一の方法であるという理由で、JSコードを読むことになるのだとおもいます。そして、こういったライブラリの性質があるため、ドキュメントはあまり注目されないのです。こういった場合、過去に同様の経験をしていないかぎり、疎外感や恐れを抱くようなカンフーテクニックに直面することになるでしょう。
この記事は、私達の多くがまだ精通していないコンテンツタイプを正確に説明することを目的としています。

JSON (JavaScript Object Notation:JavaScriptオブジェクト表記法)

JavaScript Object Notation (JSON,) is one of the new buzzwords popping up around the AJAX theme. JSON, simply put, is a way of declaring an object in Javascript. Let's see an example right away and note how simple it is.
JavaScriptオブジェクト表記法(JSON,)はAJAXテーマのまわりで飛び出ている新しい専門語の1つです。JSONは、簡単に定義すると、Javascriptにおいてオブジェクトを宣言する方法です。すぐに例を見て、それがどれほど簡単であるかを注目しましょう。
var myPet = { color: 'black', leg_count: 4, communicate: function(repeatCount){
for(i=0;i<repeatCount;i++) alert('Woof!');} };
Let's just add little bit of formatting so it looks more like how we usually find out there:
ちょっと手を加えて、いつも見ているような形にしてみましょう。
var myPet =
{
   color: 'black',
   legCount: 4,
   communicate: function(repeatCount)
   {
       for(i=0;i<repeatCount;i++)
           alert('Woof!');
   }
};
Here we created a reference to an object with two properties (color and legCount) and a method (communicate.) It's not hard to figure out that the object's properties and methods are defined as a comma delimited list. Each of the members is introduced by name, followed by a colon and then the definition. In the case of the properties it is easy, just the value of the property. The methods are created by assigning an anonymous function, which we will explain better down the line. After the object is created and assigned to the variable myPet, we can use it like this:
ここで、私達は、2つのプロパティ(色:color と 足の数:legCount)とメソッド(通信: coummunicate)を持つオブジェクトへの参照を作成しました。コンマがリストを区切った時に、オブジェクトのプロパティとメソッドが定義されると理解することは難しくありません。メンバーのそれぞれは、名称によって宣言されていて、コロンに続いて定義が記述されます。プロパティはわかりやすく、まさにプロパティの値を示しています。メソッドは、以下の例を見てもらえば分かると思うが、宣言名の無い関数を割り当てることによって作成されます。オブジェクトが作成されて、変数myPetに割り当てられた後は、それを以下の様に使うことができます:
alert('my pet is ' + myPet.color);
alert('my pet has ' + myPet.legCount + ' legs');
//if you are a dog, bark three times:
myPet.communicate(3);
You'll see JSON used pretty much everywhere in JS these days, as arguments to functions, as return values, as server responses (in strings,) etc.
今では、あなたはJSコードの中に、関数の引数として、もしくは、戻り値として、もしくは、サーバーの返り値(文字列中に)等、JSONがいたる所で使われているのを見ることでしょう。

参考までに・・・

以上の部分をコードで記述すると、以下のとおりです。アラートで結果が分かります。アラートデバック方式って、JavaScriptじゃ一般的なんでしょうね。
<script language='JavaScript'>
<!--
 var myPet =
 {
  color: '黒',
  legCount: 4,
  communicate: function(repeatCount)
  {
      for(i=0;i<repeatCount;i++)
          alert('ワン!');
  }
};

alert('私のペットの色は ' + myPet.color);
alert('私のぺっとは、 ' + myPet.legCount + ' 脚の足をもっています。');
//if you are a dog, bark three times:
myPet.communicate(3);

-->
</script>

function(関数)もオブジェクトって、いったい どういう意味?

This might be unusual to developers that never thought about that, but in JS a function is also an object. You can pass a function around as an argument to another function just like you can pass a string, for example. This is extensively used and very handy.
Take a look at this example. We will pass functions to another function that will use them.
そうは考えていなかった開発者にとっては、異常と移るかもしれませんが、JS(JavaScript)において、function(関数)もまた、オブジェクトなのです。関数の引数として、文字列を渡すことと同じように、関数自体を引数に渡すことも可能なのです。これは広く使われて、非常に便利です。
この例をちらりと見てください。ここではfunction(関数)を別のfunction(関数)に渡して利用しています。
var myDog =
{
   bark: function()
   {
       alert('Woof!');
   }
};

var myCat =
{
   meow: function()
   {
       alert('I am a lazy cat. I will not meow for you.');
   }
};

function annoyThePet(petFunction)
{
   //let's see what the pet can do
   petFunction();
}

//annoy the dog:
annoyThePet(myDog.bark);
//annoy the cat:
annoyThePet(myCat.meow);
Note that we pass myDog.bark and myCat.meow without appending parenthesis "()" to them. If we did that we would not be passing the function, rather we would be calling the method and passing the return value, undefined in both cases here.
If you want to make my lazy cat start barking, you can easily do this:
myDog.bark、myCat.meow といったfunction(関数)を、括弧「()」をつけずに引数に渡しているに注意してください。もし括弧「()」をつけてしまったら、引数をfunctionに渡せない、その時点でfunction(関数)を呼び出してしまい、返り値、この場合では”undefined"を、渡すことになります。
あなたが、私の怠惰な猫を、吠えさせたいなら、簡単にできます。
myCat.meow = myDog.bark;
myCat.meow(); //alerts 'Woof!'

配列とアイテム、オブジェクトとメンバ

The following two lines in JS do the same thing.
JS(JavaScript)では、以下の2行は同じ事です。
var a = new Array();
var b = [];
As I'm sure you already know, you can access individual items in an array by using the square brackets:
既にご存知だと思うが、配列では、角括弧 [ ] を使って個々のアイテムにアクセスすることができます:
var a = ['first', 'second', 'third'];
var v1 = a[0];
var v2 = a[1];
var v3 = a[2];
But you are not limited to numeric indices. You can access any member of a JS object by using its name, in a string. The following example creates an empty object, and adds some members by name.
数字のインデックスだけとは限りません。、JS(JavaScript)オブジェクトのすべてのメンバーについても、文字列の名前を使ってアクセスすることができます。以下の例は、空のオブジェクトを作成し、名前によっていくつかのメンバーを追加しているものです。
var obj = {}; //new, empty object
obj['member_1'] = 'this is the member value';
obj['flag_2'] = false;
obj['some_function'] = function(){ /* do something */};
The above code has identical effect as the following:
次のコードも、上記のコードと同じ効果があります。:
var obj =
{
   member_1:'this is the member value',
   flag_2: false,
   some_function: function(){ /* do something */}
};
In many ways, the items of objects and associative arrays (hashes) in JS are not distiguishable. The following two lines do the same thing too.
多くの点で、オブジェクトのアイテムとJS(JavaScript)の連想の配列(ハッシュ)は区別がつけられません。次の2行は、同じことになります。
obj.some_function();
obj['some_function']();

参考までに

配列とオブジェクトがほとんど同じという部分は、Pradoに通じていますね。参考 までに、冒頭のペットのオブジェクトを配列で記述すると以下の感じです。
var MyPet={};
MyPet['color']='黒';
MyPet['legCount']=4;
MyPet['communicate']=function(repeatCount){
	for(i=0;i<repeatCount;i++)alert('ワン');};

alert('私のペットの色は' + MyPet['color']);
alert('私のペットは、'+ MyPet.legCount + '脚の足を持っています。');
MyPet.communicate(3);
//もしくは、MyPet['communicate'](3);
配列として設定して、その後呼び出す際には、連想配列として呼び出しても、オブジェクトとして呼び出しても動くことが分かります。

オブジェクトについて十分分かったら、今度はクラスを使えますか?

The great power of object oriented programming languages derive from the use of classes. I don't think I would have guessed how classes are defined in JS using only my previous experience with other languages. Judge for yourself.
オブジェクト指向プログラミング言語の大きな威力は、クラスが使えることから派生しています。私のこれまでの他の言語での経験だけでJavaScriptがどのように定義されていると推測するのか、ということではありません。みなさんで判断できることだと思います。
//defining a new class called Pet
var Pet = function(petName, age)
{
   this.name = petName;
   this.age = age;
};

//let's create an object of the Pet class
var famousDog = new Pet('Santa\'s Little Helper', 15);
alert('This pet is called ' + famousDog.name);
Let's see how we add a method to our Pet class. We will be using the prototype property that all classes have. The prototype property is an object that contains all the members that any object of the class will have. Even the default JS classes, like String, Number, and Date have a prototype object that we can add methods and properties to and make any object of that class automatically gain this new member.
Petクラスにどのようにしてメソッドをに追加するかを、じっくり見てみましょう。そこでは、すべてのクラスが持っているprototypeプロパティを使っています。 prototypeプロパティは、どのようなクラスオブジェクトでも持っている全メンバーを含んでいるオブジェクトです。、文字列、数字、および日付の様な、デフォルトのJS(JavaScript)クラスでさえprototypeのオブジェクトを持っていて、メソッドとプロパティを追加することができ、そのクラス中の全オブジェクトは、自動的にこの新しいメンバーを参照することが可能になる。
Pet.prototype.communicate = function()
{
   alert('I do not know what I should say, but my name is ' + this.name);
};
That's when a library like prototype.js comes in handy. If we are using prototype.js, we can make our code look cleaner (at least in my opinion.)
こうなってくると、prototype.jsのようなライブラリが役に立ちます。prototype.jsを使えば、コードを綺麗に(少なくとも私の意見において。)に見せることができます。
var Pet = Class.create();
Pet.prototype =
{
   //our 'constructor'
   initialize: function(petName, age)
   {
       this.name = petName;
       this.age = age;
   },

   communicate: function()
   {
       alert('I do not know what I should say, but my name is ' + this.name);
   }
};

メモ

この最後のprototype.js の class の記述は、私にしてみると カンフー です。多分、他の普通の言語のクラス表記に近い形でクラスを宣言できる様になるという意味だと思います。

Functions(関数)が引数・・・そりゃおもろい

If you have never worked with languages that support closures you may find the following idiom too funky.
もしクロージャーをサポートする言語を一度も使ったことがないなら、以下の例文はかなりファンキーだと思います。
var myArray = ['first', 'second', 'third'];
myArray.each( function(item, index)
{
   alert('The item in the position #' + index + ' is:' + item);
});
Whoa! Let's explain what is going on here before you decide I've gone too far and navigate to a better article than this one.
わおー! 何が起きているか説明してみようね。(でないと、わかんねぇから、ほかの説明文で理解しよう と思っちゃうよね)
First of all, in the above example we are using the prototype.js library, which adds the each function to the Array class. The each function accepts one argument that is a function object. This function, in turn, will be called once for each item in the array, passing two arguments when called, the item and the index for the current item. Let's call this function our iterator function. We could have also written the code like this.
まず第一に、上記の prototype.js ライブラリを使ってる例ね、そこでは配列クラスに、each 関数を加えて行っているね。さらに、each 関数が、ある関数オブジェクトの引数を受け入れているね。この関数は、配列の各々のアイテムに呼び出されて、その都度、その時のアイテムとインデックス、2つの引数を渡しているね。この関数をイテレター(入れ子)関数と呼ぼう。このコードは次の様にも書ける。
function myIterator(item, index)
{
   alert('The item in the position #' + index + ' is:' + item);
}

var myArray = ['first', 'second', 'third'];
myArray.each( myIterator );
But then we would not be doing like all the cool kids in school, right? More seriously, though, this last format is simpler to understand but causes us to jump around in the code looking for the myIterator function. It's nice to have the logic of the iterator function right there in the same place it's called. Also, in this case, we will not need the iterator function anywhere else in our code, so we can transform it into an anonymous function without penalty.
でも、みんながこんな優等生みたいなことできるわけないよね。真面目な話だけど、この最後のフォーマットは、理解するためには良いけれど、myIterator関数を探して、コード中に書き込まなくちゃならない。イテレター関数は、その関数が呼び出されるその場所に置くの良いと思う。このケースでは、コードの他の場所で、このイテレター関数が必要な訳でもなく、名前なしの関数に変換して何の問題もない。

自分のことは、this でよいはず。でも this は 時々 ヤツ になってる

One of the most common troubles we have with JS when we start writing our code it the use of the this keyword. It could be a real tripwire.
JS(JavaScript)を書いている際に生じるもっとも一般的な失敗の一つが、this を使っている時だ。それは網をはった罠みたいなもんだ。
As we mentioned before, a function is also an object in JS, and sometimes we do not notice that we are passing a function around.
Take this code snippet as an example.
前述した様に、関数は、JS(JavaScript)のオブジェクトであるが、関数がそこにあることをたまに忘れてしまいます。
以下のコードの一部がよい例です。
function buttonClicked()
{
   alert('button ' + this.id + ' was clicked');
}

var myButton = document.getElementById('someButtonID');
var myButton2 = document.getElementById('someOtherButtonID');
myButton.onclick = buttonClicked;
myButton2.onclick = buttonClicked;
Because the buttonClicked function is defined outside any object we may tend to think the this keyword will contain a reference to the window or document object (assuming this code is in the middle of an HTML page viewed in a browser.)
buttonClicked関数が、すべてのオブジェクトの外で定義されているために、このthisが、window,documentといったオブジェクトの参照を含んでいると考えてしまいがちです。(このコードはブラウザのHTMLページ内部にあると仮定してます。)
But when we run this code we see that it works as intended and displays the id of the clicked button. What happened here is that we made the onclick method of each button contain the buttonClicked object reference, replacing whatever was there before. Now whenever the button is clicked, the browser will execute something similar to the following line.
しかし、私達がこのコードを実行する時には、私達は、それが作動し 意図されているおよび とわかります クリックされたボタンのディスプレイid 。 ここで起こったことは、私達が、個々のボタンのonclick方法に、buttonClickedされたオブジェクト参照を含ませたことです 前にそこにあったものを何でも取り替える 。 現在、ボタンがクリックされる時には、いつでも、ブラウザは以下のラインと同様な何かを実行します。
myButton.onclick();
That isn't so confusing afterall, is it? But see what happens you start having other objects to deal with and you want to act on these object upon events like the button's click.
var myHelper =
{
   formFields: [ ],
   emptyAllFields: function()
   {
       for(i=0; i < this.formFields.length; i++)
       {
           var elementID = this.formFields[i];
           var field = document.getElementById(elementID);
           field.value = '';
       }
   }
};

//tell which form fields we want to work with
myHelper.formFields.push('txtName');
myHelper.formFields.push('txtEmail');
myHelper.formFields.push('txtAddress');

//clearing the text boxes:
myHelper.emptyAllFields();

var clearButton = document.getElementById('btnClear');
clearButton.onclick = myHelper.emptyAllFields;
So you think, nice, now I can click the Clear button on my page and those three text boxes will be emptied. Then you try clicking the button only to get a runtime error. The error will be related to (guess what?) the this keyword. The problem is that this.formFields is not defined if this contains a referece to the button, which is precisely what's happening. One quick solution would be to rewrite our last line of code.
clearButton.onclick = function()
{
   myHelper.emptyAllFields();
};
That way we create a brand new function that calls our helper method within the helper object's context.