【问题标题】:Is it possible to iterate over all instances of a JavaScript pseudoclass?是否可以遍历 JavaScript 伪类的所有实例?
【发布时间】:2013-02-25 10:53:26
【问题描述】:

我正在寻找一种方法(最好不构造将它们添加到的容器)来循环遍历 JavaScript 伪类的所有实例,而无需循环嵌套实例并递归遍历窗口对象的所有子对象。这是可能的,还是我没有办法,只能创建一个数组来保存我想要访问的所有实例的任何伪类的所有实例?

【问题讨论】:

  • 你能说明一下情况吗?有哪些“伪类”?您提到window 对象,是指DOM 中的HMTLElement 实例吗?
  • 如果“伪类”是指构造函数,那么是的,您必须手动保留对所有已创建实例的引用。
  • 伪类的含义类似于 function A() { this.foo = 'bar'; } 功能 A_B(newFoo) { this.foo = newFoo; } A.prototype.constructor = A; A.prototype.B = A_B; - 我正在寻找一种方法来访问从已知原型(在示例“A.prototype”中)继承的对象,而不需要维护一个列表或递归遍历所有已知对象并希望它可以从顶层访问。
  • 好的。正如我所说,这是不可能的,因为一个对象不知道其他对象从它继承了什么。这是一个单向关系(从对象到原型)。并非所有对象都可以通过窗口递归访问。您无权访问函数中的局部变量。
  • 谢谢,我必须创建一个静态实例属性来扩展应用程序的对象。

标签: javascript iteration global pseudo-class


【解决方案1】:

这是不可能的,因为一个对象不知道其他对象从它继承了什么。这是一个单向关系(从对象/实例到原型)。

并非所有对象都可以通过window 递归访问。您无权访问函数中的局部变量。

您必须手动跟踪创建的实例。

【讨论】:

  • 有没有办法将命令添加到对象的构造函数中,以确保即使对象后来被继承也能执行这些命令?作为一个例子,我有这个: Object.defineProperty(Object.prototype, 'instances', { enumerable: false, value: new Array() });函数 A() { this.__proto__.instances.push(this); } A.prototype.constructor = A; document.write(A.instances.length); var a = new A(); document.write(A.instances.length); var b = 新的 A(); document.write(A.instances.length);
  • 这需要行“this.__proto__.instances.push(this);”放置在构造函数中以使其发挥作用 - 这是否可以为所有对象自动化(仅出于本示例的目的),而不是手动将其插入从 Object 派生的每个构造函数中?
  • 不幸的是没有。但是我可以问一下你为什么要这样做吗?
  • 我正在编写一个 JavaScript 数据库(设计用于部署在绕过 5MB 本地存储限制的修改版 Chrome 上),它通过与节点的 socket.io 通信与 PostgreSQL 数据库和其他客户端同步.js 服务器,其中数据库中的数据由对象(从数据库加载的代码,行可以具有存储的属性 [列] 和状态属性 [未存储,但在加载代码足迹后创建]、方法、事件和子类- 表可以充当类,并且特定于 DB 的代码直接进入窗口)。它适用于内部 BI 应用程序。
  • 在大多数情况下,惰性是有效的,但是如果属性所依赖的成员的初始值在创建属性之后但在访问属性之前发生更改,则会出现问题。
【解决方案2】:

通过以下代码设法解决了这个问题(并且不再需要为继承链中的每个继承创建一个虚拟对象实例):

Object.defineProperty(Object.prototype, 'constructing', {
    enumerable: false,
    writable: true,
    value: false
});
Object.defineProperty(Object.prototype, 'construct', {
    enumerable: false,
    get: function () {
        if ((this === Object) || (this.constructor === Object)) { return; }
        if (this.constructing === false) {
            this.constructing = this.__proto__.constructor;
        }
        if (this.constructing.hasOwnProperty('instances')) { this.constructing.instances.push(this); }
        var c = this.constructing;
        if ('base' in c) {
            this.constructing = c.base;
            this.constructing.call(this);
        }
        if (c !== this.__proto__.constructor) {
            for (var i in c.prototype) {
                if (!this.__proto__.hasOwnProperty(i)) { this.__proto__[i] = c.prototype[i]; }
            }
        }
    }
});

function A() {
    this.construct;
    this.foo = 'foo';
}
function A_bar() { console.log(this.foo + 'foo'); }
A.prototype.constructor = A;
A.prototype.bar = A_bar;
A.instances = new Array();

function B() {
    this.construct;
    this.foo = 'bar';
    var base = this.__proto__.constructor.base.prototype;
}
function B_bar() { console.log('bar'); }
B.base = A;
B.prototype.constructor = B;
B.prototype.bar = B_bar;
B.instances = new Array();

document.write(A.instances.length);
document.write(B.instances.length);
var a = new A();
document.write(a.foo);
document.write(A.instances.length);
document.write(B.instances.length);
var b = new B();
document.write(b.foo);
document.write(A.instances.length);
document.write(B.instances.length);
var c = new B();
document.write(c.foo);
document.write(A.instances.length);
document.write(B.instances.length);
a.bar();
b.bar();
c.bar();

输出:

00foo10bar21bar32

【讨论】:

    猜你喜欢
    • 2010-11-17
    • 2013-02-12
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 2012-04-11
    • 1970-01-01
    相关资源
    最近更新 更多