オブジェクトの型#

JavaScriptはオブジェクト指向ではないとかいう記事がたまにありますが、それは嘘です。
JavaScriptは、用意されたオブジェクトを利用することも、自分でオブジェクトを作ることもできます。

例題として

  • 1:MyClassを作成し、myFuncを実装する
  • 2:MainからMyClassのインスタンスを作りmyFunc機能を呼ぶ
という操作を数通りやってみましょう。

Javaの場合#

MyClass.myFunc()にintの数字を与えると、その2倍の数値を得られるという関数を用意します。
public class MyClass{
  public MyClass(){
    //コンストラクタ部
  }
 public int myFunc(int a){
    return(a*2);
  }
}
//----------------------
//上のオブジェクトをMainから呼びだします。
public class Main {
  public static void main(String[] args) {
    MyClass myObj = new MyClass(); //これからMyClassを使います。ここではmyObjと呼びます。
    System.out.println(myObj.myFunc( 123 )); //画面には123の倍の246が表示されます。
  }
}
この通り、myObjを作るには、MyClass型であるという宣言と、new MyClassという作成命令によるインスタンスmyObjの生成が必要です。

JavaScriptの場合(1) 普通のアプローチ#

JavaScriptでは、厳密な意味の「クラス」はないのですが、似たことはできます。
function MyClass(){
  this.myFunc = function(a){
    return (a*2);
  }
}
//this.myFunc という書き方がミソです。
//javaでの public int myFunc(int a){ という書き方とはずいぶん違いますね。
//これで、MyClassにはmyFuncというメソッド(関数)が備わります。

//MyClassをMainから使ってみる
function Main(){
  var myObj = new MyClass(); //MyClassをこれから使います。ここではmyObjと呼びます。
  print(myObj.myFunc(123));  //246と画面に出力されます。
}

JavaScriptの場合(2) いかにもスクリプト言語風のアプローチ#

先ほどのサンプルでは function MyClass(){} 内部で全ての機能を装備しましたが、JavaScriptでは外部で作成された関数を自分の一部に取り込むことが出来ます。
function Func(a){
    return (a*2);
}

function MyClass(){
  this.myFunc=Func;
  }
}
//これで、MyClass.myFunc() にあたるものができたことになります。

function Main(){
  var myObj = new MyClass();
  print(myObj.myFunc(123)); //画面に246と出力されます。
}
これは一体何なのかというと、 this.装備したい機能の名前 = 取り込みたい関数の名前 という命令で、既存の関数をクラスの関数に取り込めるのです。

JavaScriptの場合(3) いかにもJavaScriptな「プロトタイプ」によるアプローチ#

これは混乱しやすいので、ゆっくり呼んでください。
function MyClass(){
}
//とりあえず何の機能もないMyClass関数を作ります。

// prototype 命令はMyClass に関数を増設する
MyClass.prototype.myFunc = function(a){
  return (a*2);
}

function Main(){
  var myObj = new MyClass();
  print(myObj.myFunc(123)); //234が出力されます。
}

異様な書き方ですが、これはよそで宣言されたオブジェクトに対して機能を外付けしてしまうというものです。
追加する相手のオブジェクト(MyClass)が自作のものであれば、MyClassいいろいろ付けてしまえば済むことなのですが、相手がJavaScriptの組み込みオブジェクトだとそうはいきません。

わかりやすい使い方では「なんでString型にはtrim命令がないの?作っちゃえ」というようなものがあります。

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, "");
}
という文を書くと、この行が実行された後はString型にtrim命令が追加されて使えるようになります。
var strA="   abc   ";
print( strA.trim() );
という風にすると、両端の余白が除去された"abc"が得られます。

ただし!
Yahoo! Widgetの組み込みオブジェクト(Window, Imageとか)にprototypeで機能を増やそうとしてもこれはうまくいきません。
Widgetでの継承には、非常に厄介な問題が横たわっているのです。

(続く)

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-1) was last changed on 28-Nov-2007 23:43 by UnknownAuthor