私は Python と Smalltalk のバックグラウンドから Javascript に来ており、この言語における Self と Lisp の系統に感謝しています。ECMAScript5 を使用して、new 演算子を使用せずにプロトタイプの OO を試してみたかったのです。
制約:
- クラスを作成するオプションの new 演算子
- instanceof のプロトタイプ チェーンは正しくなければなりません
- WebInspector デバッグ サポート用の名前付きコンストラクター
- alloc().init() は、Objective-C や Python のような作成シーケンス
基準を満たすための実装での私の試みは次のとおりです。
function subclass(Class, Base) {
"use strict";
function create(self, args) {
if (!(self instanceof this))
self = Object.create(this.prototype);
var init = self.__init__;
return init ? init.apply(self, args) : self;
}
if (Base instanceof Function) Base = Base.prototype;
else if (Base===undefined) Base = Object.prototype;
Class.prototype = Object.create(Base);
Class.prototype.constructor = Class;
Class.create = create;
Class.define = function define(name, fn) { return Class.prototype[name] = fn; };
Class.define('__name__', Class.name);
return Class;
}
そして、それは単純なモックアップで動作するようです:
function Family(){return Family.create(this, arguments)}
subclass(Family, Object);
Family.define('__init__', function __init__(n){this.name=n; return this;});
function Tribe(){return Tribe.create(this, arguments)}
subclass(Tribe, Family);
function Genus(){return Genus.create(this, arguments)}
subclass(Genus, Tribe);
function Species(){return Species.create(this, arguments)}
subclass(Species, Genus);
クラスをファクトリ関数として使用する:
var dog = Species('dog');
console.assert(dog instanceof Object);
console.assert(dog instanceof Family);
console.assert(dog instanceof Tribe);
console.assert(dog instanceof Genus);
console.assert(dog instanceof Species);
または new 演算子を使用します。
var cat = new Species('cat');
console.assert(cat instanceof Object);
console.assert(cat instanceof Family);
console.assert(cat instanceof Tribe);
console.assert(cat instanceof Genus);
console.assert(cat instanceof Species);
console.assert(Object.getPrototypeOf(dog) === Object.getPrototypeOf(cat))
私の実装でプロトタイプ OO の必要な機能を見落としていませんか? 変更が必要な Javascript の規則や相互作用はありますか? 要約すると、ここでの「落とし穴」は何ですか? また、明らかな改善点はありますか?
コンストラクターの定義を DRYer にしたかったのですが、関数の name プロパティが書き込み可能ではないことがわかりました。これが、WebKit Inspector のオブジェクト名をサポートする理由です。私は自分が望んでいたことを達成するために評価を構築することができましたが、... うーん。