用个例子说明问题:function F(){};var p1 = new F();F.prototype = {};var p2 = new F()console.log(p1.constructor)//Fconsole.log(p2.constructor)//Object
在这里原型不是在p1对象实例后重写了原型对象为空对象,那么应该p1和p2两个构造函数都输出Object.为什么p1输出F?在此感恩各位师兄解惑!
var obj1 = { a: 1 } console.log(obj1.a) // 1 obj1 = {} console.log(obj1.a) // undefined
原型修改只作用于修改之后创建的对象
不过话说回来,真心不赞成没事改原型玩。在实际开发中真心没找到修改原型的作用。
画的不是很好,希望能提供帮助,调用实例的constructor属性其实是原型对象的属性
constructor
首先你要明白,F.prototype 是对一个实例对象的引用,这个实例对象在你创建函数 F( ) 的时候同时被生成,如果我们给这个对象起个名字叫做 A,那么我们可以简单的理解为:A 是一个被存储在内存中的一个实例对象,而 F.prototype 是指向 A 的一个指针。
同时,A 对象内也有一个指针 constructor ,它指向了函数 F()。
那么当你第一次使用 new F( ) 时,生成了一个新对象 a ,p1 是对象 a 的一个引用(即p是指向a的一个指针),而 a 的 __proto__ 属性在此时也已经被指向为 A。
即目前,指向对象实例 A 的指针有两个,分别是 a.__proto__ 和 F.prototype。
之后你对 F.prototype 进行赋值时,实际上改变了 F.prototype 的指向,试他指向了另一个个实例对象{},我们管这个实例对象叫 B 好了,对于这个实例对象 B,它的 constructor 的属性指向了 Object。
请注意,此时 a 的 __proto__ 的指向并没有改变,仍是指向了实例对象A。
那么当你第二次调用 new F( ) 的时候,实际上生成了另一个新的实例对象 b, b 的 __proto__ 属性指向的是 B。
所以在 p1.constructor 的背后其实是相当于:p1 -> a, a.__proto__ -> A, A.constructor -> F( )。
而在 p2.constructor 的背后则为:p2 -> b, b.__proto__ -> B, B.constructor -> Object( )
恩,我也给张参考图吧,第二次 new 之后,最后的原型链大概是下面这个样子的。
原型修改只作用于修改之后创建的对象
不过话说回来,真心不赞成没事改原型玩。在实际开发中真心没找到修改原型的作用。
画的不是很好,希望能提供帮助,调用实例的
constructor
属性其实是原型对象的属性首先你要明白,F.prototype 是对一个实例对象的引用,这个实例对象在你创建函数 F( ) 的时候同时被生成,如果我们给这个对象起个名字叫做 A,那么我们可以简单的理解为:A 是一个被存储在内存中的一个实例对象,而 F.prototype 是指向 A 的一个指针。
同时,A 对象内也有一个指针 constructor ,它指向了函数 F()。
那么当你第一次使用 new F( ) 时,生成了一个新对象 a ,p1 是对象 a 的一个引用(即p是指向a的一个指针),而 a 的 __proto__ 属性在此时也已经被指向为 A。
即目前,指向对象实例 A 的指针有两个,分别是 a.__proto__ 和 F.prototype。
之后你对 F.prototype 进行赋值时,实际上改变了 F.prototype 的指向,试他指向了另一个个实例对象{},我们管这个实例对象叫 B 好了,对于这个实例对象 B,它的 constructor 的属性指向了 Object。
请注意,此时 a 的 __proto__ 的指向并没有改变,仍是指向了实例对象A。
那么当你第二次调用 new F( ) 的时候,实际上生成了另一个新的实例对象 b, b 的 __proto__ 属性指向的是 B。
所以在 p1.constructor 的背后其实是相当于:
p1 -> a, a.__proto__ -> A, A.constructor -> F( )。
而在 p2.constructor 的背后则为:
p2 -> b, b.__proto__ -> B, B.constructor -> Object( )
恩,我也给张参考图吧,第二次 new 之后,最后的原型链大概是下面这个样子的。