JavaScript中有没有办法实例化一个不一定是函数的对象?

时间:2011-08-26 22:07:37

标签: javascript metaprogramming prototype-programming

我的原型示例是以下伪代码:

var kind = ...;
...
var type = new kind();
...
var person = new type();
...
var john = new person();

但问题是type不是函数,因此new type()不起作用。 是否有可以添加到对象的特定属性以使其可以被new接受?

对我来说最重要的是原型链,这对我来说很重要,person.[[Prototype]]应该是type等,以防new无效。

创建子类型链不是一种选择。这里typeperson的元类型,而不是它的超类型。同样地,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),则更为可取。

3 个答案:

答案 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