【问题标题】:Why am I getting this type error: instance vs prototype为什么我会收到这种类型的错误:实例与原型
【发布时间】:2014-04-12 06:06:49
【问题描述】:

您好,我正在尝试了解 .prototype 和普通实例之间的区别,或者说发生了什么。谁能解释一下,为什么这段代码不起作用?我收到一个类型错误:“未定义不是函数”。我只是想看看 Ninja() 类和 .prototype 以及第一个实例之间会发生什么。然后我试图看看当我创建一个名为 ninja 的新 Ninja() 类时会发生什么。然后重复

     function Ninja() {
     this.swingSword = function() {
     return true;
     };
     }

     Ninja.prototype.swingSword = function() {
     return false;
     };

    var ninja = new Ninja;
    console.log(Ninja.prototype.swingSword());
    console.log(Ninja.swingSword());
    console.log(ninja.swingSword());
    console.log(ninja.prototype.swingSword());

【问题讨论】:

    标签: javascript class inheritance prototype instance


    【解决方案1】:

    prototypeFunction 对象的属性,并且所有函数对象都继承自Function,它们都具有该属性。在你的例子中,Ninja 是一个函数,但ninja 只是一个由Ninja 构造的对象,所以它没有prototype。因为它没有prototype,所以JavaScript 返回undefined。而您正试图在undefined 上拨打swingSword,这是不可能的。这就是您收到该错误的原因。

    你可以这样检查

    console.log({}.toString.call(Ninja));
    # [object Function]
    console.log({}.toString.call(ninja));
    # [object Object]
    console.log(Ninja.prototype);
    # { swingSword: [Function] }
    console.log(ninja.prototype);
    # undefined
    

    另外,请注意,您只在Ninja.prototype 上定义了swingSword,而不是在Ninja 上。当您调用Ninja.swingSowrd() 时,JavaScript 将首先在Ninja 中查找它,然后在其父原型中查找它,即Function.prototype。在Ninja 上的查找将不涉及Ninja.prototype。那就是您在该行也遇到了错误。

    【讨论】:

    • 好的。那为什么 Ninja.swingSword() 在控制台中不起作用?
    • @christopherclark 请检查更新的答案:)
    【解决方案2】:

    您不能调用Ninja.swingSword();,因为在调用Ninja() 构造函数/函数之前未定义该函数。 但是你可以做new Ninja.swingSword();返回true

    也就是说,ninja.prototype 是未定义的,因为它是Ninja 类的一个实例,并且所有prototype 变量都直接分配给ninja。但是,在构造时,您将 this.swingSword 设置为返回 true 的新函数。这就是为什么ninja.swingSword(); 将返回true,而不是您可能期望通过原型函数返回的false

    【讨论】:

      【解决方案3】:

      Ninja 函数没有 swingSword 方法,但 Ninja.prototype 有。函数是与许多其他对象相同的对象,不同之处在于您可以使用 new 关键字创建实例,并且它具有内置原型成员。

      如果我有一个像这样叫 Ben 的对象:

      var ben = {
        name:"Ben",
        address:{
          street:"street name",
          city:"city name"
        }
      }
      

      这里应该很明显,我没有 ben.street 但有一个 ben.address.street。

      关于构造函数和原型的解释可以在here找到。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-01
        • 2016-10-18
        • 1970-01-01
        • 2022-01-08
        • 1970-01-01
        • 2017-01-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多