我的原型示例是以下伪代码:
var kind = ...;
...
var type = new kind();
...
var person = new type();
...
var john = new person();
但问题是type
不是函数,因此new type()
不起作用。
是否有可以添加到对象的特定属性以使其可以被new
接受?
对我来说最重要的是原型链,这对我来说很重要,person.[[Prototype]]
应该是type
等,以防new
无效。
创建子类型链不是一种选择。这里type
是person
的元类型,而不是它的超类型。同样地,kind
是元元类型。以下测试可阐明要求:
完成后,我想要这些积极的测试:
console.log(john instanceof person); // should be true
console.log(person instanceof type); // should be true
console.log(type instanceof kind); // should be true
和这些否定测试:
console.log(john instanceof type); // should be false
console.log(john instanceof kind); // should be false
console.log(person instanceof kind); // should be false
我听说通过分配到__proto__
属性可以做出这种魔法,但不知道怎么做。显然,如果有便携式解决方案(例如使用Object.create
),则更为可取。
答案 0 :(得分:2)
是否有可以添加到对象的特定属性以使其可以被
new
接受?
没有。根据ECMAScript第11.2.2节控制此功能的属性称为[[Construct]]
,从方括号可以看出,它是一个内部属性。它不受ECMAScript代码的影响。根据13.2节,创建Function对象时,唯一的时间[[Construct]]
被分配。
ECMAScript第三版中对原型继承的唯一访问是通过创建具有prototype
属性的构造函数。即使您不打算对其执行任何操作,也必须创建该功能。 This question涵盖了类/实例系统的常见模式。
在ECMA 5中,你确实得到了Object.create()
。为了与当前不支持它的浏览器兼容,您可以使用不执行任何操作的临时构造函数自己实现Object.create()
的那部分,例如:
if (!('create' in Object)) {
Object.create= function(proto, props /* optional */) {
var obj;
if (proto===null) {
obj= {};
} else {
Object.create._construct.prototype= proto;
obj= new Object.create._construct();
Object.create._construct.prototype= null;
}
if (props!==undefined)
Object.defineProperties(obj, props);
return obj;
};
Object.create._construct= function() {};
}
(当然Object.defineProperties
是另一种ES5方法,如果你想要支持,你必须小心翼翼,并且这不可能在纯ES3中实现,只能使用其他浏览器扩展。)
我听说通过分配到
__proto__
属性可以做出这种魔法,但不知道如何。
这始终是非标准的,即使在Firefox中也会消失。不要理会它。
答案 1 :(得分:0)
尝试new type.constructor()
,它会创建一个与type
相同类型的新对象,这可能是您想要的。
答案 2 :(得分:0)
据我了解,您希望type
继承kind
?是吗?
如果是的话......
function kind() {};
kind.prototype.name = "fred";
function type() {};
type.prototype = new kind();
var person = new type();
colsole.log(person.name); //fred
console.log(person instanceof type); // true
console.log(person instanceof kind); // true
console.log(type.prototype instanceof kind); //true