2017-05-01 8 views
2

私はクラスの機能を上書きしようとしています:はJavaScript:全クラスのコンストラクタで定義されたプロパティを上書き

class MyClass { 
    constructor() { 
    // more code 
    } 

    myFunction = function() { 
    console.log('not this') 
    } 
} 

// can't change the code above 

MyClass.prototype.myFunction = function() { 
    console.log('it should print this') 
} 

new MyClass().myFunction() 

をしかし、バベルは、これに上記をコンパイル:

class MyClass { 
    constructor() { 
    // more code 

    this.myFunction = function() { 
     console.log('not this'); 
    }; 
    } 
} 

// can't change the code above 

MyClass.prototype.myFunction = function() { 
    console.log('it should print this'); 
}; 

new MyClass().myFunction(); 

関数であるので元のコードのプロパティとして定義されている場合、Babelはその定義をコンストラクタに置きます。 私が正しく理解していれば、プロトタイプには関数のみが含まれていますが、すべてのプロパティは含まれていません。 オブジェクトがプロトタイプから派生した後にコンストラクタが実行されるため、プロトタイプを使用してその関数を上書きすることはできません。

私の2回目の試行は、コンストラクタを上書きした

class MyClass { 
    constructor() { 
    // more code 
    } 

    myFunction = function() { 
    console.log('not this') 
    } 
} 

// can't change the code above 

let oldConstructor = MyClass.prototype.constructor 
MyClass.prototype.constructor = function() { 
    // call old constructor first, it will set myFunction 
    oldConstructor() 

    // now overwrite myFunction 
    this.myFunction = function() { 
    console.log('it should print this') 
    } 
} 

new MyClass().myFunction() 

まあ、試してみましょう... バベルでコンパイル、test.jsし、実行するためにそれを保存します。

~> node test.js 
not this 

私がしようとしましたできるだけ一般的な質問をする。特定のケースでクラスを変更できない理由についての背景情報:クラスは実際に私が使用しているライブラリのものであり、使用する他のパッケージもそのライブラリに依存しています。 MeteorJSでは、依存関係の正確なバージョンとソースを指定するパッケージが必要です。そのため、私はフォークを使用できません。このライブラリに依存するすべてのパッケージをforkする必要があります。

答えて

0

実際にはあなたのクラスは変更されていますが、how javascript interpreter looks for information inside its objectsが原因で効果が得られません。まず、オブジェクト内のプロパティ、次にプロトタイプのチェーン。

最初の例では、ローカルプロパティを「削除」すると、変更が有効になります。例:

class MyClass { 
    constructor() { 
    // more code 

    this.myFunction = function() { 
     console.log('not this'); 
    }; 
    } 
} 

// can't change the code above 

MyClass.prototype.myFunction = function() { 
    console.log('it should print this'); 
}; 

const obj = new MyClass(); 
delete obj.myFunction; 
obj.myFunction(); 

https://jsbin.com/gixufadewu/edit?js,console

+0

この回答は解決策を見つけるのにはあまり役に立ちませんが、問題と構造を理解するうえで最も役立ちます。 解決策として自分の答えを記入することはできないので、問題を理解するのに役立ちましたので、解決策としてマークします。 – PetaByteBoy

0

これを行うことはできません。 MyClassをインスタンス化すると、いつでも内部のmyFunctionが再定義されます。しかし、myFunctionはプロトタイプチェーンで定義されていません。したがって、インタプリタはまずインスタンス内のメソッドを探し、次にプロトタイプチェーン内のメソッドを探します。 JavaScriptコードinheritanceで上書きできるプロトタイプチェーンでmethodsを定義します。

例:

var a = new MyClass(); 
var b = new MyClass(); 

a.myFunction() === b.myFunction(); //false 

a.__proto__.myFunction() === b.__proto__.myFunction() //true 
+0

元のクラスを変更することはできませんが、コンストラクタを継承でオーバーライドすることができます。これは私が探していたものではありませんが、同様に機能します。 – PetaByteBoy

0

元の質問の解決策がないので、私はこの使用して終了:明らか

class MyClass { 
    myFunction = function() { 
    console.log('not this') 
    } 
} 

class MyNewClass extends MyClass { 
    myFunction = function() { 
    console.log('should print this') 
    } 
} 

new MyNewClass().myFunction() 

を私は常に何かをしている、今MyNewClassを使用する必要があります私は本当に望んでいないし、元の質問は、既存のクラスの機能を上書きするソリューションを求めたが、これは私の場合に動作します。

0

は何ができることは、プロトタイプにゲッター/セッターを置くことによって割り当てを傍受することです:

function myFunction() { 
    console.log('it should print this'); 
} 
Object.defineProperty(MyClass.prototype, "myFunction", { 
    set(val) { /* ignore */ }, 
    get() { return myFunction; } 
}); 

また、あなたの可能性decorate the constructorextra precautionsを意味ES6クラスのけれども。

関連する問題