如何在 Javascript 中实现此 C++ 模式?
How to implement this C++ pattern in Javascript?
来自继承 class 的方法应该 return 继承自谁的对象类型。在 C++ 中,这种行为很容易实现。但是我不知道如何在 javascript 中做到这一点。我知道错了,但我是这样写的。
class A {
someMethod() {
return new A();
}
}
class B extends A {
}
var b = new B();
b.someMethod() // should return an object of type B not A
在 C++ 中这很容易做到
template <typename c>
struct a
{
a() : _value(NULL) {}
a(std::string v) : _v(v) {}
static c* from_string(std::string &v)
{
return new c(v);
}
private:
std::string _v;
};
struct b : public a<b>
{
b() : b<a>() {}
b(std::string &v) : node<b>(a) {}
};
如何使用 javascript 来实现?
编辑
这不是继承class的方式,而是一种继承和创建对象的特殊模式。 Node.Js 中有几个例子,例如 Buffer.from
、Buffer.alloc。但我想从基础 class.
重现这个
有人告诉我可以使用以下脚本解决我的问题:
class A {
method() { return this.constructor(); }
}
class B {}
var b = new B();
var b1 = b.method();
我真正想做的是下面这样的事情。
class A {
static from() { return new this.constructor() }
};
class B extends A {};
a = A.from();
b = B.from();
a instanceof A // should be true
b instanceof B // should be true.
编辑 2
我发现了一些东西。
我在 typescript 中发现相同的 C++ 行为可以归档如下:
class a {
static from<t extends a>(c: { new(): t }) : t {
return new c();
}
};
class b extends a {
}
let b1 = a.from(b);
b1 instanceof b
b1 instanceof a
console.log(b1);
es6 等价物是:
class a {
static from(c) {
return new c();
}
}
;
class b extends a {
}
let b1 = a.from(b);
b1 instanceof b;
b1 instanceof a;
console.log(b1);
//# sourceMappingURL=index.js.map
正如我所说:C++ 中的模板 class 实际上是一个元 class。它用于从中构建其他 classes。
因此我们可以将此观察应用于 JavaScript。我玩过,这是我能得到的最接近的东西。先定义一个"template":
function TemplateA(cls) {
class A {
static from() {
return new cls();
};
foo() {
return -1;
};
};
return A;
};
现在定义自定义 "extends":
function Extends(base, derived) {
// Update statics
// (these should not be overwritten)
var common = {name: 1, prototype: 1, length: 1};
var statics = Object.getOwnPropertyNames(base)
.filter(el => !common[el]);
statics.forEach(el => {
derived[el] = base[el];
});
// Update instance methods
var instanceMethods = Object.getOwnPropertyNames(base.prototype);
instanceMethods.forEach(el => {
derived.prototype[el] = base.prototype[el];
});
};
最后用法:
class B {
test() { return 1; }
};
> Extends(TemplateA(B), B);
> var b = B.from();
> b instanceof B;
true
> var x = new B();
> x.foo();
-1
> x.test();
1
看来如你所愿。但这有一些缺点。它不是真正的继承(原型只是更新)。特别是 B
不是 A<B>
的子 class(实际上 Extends
之后甚至不存在这样的 class)。另一方面,JavaScript 的 inheritance/prototyping 非常独特,与 C++ 截然不同,因此我们不能指望一切正常。
旁注:
- 安全吗?大概。然而,它确实需要开发人员的大量纪律。例如,覆盖您不想覆盖的内容太容易了。
- 我会在生产环境中使用它吗?不太可能。无论您试图完成什么,很可能都可以通过其他一些标准方式实现。将解决方案视为一种学术乐趣。
- 最后:谁告诉你C++方式是最好的方式?你的游泳技术在攀岩时并没有多大用处,对吧?所以我强烈建议你重新考虑你的整个架构并尝试以不同的方式做事。
来自继承 class 的方法应该 return 继承自谁的对象类型。在 C++ 中,这种行为很容易实现。但是我不知道如何在 javascript 中做到这一点。我知道错了,但我是这样写的。
class A {
someMethod() {
return new A();
}
}
class B extends A {
}
var b = new B();
b.someMethod() // should return an object of type B not A
在 C++ 中这很容易做到
template <typename c>
struct a
{
a() : _value(NULL) {}
a(std::string v) : _v(v) {}
static c* from_string(std::string &v)
{
return new c(v);
}
private:
std::string _v;
};
struct b : public a<b>
{
b() : b<a>() {}
b(std::string &v) : node<b>(a) {}
};
如何使用 javascript 来实现?
编辑
这不是继承class的方式,而是一种继承和创建对象的特殊模式。 Node.Js 中有几个例子,例如 Buffer.from
、Buffer.alloc。但我想从基础 class.
有人告诉我可以使用以下脚本解决我的问题:
class A {
method() { return this.constructor(); }
}
class B {}
var b = new B();
var b1 = b.method();
我真正想做的是下面这样的事情。
class A {
static from() { return new this.constructor() }
};
class B extends A {};
a = A.from();
b = B.from();
a instanceof A // should be true
b instanceof B // should be true.
编辑 2
我发现了一些东西。
我在 typescript 中发现相同的 C++ 行为可以归档如下:
class a {
static from<t extends a>(c: { new(): t }) : t {
return new c();
}
};
class b extends a {
}
let b1 = a.from(b);
b1 instanceof b
b1 instanceof a
console.log(b1);
es6 等价物是:
class a {
static from(c) {
return new c();
}
}
;
class b extends a {
}
let b1 = a.from(b);
b1 instanceof b;
b1 instanceof a;
console.log(b1);
//# sourceMappingURL=index.js.map
正如我所说:C++ 中的模板 class 实际上是一个元 class。它用于从中构建其他 classes。
因此我们可以将此观察应用于 JavaScript。我玩过,这是我能得到的最接近的东西。先定义一个"template":
function TemplateA(cls) {
class A {
static from() {
return new cls();
};
foo() {
return -1;
};
};
return A;
};
现在定义自定义 "extends":
function Extends(base, derived) {
// Update statics
// (these should not be overwritten)
var common = {name: 1, prototype: 1, length: 1};
var statics = Object.getOwnPropertyNames(base)
.filter(el => !common[el]);
statics.forEach(el => {
derived[el] = base[el];
});
// Update instance methods
var instanceMethods = Object.getOwnPropertyNames(base.prototype);
instanceMethods.forEach(el => {
derived.prototype[el] = base.prototype[el];
});
};
最后用法:
class B {
test() { return 1; }
};
> Extends(TemplateA(B), B);
> var b = B.from();
> b instanceof B;
true
> var x = new B();
> x.foo();
-1
> x.test();
1
看来如你所愿。但这有一些缺点。它不是真正的继承(原型只是更新)。特别是 B
不是 A<B>
的子 class(实际上 Extends
之后甚至不存在这样的 class)。另一方面,JavaScript 的 inheritance/prototyping 非常独特,与 C++ 截然不同,因此我们不能指望一切正常。
旁注:
- 安全吗?大概。然而,它确实需要开发人员的大量纪律。例如,覆盖您不想覆盖的内容太容易了。
- 我会在生产环境中使用它吗?不太可能。无论您试图完成什么,很可能都可以通过其他一些标准方式实现。将解决方案视为一种学术乐趣。
- 最后:谁告诉你C++方式是最好的方式?你的游泳技术在攀岩时并没有多大用处,对吧?所以我强烈建议你重新考虑你的整个架构并尝试以不同的方式做事。