newを実装する

new は予約語なので、代わりにneoで*1

Function.prototype.neo =function(){
  var obj={};
  obj.__proto__ = this.prototype;
  var ret = this.apply(obj,arguments);
  if( ret && typeof(ret)=='object' ){
    delete obj;
    obj = ret;
  }
  return obj;
}

ふむ… obj={} は obj= new Object なので「実装する」と偉そうに言ったわりにアレだが、別に実装が目的ではなくてJavascriptのnew(とthis)の動きを理解するためのサンプルだからこれでいいのだ。
プロトタイプチェーン __proto__ をいじれる系(firefoxとか)なら、だいたいうまくいくはず。

// クラス定義のようなもの
function Klass(x){
  this.x = x;
}
Klass.prototype.add1=function(){
  return this.x+1;
}
// 使ってみる
obj = Klass.neo(1); // <= obj = new Klass(1)
obj.x      // => 1
obj.add1() // => 2
typeof obj // => 'object'
obj instanceof Klass     // => true
obj.constructor == Klass // => true

constructor プロパティーや instanceof までちゃんと動く。

解説しよう。

Function.prototype.neo =function(){
  // 新たなインスタンス obj にメモリを割り当てる
  var obj={};

  // プロトタイプチェーンをつなげる
  obj.__proto__ = this.prototype;

  // 変数 this に、上2行で初期化した obj をセットして
  // コンストラクタ関数を呼ぶ
  var ret = this.apply( obj, arguments );

  // 次の if 文がやっているのは、
  // コンストラクタ関数がthis以外を返すこともできる
  // というjavascriptの動作のエミュレート。
  if( ret && typeof(ret)=='object' ){
    // null以外のobjectが返ってきた場合は、
    // new演算子が作成したインスタンスを捨てて
    delete obj;
    // 返ってきた値を作成したことにする
    var obj = ret;
  }
  return obj;
}

*1:newとして設定することもできるが記述が煩雑になるだけ