我正在寻找一种方法(最好不构建添加到的容器(,在JavaScript伪类的所有实例中循环,而不循环嵌套实例并递归地循环窗口对象的所有子对象。这可能吗?或者我除了创建一个数组之外别无选择,只能创建一个包含我想访问的任何伪类的所有实例的数组吗?
这是不可能的,因为一个对象不知道其他对象从中继承了什么。这是一种单向关系(从对象/实例到原型(。
并且并非所有对象都可以通过在window
上递归来达到。您无法访问函数中的局部变量。
您必须手动跟踪已创建的实例。
使用以下代码解决了这个问题(并消除了为继承链中的每个继承创建对象的虚拟实例的需要(:
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