[英]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.