2017-07-08 14 views
0

私は2つのAPIを持っていて、最初からクラスを継承したいと思いますが、.prototype.toJSON()でレスポンスを変更します。クラスメソッドを継承するJavascript

私がファーストクラスから継承するとき、どのようにしてクラスメソッドも継承できます。私は今

var User = require('./v2/models/users'); 
User.find(1); 

を呼び出そうとすると

//file v1/models/users.js 
var UserModel = function() { 
    this.id = 0; 
    this.firstName = ''; 
    this.lastName = ''; 
} 

UserModel.find = function(q, callback) { 
    //find any user that matches q and map them to UserModel 
    if (err) return callback(err, null); 
    callback(null, users); 
} 

module.exports = UserModel; 

そして、次のバージョンでは

//file v2/models/users.js 
var UserModel = require('../v1/models/users'); 

function UserModelV2() { 
    UserModel.call(this); 
} 

UserModelV2 = Object.create(UserModel.prototype); 
UserModelV2.prototype.constructor = UserModel; 

UserModelV2.prototype.toJSON = function() { 
    var obj = {}; 
    obj.firstName = 'foo'; 
    return obj; 
} 
module.exports = UserModelV2; 

私はUser.findが存在しないというエラーを取得します。

私はプロトタイプのプロパティのみを継承していることを知っていますが、クラスメソッドを継承する例はどこにもありません。

+0

'User.prototype.find' - 関数の' .prototype'は、その関数をコンストラクタとして使用して作成されたオブジェクトのプロトタイプ( '__proto__'プロパティ)を決定します。 –

+0

これを見て、私はあなたが 'UserModelV2 'を意味すると思います。prototype = Object.create(UserModel.prototype); ' – Thomas

+0

@Thomas番号は、' Object.create() 'の正しい使い方です。 –

答えて

3

findを直接UserModelに追加しないでください。これにより、メソッドが1つのインスタンスにのみ追加されるためです。 UserModelのすべてのインスタンスは、あなたのコンストラクタ関数のプロトタイプから継承されますので

UserModel.prototype.find = function(id) { 
    //find the user by id and return 
} 

はプロトタイプに追加します。ちなみに

// Constructor of sub-class 
function UserModelV2() { 
    // Call the prototype.constructor, not just .constructor 
    UserModel.prototype.constructor.call(this); 
} 

// Perform inheritance 
UserModelV2.prototype = new UserModel(); 

// Correct the constructor of the prototype 
UserModelV2.prototype.constructor = UserModelV2; 

// Extend the sub-class 
UserModelV2.prototype.toJSON = function() { 
    var obj = {}; 
    obj.firstName = 'foo'; 
    return obj; 
} 

(とあなたがこれに引っかかって、なぜこれは可能性が)技術的に、(とclassキーワードにもかかわらず)は、JavaScript:

次に、あなたの次のバージョンでは、このように最初から継承しますクラスを持たず、プロトタイプを持ち、継承の基礎となります。

+0

しかし、私はvar user = new UserModel();を実行する必要があります。 user.find(id);毎回。それとも別の方法がありますか? – Ron

+0

オブジェクトベースとして機能する関数を作成すると、コンストラクタ関数が作成され、コンストラクタ関数がどのように使用されるのかが確認されます。あなたの関数は 'this'を使用しているため個々のインスタンスが必要であることを示しています。これはインスタンスプロパティの作成方法です。インスタンスを構築せずにインスタンスプロパティを持つことはできません(つまり、 'new')。 –

+0

私は何をしたいのですか?おそらく私の例は最高ではありませんでした。なぜなら、findは実際にもっと多くのUserのインスタンスを返すことができるからです。私は私の質問を更新します。 – Ron

0

さて、あなたは単にUserModel

Object.assign(UserModelV2, UserModel); 

からオーバー方法をコピーすることもできますし、UserModelV2機能ではなく、直接Function.prototypeUserModel関数からそのプロパティを継承することを定義します。

Object.setPrototypeOf(UserModelV2, UserModel); 

それとも、新しいclass構文を使用しているが、このの世話をしてみましょう:あなたは下位互換性が必要な場合は、

class UserModelV2 extends UserModel { 
    toJSON(){ 
    return {firstName: 'foo'};  
    } 
} 

多分バベルのようなtranspilerとの組み合わせで。

私は最後のオプションをお勧めします。私にとっては、これは最もクリーンなアプローチのようで、には、のトランスファーを使用する能力が備わっています。
それは意味的にはっきりしています。 JSコンパイラでさえ、あなたが何らかの関数のプロトタイプを恣意的に使いこなしているだけでなく、何かを壊したり、「奇妙な」何かをしたりするかもしれません。

+0

assignを使用すると、 'find'関数が検出されますが、古いプロパティのtoJSONも使用されます。 – Ron

+0

あなたの 'UserModel'には"古い "' toJSON'メソッドはありません。そして、新しいプロパティで上書きしようとする前に**古いプロパティを割り当てる必要があります – Thomas