一,关于原型覆写为什么要在构造函数外
function Parent(){
this.name ='parent'
this.play=[1,2,3]
}
function Child(){
this.type='child'
Child.prototype=new Parent(); //undefined
}
// Child.prototype=new Parent(); * //parent
let son = new Child();
console.log(son.name)
二,new实现的过程
1.创建一个空的简单Javascript对象 (即{});
2.链接该对象(即设置该对象的构造函数)到另一个对象;
3.将步骤1新创建的对象作为this的上下文;
4.如果该函数没有返回对象,则返回this;
三. 模拟一个new
function myNew(fn) {
let o = Object.create(fn.prototype)
let k = fn.call(o);
if (typeof k === 'object') {
return k;
} else {
return o;
}
}
四.关于原型写在构造函数里,输出undefined问题
在new一个实例的时候,先是将这个空对象附加一个__proto__属性指向原型对象,也就是说先连接原型对象再执行构造函数中的代码。
function Parent(){
this.name ='parent'
this.play=[1,2,3]
}
function Child(){
this.type='child'
Child.prototype=new Parent();
}
let son1 =new Child();
console.log(son1.name) //undefined
在new 一个son1的时候,连接原型,执行构造函数
function myNew(fn) {
// 以构造函数fn的prototype为原型 创建一个新的简单对象
let o = Object.create(fn.prototype)
// 改变fn的this指向到o,并执行fn
let k = fn.call(o);
// 如果构造函数没有返回对象,则返回o
if (typeof k === 'object') {
return k;
} else {
return o;
}
}
这里要注意了:如果构造函数没有返回对象,则返回o !
明显我们new son1的时候,k不是对象,它只是执行了Child的构造函数,最终我们的son1接收的是o的值。
那么我们在执行构造函数时,遇见了这条语句
Child.prototype=new Parent();
执行了吗?执行了,但是这条语句无法影响到o,因为o的原型已经赋完值了,o指向的是最初的Child原型,后面再改变构造函数Child的原型指向,但此时无法影响到o了。
再看:
function Parent(){
this.name ='parent'
this.play=[1,2,3]
}
function Child(){
this.type='child'
Child.prototype=new Parent();
}
let son1 =new Child();
console.log(son1.name) //undefined
let son2 =new Child();
console.log(son2.name) //parent
son2为什么能够继承Parent?
因为在第一次new的时候改变了Child的原型指向,能够使得后续的实例能够实现继承
总之:
在构造函数中覆写原型能够使后续实例实现继承
但是第一个实例它的原型对象是开始的,后面又被改变了,可以说这份最开始的原型对象是第一个实例所独有的。