问题
There are two pieces of codes.
Why is the first one correct but the second one incorrect?
What's wrong with this.prototype
?
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
if (typeof this.sayName != "function"){
Person.prototype.sayName = function(){
alert(this.name);
};
}
}
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
if (typeof this.sayName != "function"){
this.prototype.sayName = function(){
alert(this.name);
};
}
}
回答1:
Both of them are actually incorrect. But more on that later.
The second one is incorrect because objects don't have prototype
property. Only functions have a such a property.
In the second example, this
is an object, so this.prototype
is undefined
. In the first example you are setting Person.prototype
and Person
is a function, so all is "good".
Why is the first example still wrong? Because you usually don't have a reason to extend the prototype object inside the constructor. The constructor should only contain instance specific code and the prototype object should hold properties which are shared by all instances.
So your above example is correctly written as:
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype.sayName = function(){
alert(this.name);
};
回答2:
It's about how prototype is implemented.
When you saying Person.prototype.sayName 'Person.prototype' gives you the [[Prototype]] property of 'Person' to be modified with.
when calling this.prototype.sayName a property named 'prototype' is checked for 'this' object and if not found the object referenced by [[Prototype]] property of 'this', which is still not found cause you haven't defined it
P.S.
Haven't tested myself, but this.__proto__ shall work in some implementations
回答3:
in this.prototype
you are referring to the instance. The instance has no prototype, the constructor function does. You can replace:
if (typeof this.sayName != "function"){
this.prototype.sayName = function(){
alert(this.name);
};
}
with
if (!Person.prototype.sayName) {
Person.prototype.sayName = function(){
alert(this.name);
};
}
A method assigned to the prototpe will exist within all derived instances. this.sayName
in the first snippet doesn't exist on first instantiation, but your if ...
catches it and assigns Person.prototype.sayName
, which is subsequently available to new instances of Person
. That's why the first example works.
来源:https://stackoverflow.com/questions/22292881/javascript-prototype-declaration