为什么我会收到此类错误:instance vs prototype

时间:2014-04-12 06:06:49

标签: javascript class inheritance prototype instance

您好我正在尝试了解.prototype和常规实例之间的区别或发生的事情。任何人都可以解释它,为什么这段代码不起作用?我得到一个类型错误:“undefined不是一个函数”。我只是想看看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());

3 个答案:

答案 0 :(得分:0)

prototypeFunction对象的属性,并且所有函数对象都从Function继承,它们都具有该属性。在您的情况下,Ninja是一个函数,但ninja只是由Ninja构造的对象,因此它没有prototype。由于它没有prototype,因此JavaScript返回undefined。而您正试图在swingSword上致电undefined,这是不可能的。这就是你得到这个错误的原因。

您可以像这样检查

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

另请注意,您仅在swingSword而非Ninja.prototype上定义了Ninja。当您调用Ninja.swingSowrd()时,JavaScript会首先在Ninja中查找,然后在其父级原型中查找Function.prototypeNinja上的查询不会涉及Ninja.prototype。那就是你在这一行上也遇到了错误。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

Ninja函数没有swingSword方法,Ninja.prototype就是这样。函数是一个与许多其他对象相同的对象,区别在于您可以使用new关键字创建实例,并且它具有原型成员中的构建。

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

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

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

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