我在JavaScript中使用这个原型做错了什么想法?

时间:2011-07-07 15:51:13

标签: javascript inheritance prototype-oriented

以下代码不会像我想象的那样生成原型。谁能看到我做错了什么?

var A = function () {
    return {
        workingTest: function () {return "OK";}
    };
};

A.prototype.notWorkingTest = function () {return "Not so much";};

var a = new A();

a.workingTest(); // "OK"
a.notWorkingTest(); // TypeError: "undefined_method"

有什么想法吗?我认为这是扩展JS类的正确方法,但我遗漏了一些东西。

5 个答案:

答案 0 :(得分:3)

将A更改为

var A = function () {
  this.workingTest = function () {return "OK";};
};

问题是您的原始A函数正在创建并返回Object的直接实例,而不是使用由A运算符创建的new实例并绑定到this

要理解这一点,请尝试运行

var B = function () { return { x: 42 }; }
var C = function () { this.x = 42; }
var b = new B;
var c = new C;
alert("b.constructor === B : " + (b.constructor === B));  // false
alert("b.constructor === Object : " + (b.constructor === Object));  // true
alert("c.constructor === C : " + (c.constructor === C));  // true

因为B返回一个新对象,它返回的值不再是instanceof B,也不会使用B的原型。

答案 1 :(得分:0)

由于A返回单独的对象,a不是A类的实例;相反,它是一个普通的对象,恰好由A函数返回 它根本没有与A或其prototype相关联。

相反,您需要在构造函数中将workingTest分配给this,而不是返回任何内容:

var A = function () {
    this.workingTest = function () { return "OK"; };
};

答案 2 :(得分:0)

因为您在A返回“匿名”对象时扩展了new A()的原型。

答案 3 :(得分:0)

在现代浏览器中,您可以通过以下方式保持有趣的原型制作方法:

var A = {
  workingTest: function () {return "OK";}
};
A.notWorkingTest = function () {return "Yes it does";};

var a = Object.create (A);
a.workingTest(); // "OK"
a.notWorkingTest(); // "Yes it does"

a.extending = function () {return "extended";};
var b = Object.create(a);
b.workingTest(); // "OK"
b.extending();  // "extended"

这符合ES5规范。

答案 4 :(得分:0)

您将A定义为返回对象文字的函数。在调用函数时使用new关键字意味着它是一种特殊类型的函数,即构造函数。 JavaScript中的构造函数必须以特定方式编写,使用this关键字设置属性。

var A = function () {
  this.workingTest = function () {return "OK";};
};