我可以设置实例化函数的原型吗?

时间:2008-11-23 22:36:00

标签: javascript

这失败,'X.m不是函数'......

var Y = function () {
    this.m = function () {
        alert('this is m');
    };
};

var X = new function () { };

X.prototype = new Y();
X.m();

如果我在X定义中跳过new关键字,然后在调用m()之前实例化X,那肯定会有效。为什么我不能这样做?

3 个答案:

答案 0 :(得分:2)

不,您无法设置原型并且具有以前现有实例的更改效果。但是,您可以修改原型对象以获得所需的效果。但不是你尝试过的方式。这是因为您的实例X是一个对象,而不是一个类。 (这是因为你在定义类之前使用了“new”运算符。)

简单测试:

var X = new function () { };
alert(X.prototype);  // displays "undefined" because X is an 
                     // object not a class

因此,当您在X上设置“prototype”属性时,您没有将模板对象存储在类中,您只是在对象X上创建一个名为“prototype”的新属性,所以,如果您这样做:

var Y = function () {
    this.m = function () {
        alert('this is m');
    };
};

var X = new function () { };
X.prototype = new  Y();
X.prototype.m();  // displays "this is m"

然后你得到你之前预期的输出。

即使您创建了X作为匿名类的实例,您仍然可以通过“constructor”属性访问该类。获得该引用后,即可修改原型对象。像这样:

X.constructor.prototype.m = new Y().m;
X.m();  // displays "this is m"

但是,您应该注意,这不起作用:

X.constructor.prototype = new Y();
X.m();  // fails

因为更改整个原型对象只影响将来创建的实例。

答案 1 :(得分:1)

在实际调用构造函数之前,应将prototype属性分配给您用作构造函数的函数。例如,这将按预期工作:

var Y = function () {
    this.m = function () {
        alert('this is m');
    };
};

var X = function () { };
X.prototype = new Y();

new X().m();

答案 2 :(得分:0)

当您在object上使用。{/ 1>时,您正试图在function上使用.prototype。

alert(typeof Y); alert(typeof X);

你实际上是在X上创建一个名为prototype的属性,而不是使用“magic”原型(试试X.prototype.m()来看看我的意思)。