您好我正在尝试了解.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());
答案 0 :(得分:0)
prototype
是Function
对象的属性,并且所有函数对象都从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.prototype
。 Ninja
上的查询不会涉及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。