”studnet.prototype.x这里如果只是动态的修改studnet.prototype上面会被动态的修改,但是如果一整个studnet.prototype都全部修改的话,并不会影响已经new了的实例”
不懂为啥会不影响?感觉老师讲的不是很明白。。。。不知道是不是我理解问题,请教下!
可以这样理解:bosn.__proto__和student.prototype都是引用,在创建bosn的时候,bosn.__proto__指向了student.prototype指向的对象,之后你修改student.prototype指向的对象,是不会影响bosn.__proto__指向的对象的
因为在new一个Student类型的bosn对象实例时,会将Student.prototype的值赋值给bosn._proto_,而Student.prototype的值是它所指向的那个对象的地址(对象本身存在堆内存中),而[Student.prototype:对象地址]存在栈内存中,当通过Student.prototype.x修改对象时,修改的是存在堆内存的对象本身,因为bosn._proto_存的是对象的地址,所以bosn(包括所以已创建或指向这个地址的对象)肯定也会跟着一起变啦。但当你给Student.prototype赋予一个新对象的值时,会在堆内存新开辟一块地址存放这个对象,并且将对象的地址传给Student.prototype,所以原来的对象肯定不会跟着变啦,它们指向的都不是同一个对象。如果你能好好理解上边这一段,你就会明白JavaScript的引用传递和深拷贝浅拷贝等问题。
在前面的例子中 变量a和变量b的内存中保存的是个指针(即引用),也就是说它们所指向同一个对象。所以修改a的属性,会影响b的属性。但是当 a = 10; ( 或者 a = { y: 5}; ) 变量a中保存的值为5(或者引用另一个对象{ y: 5}的地址),再修改属性就不会影响变量b了。
这是因为js的坑比特性,当复制保存着对象的某个变量时,操作的是对象的引用。但在为对象添加属性时,操作的是实际的对象。举个例子:
var a = { x: 1 }; // 创建对象并将对象的引用传递给变量a(保存在内存中) var b = a; // 将对象的引用传递给变量b a.x = 2; // 修改变量a内存中保存的引用所指向的对象的属性x console.log(b.x); // 2 a = 10; // 修改变量a的值 console.log(b); // object
这种特性仅仅限于引用类型,基本类型和其他语言一样按照值传递。比如 a = 2 ; b = a; a = 3; console.lof(b); // 2
可是 改prototype中的一些就会影响到,改全部就不会影响。总感觉怪怪的。。
举个例子,一个女的生了个孩子,然后她去整容,只会影响她自己的样子,不会影响自己孩子的样子,这就是为啥new实例不会被修改。