0

Dojoから来たので、 Dojoの機能が本当に恋しいです。私は複雑なアプリケーションを開発していて、ノードから生きている地獄をハッキングして、それをもっと...まあ、もっと強力にしました。declare()lang.inherits()

これが実際に何をするかを示す例です:

var First = declare( null, {
  one: function(p){ 
    console.log("one in First");
    console.log(p); 
    return 1000; 
  },
  two: function(p){ 
    console.log("two in First");
    console.log(p);
    return 1001; 
  },
  constructor: function(a){ 
    this.a = a; 
    console.log("Constructor of First called");
  },
})

var Second = declare( First, {
  two: function( p ){
    console.log("two in Second"); 
    console.log( p );
    a = this.inherited(arguments);
    console.log("Inherited function returned: " + a );
  },
  constructor: function(a){ 
    console.log("Constructor of Second called, and this.a is...");
    console.log( this.a );
  },
})

console.log("Creating first...");
first = new First(10);
console.log("Creating second...");
second = new Second( 20 );

console.log( "first.a:")
console.log( first.a );
console.log( "second.a:")
console.log( second.a );

console.log( "first.one(1):")
first.one(1);
console.log( "first.two(2):")
first.two(2);

console.log( "second.one(3):")
second.one(3);
console.log( "second.two(4):")
second.two(4);

表示されます:

Creating first...
Constructor of First called
Creating second...
Constructor of First called
Constructor of Second called, and this.a is...
20
first.a:
10
second.a:
20
first.one(1):
one in First
1
first.two(2):
two in First
2
second.one(3):
one in First
3
second.two(4):
two in Second
4
two in First
4
Inherited function returned: 1001

この関数lang.inherits()がミニマルである理由はわかっています。nodejsは、Javascriptで「クラス」、プロトタイプ、およびオブジェクトを処理する特定の方法を課したくないのです。

ただし、そこにある多くのコードは次のものでいっぱいです。

function SomeClass( options ){
  this.options = options;
}

SomeClass.prototype.functionOne = function(something){
  //...
}
SomeClass.prototype.functionTwo = function(something){
  //...
}

どれが(そして...まあ、そうすべきですか?)次のように書くことができます:

SomeClass = declare( null, {
  constructor: function(options){
    this.options = options;
  },
  functionOne: function(something){
    // ...
  },
  functionTwo: function(something){
    // ...
  },
})

できるという利点があります:

SomeOtherClass = declare( SomeClass, {
  constructor: function(){
    this.options['manipulate'] ++;
  },
  functionOne: function(something){
    this.inherited(arguments); // Call the superclass method
    // ...
  },
})

これにより、親などのコンストラクターが自動的に呼び出されます(実装するためthis.inherited()に、実際には関数のハッシュマップを作成することになりました。これは、事実上名前がないためです)。

これとDojoの主な違いは、このバージョンは多重継承とミックスインを実装していないことです。ただし、クライアント側の環境では多重継承/ミックスインは理にかなっていますが、サーバー側のプログラムではそれらが大きなやり過ぎになると思います。OK...これがコードです。このコードで本当に間違っていることを見つけることができますか?

私はすでに存在する何かを発明しましたか?

どうぞ...

var 
  dummy
;

var declare = exports.declare = function(superCtor, protoMixin) {

  // Kidnap the `constructor` element from protoMixin, as this
  // it mustn't get copied over into the prototype
  var constructor = protoMixin.constructor;
  delete protoMixin.constructor;

  // The function that will work as the effective constructor. This
  // will be returned
  var ctor = function(){

    // Call the superclass constructor automatically
    if( typeof( superCtor.prototype.constructor === 'function' ) ){
       superCtor.prototype.constructor.apply( this, arguments );
    }

    // Call its own constuctor (kidnapped a second ago)
    if( typeof( constructor ) === 'function' ){
      constructor.apply( this, arguments );
    }
  };

  // The superclass can be either an empty one, or the one passed
  // as a parameter
  superCtor = superCtor === null ? function(){} : superCtor;

  // Create the new class' prototype. It's a new object, which happen to
  // have its own prototype (__proto__) set as the superclass' and the
  // `constructor` attribute set as ctor (the one we are about to return)
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });

  // Implement inherited() so that classes can run this.inherited(arguments)
  // This will only work for sub-classes created using declare() as they are
  // the ones with the _inheritMap in their prototype
  protoMixin.inherited = function(args){
    var name, fn;

    // Look for the name in the _inheritMap
    name = this._inheritMap[ args.callee ];
    if( name ){
      fn = superCtor.prototype[name];
      if( fn ){
        return fn.apply( this, args );
      } else {
        throw( new Error("Method " + name + "() not inherited!") );
      }
    }
  }

  // Copy every element in protoMixin into the prototype.
  ctor.prototype._inheritMap = {}
  for( var k in protoMixin ){
    ctor.prototype[ k ] = protoMixin[ k ];
    ctor.prototype._inheritMap[ protoMixin[ k ] ] = k;
  }

  return ctor;
};
exports = module.exports = declare;
4

2 に答える 2

0

基本的にnpm install declarejsはDojoの宣言を取り除いたバージョンです。

ここでもう少し情報を見つけることができます

.extend()個人的には、簡単に取り除けるバックボーンのようなものが好きです。

于 2013-02-22T15:47:21.997 に答える
0

まあ、私が思う答えは「それがうまくいくなら、それなら素晴らしい!」です。それは動作します...そう:素晴らしい!

今後の参考のために、「declare」はGitHubにあります。

https://github.com/mercmobily/JsonRestStores/blob/master/declare.js

this.inherited(arguments)がハッシュマップなしで機能するようにコードを更新しました。

今のところ、それは以下の一部です:

https://github.com/mercmobily/JsonRestStores

別のリポジトリを作成したほうがいいかもしれませんが、それ自体が便利な関数なので!

メルク。

于 2013-02-25T14:04:19.067 に答える