Javascript 让对象回退到另一个对象
这是一段丑陋的 Javascript 代码,如果能找到解决方法就好了。
Javascript 没有类,这是一件好事。但它以一种相当丑陋的方式实现了对象之间的回退。基本构造应该是拥有一个对象,当找不到某个属性时,它会回退到另一个对象。
因此,如果我们希望 a
回退到 b
,我们会想要执行以下操作:
a = {sun:1};
b = {dock:2};
a.__fallback__ = b;
then
a.dock == 2;
但是,Javascript 提供了一个 new
运算符和 <代码>原型。所以我们做了远不那么优雅的事情:
function A(sun) {
this.sun = sun;
};
A.prototype.dock = 2;
a = new A(1);
a.dock == 2;
但除了优雅之外,这严格来说也不太强大,因为这意味着用 A 创建的任何东西都会得到相同后备对象。
我想做的是将 Javascript 从这种人为限制中解放出来,并能够为任何单个对象提供任何其他单个对象作为其后备。这样我就可以在有意义时保留当前行为,但在有意义时使用对象级继承。
我最初的方法是创建一个虚拟构造函数:
function setFallback(from_obj, to_obj) {
from_obj.constructor = function () {};
from_obj.constructor.prototype = to_obj;
}
a = {sun:1};
b = {dock:2};
setFallback(a, b);
但不幸的是:
a.dock == undefined;
有什么想法为什么这不起作用,或者有任何解决方案来实现 setFallback 吗?
(我通过 node.js 在 V8 上运行,以防这是平台相关的)
编辑:
我在下面发布了一个部分解决方案,该解决方案适用于 V8,但不是不一般。我仍然希望有一个更通用的解决方案。
Here's a ugly bit of Javascript it would be nice to find a workaround.
Javascript has no classes, and that is a good thing. But it implements fallback between objects in a rather ugly way. The foundational construct should be to have one object that, when a property fails to be found, it falls back to another object.
So if we want a
to fall back to b
we would want to do something like:
a = {sun:1};
b = {dock:2};
a.__fallback__ = b;
then
a.dock == 2;
But, Javascript instead provides a new
operator and prototypes
. So we do the far less elegant:
function A(sun) {
this.sun = sun;
};
A.prototype.dock = 2;
a = new A(1);
a.dock == 2;
But aside from elegance, this is also strictly less powerful, because it means that anything created with A gets the same fallback object.
What I would like to do is liberate Javascript from this artificial limitation and have the ability to give any individual object any other individual object as its fallback. That way I could keep the current behavior when it makes sense, but use object-level inheritance when that makes sense.
My initial approach is to create a dummy constructor function:
function setFallback(from_obj, to_obj) {
from_obj.constructor = function () {};
from_obj.constructor.prototype = to_obj;
}
a = {sun:1};
b = {dock:2};
setFallback(a, b);
But unfortunately:
a.dock == undefined;
Any ideas why this doesn't work, or any solutions for an implementation of setFallback
?
(I'm running on V8, via node.js, in case this is platform dependent)
Edit:
I've posted a partial solution to this below, that works in the case of V8, but isn't general. I'd still appreciate a more general solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,进行更多研究和跨平台检查,还有更多信息(尽管不是通用解决方案)。
有些实现基本上与我为
__fallback__
所做的一样。它被称为 __proto__ ,几乎是完美的:看起来,当构造一个新对象时发生的事情大致是这样的:
产生的行为大致相当于:
所以难怪稍后会出现并调整对象的 constructor 或 constructor.prototype 不起作用,因为 __proto__ 设置已经设置。
现在,对于我的 v8 应用程序,我可以只使用
__proto__
,但我知道这不会在 IE VM 上公开(我不运行 Windows,所以我无法判断)。所以这不是问题的通用解决方案。Okay, some more research and cross-platform checking and there's some more information (though not a general solution).
Some implementations have basically what I did for my
__fallback__
. It is called__proto__
and is about perfect:It seems that, what happens in when a new object is constructed is roughly this:
produces behavior roughly equivalent to:
So it is no wonder that coming along later and adjusting an object's constructor or constructor.prototype has no effect, because the
__proto__
setting is already set.Now for my v8 application, I can just use
__proto__
, but I understand it that this isn't exposed on the IE VM (I don't run windows, so I can't tell). So it is not a general solution to the problem.您可以只使用
Object.create
。它是 ES5 的一部分,因此它已经在某些浏览器中本地可用。我相信它完全符合您的要求。You could just use
Object.create
. It's part of ES5 so it's already available natively in some browsers. I believe it does exactly what you want.