提问人:Selim Choueiter 提问时间:11/6/2023 最后编辑:Selim Choueiter 更新时间:11/13/2023 访问量:158
在 JavaScript 中将类绑定到类的每个新实例
Bind class to every new instance of a class in JavaScript
问:
我最近被拿了一堆 JavaScript 谜语,并且真的在这个谜语上停留了大约一天半(就上下文而言,所有其他谜语最多需要 1 小时)。由于我想自己提出最终的解决方案,我将发布一段类似的代码,以便我可以抓住大致的想法并根据谜语的上下文实现它。
假设这是一段代码:
class Vehicle {
constructor(brand, model, power) {
this.brand = brand;
this.model = model;
this.power = power;
}
info() {
return `This vehicle is a ${this.brand} - ${this.model}, with a power of ${this.power}`;
}
}
//do something with my class here such that
//the next calls will return/display as follows
const v = new Vehicle('Mercedes', 'C class', 12345);
console.log(v.info()); // This vehicle is a Mercedes - C class, with a power of 12345
const {
info
} = v;
console.log(info()); // This vehicle is a Mercedes - C class, with a power of 12345
//To keep in mind, the function should stay the same, so a call to (info === v.info) should return true;
//And only the part of the code where it says to enter the code can be changed, so the class should be untouched.
我知道这不应该是一个也许会在日常生活中使用的情况,因为它是一个谜语,只是为了挑战我们的大脑,但它挑战了我,以至于我放弃了哈哈。
我尝试循环遍历 Vehicle.prototype 的条目,并将每个作为函数且不是构造函数的条目设置为绑定到类的相同函数,或 class.prototype 或类似的东西,但它不起作用。
我该如何解决它,或者至少使它能够在每次创建该类的新实例时编辑函数调用?
编辑: 我尝试使用bind方法,甚至尝试过这样的东西
Vehicle.prototype['info'] = Vehicle.prototype['info'].bind(Vehicle.prototype);
Vehicle.prototype['info'] = Vehicle.prototype['info'].bind(Vehicle);
Vehicle.prototype['info'] = Vehicle.prototype['info'].bind(Vehicle.prototype['info']);
我尝试了许多替代方案,但它们不起作用,因为我必须将其绑定到创建的类的每个实例。因此,如果创建了一个新实例,并且在那里执行了相同的操作,则每个实例都将根据从中提取数据的实例返回数据。
答:
保持为 .您需要使用 .info === v.info
true
bind()
class Vehicle {
constructor(brand, model, power) {
this.brand = brand;
this.model = model;
this.power = power;
}
info() {
return `This vehicle is a ${this.brand} - ${this.model}, with a power of ${this.power}`;
}
}
const v = new Vehicle('Mercedes', 'C class', 12345);
console.log(v.info());
const info = v.info;
console.log(info.bind(v)());
console.log(info === v.info);
更新:
gog 的另一个优雅解决方案。我在这里添加了它,因为这个问题已经结束了。
class Vehicle {
constructor(brand, model, power) {
this.brand = brand;
this.model = model;
this.power = power;
}
info() {
return `This vehicle is a ${this.brand} - ${this.model}, with a power of ${this.power}`;
}
}
let fn = Vehicle.prototype.info
Object.defineProperty(Vehicle.prototype, 'info', {
get() {
return this._bound ?? (this._bound = fn.bind(this))
}
});
const v = new Vehicle('Mercedes', 'C class', 12345);
console.log(v.info());
const {
info
} = v;
console.log(info());
console.log(info === v.info)
该方法应在类的构造函数中使用,而不是在原型上使用。bind()
如果要将方法绑定到类本身,而不是实例,可以这样做:
class Vehicle {
static info() {
return `This is a vehicle`;
}
}
Vehicle.info = Vehicle.info.bind(Vehicle);
console.log(Vehicle.info()); // This is a vehicle
在这种情况下,将方法绑定到类本身。Vehicle.info = Vehicle.info.bind(Vehicle);
info
Vehicle
评论
info()
你面临的问题是,当你从实例中解构时,你基本上是在借用它的方法,所以不再正确绑定,你需要重新绑定它。info
v
this
class Vehicle {
constructor(brand, model, power) {
this.brand = brand;
this.model = model;
this.power = power;
}
info() {
return `This vehicle is a ${this.brand} - ${this.model}, with a power of ${this.power}`;
}
}
//do something with my class here such that
//the next calls will return/display as follows
const v = new Vehicle('Mercedes', 'C class', 12345);
console.log(v.info()); // This vehicle is a Mercedes - C class, with a power of 12345
// here is where the issue starts,
// now info is no longer "connected" to v instance,
// the function is just borrowed from that object
const {
info
} = v;
// so you need to rebind it before use
console.log(info.bind(v)()); // This vehicle is a Mercedes - C class, with a power of 12345
//To keep in mind, the function should stay the same, so a call to (info === v.info) should return true;
//And only the part of the code where it says to enter the code can be changed, so the class should be untouched.
评论
bind()
this