2

这是一个丑陋的Javascript,如果能找到解决方法会很好。

Javascript 没有类,这是一件好事。但是它以一种相当丑陋的方式实现了对象之间的回退。基本构造应该是拥有一个对象,当无法找到某个属性时,它会退回到另一个对象。

因此,如果我们想a退回到b我们想要做的事情:

a = {sun:1};
b = {dock:2};
a.__fallback__ = b;

然后

a.dock == 2;

但是,Javascript 提供了一个new运算符和prototypes. 所以我们做的远不那么优雅:

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,但不是通用的。我仍然希望有一个更通用的解决方案。

4

2 回答 2

5

你可以只使用Object.create. 它是 ES5 的一部分,因此它已经在某些浏览器中原生可用。我相信它完全符合您的要求。

于 2010-05-10T18:27:38.647 回答
0

好的,更多的研究和跨平台检查,还有更多的信息(虽然不是一般的解决方案)。

一些实现基本上具有我为我的__fallback__. 它被称为__proto__并且是完美的:

a = {sun:1};
b = {dock:2};
a.__proto__ = b;

a.dock == 2;

看起来,在构造一个新对象时发生的情况大致是这样的:

a = new Constructor(...args...);

产生的行为大致相当于:

object.constructor = constructor;
object.__proto__ = constructor.prototype;
constructor.call(this, ...args...);

所以难怪后来调整对象的构造函数或constructor.prototype没有效果,因为__proto__设置已经设置好了。

现在对于我的 v8 应用程序,我可以只使用__proto__,但我知道这不会在 IE VM 上公开(我不运行 Windows,所以我不知道)。所以这不是问题的一般解决方案。

于 2010-05-10T18:31:39.027 回答