js的原型链的子对象修改父对象
为什么引用值可以修改,原始值不能修改?
其实换句话说,就是通过构造函数实例化出的对象为什么都可以获取prototype的值,但修改的时候只能修改prototype的引用值不能修改原始值?
原始值它们是不可变的。你不能改变原始值本身,只能重新赋值一个新值。
而引用值它们是可变的。你可以修改引用值中的属性或元素,因为引用值本身存储的是一个指向实际数据的地址,而不是数据本身。当你修改引用值中的属性或元素时,实际数据在内存中的位置并没有改变,只是它的值被改变了。
因此,当你修改一个引用值的属性或元素时,其原型链上的所有对象都可以访问这个被修改的值。但是,如果你想要修改一个原始值,你必须重新赋值一个新值,而这个新值并不会影响原始值的原型链。
你可能会说,你不是胡扯狗也吗?为什么: var a = 1; a = 2;
可以修改?他也是原始值啊,那我要告诉你,这需要了解一些JavaScript底层的运行机制:
原始值的修改不是直接修改当前的值,而是在栈内存开辟出一块新的空间,把值存里面,再将 a
指向刚才的新空间,所以原始值并没有被修改,而是变量的值被修改了(也就是一旦原始值被赋值后就不能更改了)
那对于引用值来说,它们是存在堆内存中的,栈内存存放的是堆内存的地址,引用值变量指向栈内存,通过栈内存的地址找到堆内存的数据,所以它们修改是修改的堆内存的值实际数据
综上所述,我的理解就是:原型链的子对象不能修改父对象的原始值是因为原始值的值是存在于变量本身的栈内存中,而不是存在于堆内存中,开辟新空间存放原始值实际上是创建了一个新的变量,并将其指向一个新的栈内存地址,所以,原始值的修改只会影响到变量本身,而不会影响到其父对象的属性值。对于引用值来说子对象的修改会影响到父对象的值,因为它们在内存中是共享的,当子对象修改引用值其实修改的是堆内存的实际数据,因此,修改会影响到它的原型链上的所有对象,包括父对象和子对象
为什么下面代码会输出我是 Benz 车 ?
function Car() {
this.brand = 'Benz';
}
Car.prototype = {
brand: 'Mazda',
intro: function() {
console.log('我是' + this.brand + '车');
}
}
var car = new Car();
car.intro();
因为this
指向的是构造函数,而不是原型链,所以查找值时先从构造函数构造出的对象本身查找,之后沿着原型链一层层往下找
Car.prototype.intro();
如此则打印的是 我是 Mazda
,因为此时 this
指向的是原型(原型也是一个对象)