代码
function Person(name,age,sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.eat = function () {
console.log('人可以吃饭');
}
Person.prototype.sleep = function () {
console.log('人可以睡觉');
}
function Student(name,age, sex,score) {
this.score = score;
Student.prototype = new Person(name,age,sex);
}
Student.prototype.study = function(){
console.log('学生可以学习');
}
var stu = new Student('lilh',18,'man',100);
var ss = new Student('zy',18,'man',100);
console.log(stu.name);
console.log('=========');
console.log(ss.name);
结果:
疑问: stu.name 为什么会是undefined?
解析
function 的prototype 属性,在函数声明的时候,就存在了,这个时候,prototype指向的是object. 当声明对象语句var stu = new Student(‘lilh’,18,‘man’,100); 执行时,执行到
Student.prototype = new Person(name,age,sex); 这个语句时,stu这个对象的__proto__属性的指向实际上已经确定了; 它实际上指向了构造函数Student前面prototype指向的object. 所以对Student.prototype所做的一系列更改,比如添加方法,stu对象都已经不能使用了。
但是ss这个对象,因为stu创建时,已经执行了Student.prototype = new Person(name,age,sex); 这个语句,所以,此时构造函数Student的prototype,已经被重新赋值了。所以,该对象能够正常继承Person的属性。
正确的继承
接着上面的解析来说,正常的继承没有把Student.prototype = new Person(name,age,sex); 放在构造函数中使用,来进行继承的。 因为,这样会引起第一个创建的对象不能正常使用。 正确的代码:
function Person(name,age,sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.eat = function () {
console.log('人可以吃饭');
}
Person.prototype.sleep = function () {
console.log('人可以睡觉');
}
function Student(name,age, sex,score) {
this.score = score;
Person.call(this,name,age,sex); //这里使用call 并将this传递过去,这样Student就拥有了Person的属性
// Student.prototype = new Person(name,age,sex);
}
Student.prototype = new Person();// 这里不传值
Student.prototype.study = function(){
console.log('学生可以学习');
}
var stu = new Student('lilh',18,'man',100);
console.dir(stu);
var ss = new Student('zy',18,'man',100);
console.log(stu.name);
console.log('=========');
console.log(ss.name);
总结
我们是知道prototype的位置,需要放在对象创建之前的。但是这个例子告诉我们,prototype的位置还有另外一个特点,如果放在了构造函数当中,实际上,在第一个对象创建之前,引用的prototype,还是构造函数里的Prototype更改之前 的引用值。