想要对js理解更深刻,就需要对内存空间有个清晰的认知。
- // 分配内存
- var obj = {
- b: 2
- }
-
- var obj1 = 1
-
- // 使用内存
- console.log(obj)
-
- // 回收内存?那基本数据类型怎么回收?
- obj = null
栈内存与堆内存本身没有区别,只是存储方式的差异,有了不同。


- var testHeap = {
- a: 10,
- b: 20,
- c: {
- m: 100,
- n: 110
- }
- }
-
- testHeap.a
- var a = 1;
- var b = a;
-
- console.log(a === b)
- b += 1;//栈中值的本身是无法修改的,var b = a赋值时,是先在栈中开辟内存b,然后将a的值赋值给b;当b = b+1是又会重新开辟一块空间,将b+1的值2赋值给b,原来的b占用的空间被释放
- console.log(a === b)
- console.log(a);
- console.log(b);
-
- var str = 'hello'
- str += 'world'
解析:栈中值的本身是无法修改的,var b = a赋值时,是先在栈中开辟内存b,然后将a的值赋值给b;当b = b+1是又会重新开辟一块空间,将b+1的值2赋值给b,原来的b占用的空间被释放

说明:
第一个打印中a b 的等价,并不表示他们是同一个地址(指向同一个内存地址)。a赋值给b的时候,其实是把1这个值赋值给了b,而不是赋值的内存地址。所以说,基础数据类型,是按值访问的。
- var a = 1;
- var b = a;
- console.log(a === b)
如:对字符串的操作一定是返回一个新字符串,原始字符串并没有被改变
- var str = 'hello world'
- str[0] = 'b'
-
- console.log(str) // 'hello world'基本数据类型值的本身不会被修改
- var a = {
- m: 1
- };
- var b = a; //b=a 赋值是赋值的内存地址,所以赋值后修改b,a也会被修改
- console.log(a === b) //true
- b.m = 2
- console.log(a === b)
- console.log(b.m);
- console.log(a.m);
赋值是赋值的内存地址,所以赋值后修改b,a也会被修改

- var a = {}
- var b = {}
- console.log(a == b) //false
此处a和b都由自己独立的内存地址,所以返回false
想要通过一个方法修改对象,而不改变原有对象
- // 示例1
- var person = {
- province: 'hubei',
- city: 'wuhan'
- }
-
- function getPerson(p, name, age) {
- p.name = name;
- p.age = age;
- return p;
- }
-
- var a = getPerson(person, 'Bob', 10);
-
- console.log(a);
- console.log(person);
- console.log(a === person);
说明:最后原有对象也被修改了,传入的是person对象的内存地址,所以修改p以后,person也会被修改
想通过Object.assign()方法创建一个新的对象bar,但是发现最后foo对象也被更改了
console.log(foo === bar);//进行了浅拷贝
- // 示例2
- var foo = {
- a: 1,
- b: 2
- };
- // Object.assign方法是浅拷贝,拷贝的是数据的内存地址
- var bar = Object.assign(foo, { c: 100 }); // a,b,c
-
- console.log(foo, bar);//foo被修改,{a: 1, b: 2, c: 100}
-
- var bar = Object.assign({}, foo, { c: 100 });
- console.log(foo, bar);//{a: 1, b: 2, c: 100}
- foo.b = 3;
- console.log(foo, bar);//{a: 1, b: 3, c: 100},{a: 1, b: 2, c: 100}
- console.log(foo === bar);//进行了浅拷贝