function People() {
}
People.prototype.say = function () {
alert("hello");
}
function Student() {
}
Student.prototype = new People();
var superSay = Student.prototype.say;
Student.prototype.say = function () {
superSay.call(this); // 为什么会是"hello"?
alert("stu-hello");
}
var s = new Student();
s.say();
superSay.call(this)
Why is the People.prototype.say
function called? Who does this
point to?
this points to the

Student{}
class. You can verify this by adding a lineconsole.log(this)
abovesuperSay.call(this)
.Then, let’s look at this code
For the convenience of explanation later, I call the instance created by
new People()
hereInstance X
.Because
superSay = Student.prototype.say
, because the aboveStudent.prototype = new People();
, soStudent.prototype
isinstance X
.So actually
superSay
callssay
ofinstance X
, notPeople.prototype.say
.As for why you think you are calling
In addition, the
superSayPeople.prototype.say
, it is mainly a problem with the prototype chain.Instance X
is an instance of the People class, so all methods ofInstance So
Instance X.sayIf the
saymethod is not overridden for
Instancecall
insuperSay.call(this)
just changes the context ofthis
. However, sinceis
instance
This problem is often encountered in js
Personal opinion: Let’s first talk about the search sequence for finding the say method: s——student.prototype——people.prototype——Object. If found, it is ready and stop searching. Combined with your code, say will only find student.prototype. Here you can first change your code to look like this to make it clearer:
Others remain unchanged. At this time, s.say() - outputs 321, s.jiao() - outputs 456. Then go back to your code, because you have overridden the sdudent.prototype.say method, so this code will be executed
The first sentence superSay.call(this), first superSay is a variable, the variable type is function, you can add a piece of code console.log(typeof supperSay) after var superSay = Student.prototype.say, so you just Call this function, and this variable stores Student.prototype.say. Execute to var superSay = Student.prototype.say. In fact, the value assigned here is People.prototype.say. This point is similar on pages 166-167 of Elevation. Regarding this point, you can change these two sections of your code to this, leaving the rest unchanged.
An error will be reported when calling superSay at this time, because when var superSay = Student.prototype.say is executed; student.prototype has only one constructer attribute and no say method. Then go back to your code and People.prototype.say will be assigned to superSay
Bind this in the superSay constructor to Student.prototype.
Aren’t you afraid that the poster will be fooled by all the talk upstairs?
In his program, stuSay points to the anonymous function object function () {alert("hello");}. As long as you don't reassign stuSay, it will always point to this function object. No matter where you call it, it will always be like this. As a result, as for who this points to inside the function body, please read the Rhinoceros book...