【问题标题】:I am doing something wrong with this prototype in JavaScript, any ideas?我在 JavaScript 中对这个原型做错了什么,有什么想法吗?
【发布时间】:2011-09-30 14:26:18
【问题描述】:

下面的代码并没有像我想象的那样产生原型。谁能看到我做错了什么?

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 类的正确方法,但我遗漏了一些东西。

【问题讨论】:

  • 如果你这样做console.log(a.prototype)会得到什么?

标签: javascript inheritance prototype-oriented


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    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 规范。

    【讨论】:

      【解决方案3】:

      因为您扩展了A 的原型,而new A() 返回了一个“匿名”对象。

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          【解决方案5】:

          把A改成

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

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

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

          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的原型。

          【讨论】:

          • 这修复了它。先生,您是当时的英雄!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多