[英]JavaScript: Overwrite property defined in constructor for whole class
我正在嘗試覆蓋一個類的功能:
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()
但是 Babel 將上面的內容編譯為:
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 將該定義放在構造函數中。 如果我理解正確,原型只包含函數,而不是所有屬性。 因為構造函數在對象從原型派生之后運行,所以我不能使用原型來覆蓋該函數。
我的第二次嘗試是覆蓋構造函數:
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()
好吧,讓我們試試……用 Babel 編譯,保存到 test.js 並運行:
~> node test.js
not this
我試圖使這個問題盡可能籠統。 關於為什么我不能在特定情況下更改類的更多背景信息:該類實際上來自我正在使用的庫,而我使用的其他包也依賴於該庫。 MeteorJS 需要包來指定其依賴項的確切版本和來源,這就是我不能使用 fork 的原因:我必須 fork 依賴於這個庫的每個包。
實際上,您正在更改您的課程,但它“沒有生效”,因為javascript 解釋器如何在其對象中查找信息。 首先,對象內部的屬性,然后是原型鏈。
在您的第一個示例中,如果您“刪除”本地屬性,您的更改就會生效。 例子:
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();
這是無法做到的。 每當您實例化MyClass
時,內部的myFunction
都會被重新定義。 但不是原型鏈中定義的myFunction
。 所以解釋器會先在實例中查找方法,然后在原型鏈中查找。 在原型鏈中定義可以被 JavaScript 繼承覆蓋的methods
。
例如:
var a = new MyClass();
var b = new MyClass();
a.myFunction() === b.myFunction(); //false
a.__proto__.myFunction() === b.__proto__.myFunction() //true
由於原始問題沒有解決方案,我最終使用了這個:
class MyClass {
myFunction = function() {
console.log('not this')
}
}
class MyNewClass extends MyClass {
myFunction = function() {
console.log('should print this')
}
}
new MyNewClass().myFunction()
顯然,我現在總是必須使用 MyNewClass,這是我並不真正想要的,並且最初的問題要求解決方案來覆蓋現有 Class 的功能,但這在我的情況下有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.