面向对象在javascript中的实践之内存分析
2016-03-25 23:31
369 查看
分析下面代码的结果,并且阐述原因:
系统执行var a = {n:1}这句代码时,会开辟一个栈内存和一个堆内存。
在堆内存中存储了一个具体的对象Object {n: 1},在栈内存中存储了指向堆内存这个对象的一个地址a,也称之为指针。
当系统执行到 var b = a; 这句代码时,系统又在栈内开辟了一块空间b,b和a一样,都指向了堆内存中的那个对象Object {n: 1},简称对象①号,b也是一个指针。
当系统执行到这句代码时:a.x = a = {n:2}; 代码中点运算符的优先级比赋值要高,所以a.x优先被执行,a.x=a,表示对象①号Object {n: 1}有个属性x指向了对象a,此时对象①号变成了这样:Object {n: 1, x: Object}。
然后开始执行a = {n:2} ,这时候在堆内存中重新开辟了一块空间用于存储一个新的对象,即对象②号 :Object {n:2},此时栈中的a指向了这个新的对象—对象②号。
而对象①号变成了这样Object {n: 1, x: {n:2}} ,此时指针a与对象①号的关系,从此断开了。指针a指向了对象②号。
然后执行 console.log(a.x); 此时要输出的是对象②号的属性x,很显然是undefined。
最后执行console.log(b.x); 指针b一直保存的是对象①号的地址。很显然是个对象{n:2},在控制台上打印出的是这个对象②号即:Object {n: 2}。
画个图来说明问题吧:
var a = {n:1}; var b = a; a.x = a = {n:2}; console.log(a.x); console.log(b.x);一般系统在内存中会开辟两块空间用来存储数据,一个是栈区域(用于存储简单数据类型和变量),一个是堆区域(用于存储复杂数据类型,如函数,数组,对象)。
系统执行var a = {n:1}这句代码时,会开辟一个栈内存和一个堆内存。
在堆内存中存储了一个具体的对象Object {n: 1},在栈内存中存储了指向堆内存这个对象的一个地址a,也称之为指针。
当系统执行到 var b = a; 这句代码时,系统又在栈内开辟了一块空间b,b和a一样,都指向了堆内存中的那个对象Object {n: 1},简称对象①号,b也是一个指针。
当系统执行到这句代码时:a.x = a = {n:2}; 代码中点运算符的优先级比赋值要高,所以a.x优先被执行,a.x=a,表示对象①号Object {n: 1}有个属性x指向了对象a,此时对象①号变成了这样:Object {n: 1, x: Object}。
然后开始执行a = {n:2} ,这时候在堆内存中重新开辟了一块空间用于存储一个新的对象,即对象②号 :Object {n:2},此时栈中的a指向了这个新的对象—对象②号。
而对象①号变成了这样Object {n: 1, x: {n:2}} ,此时指针a与对象①号的关系,从此断开了。指针a指向了对象②号。
然后执行 console.log(a.x); 此时要输出的是对象②号的属性x,很显然是undefined。
最后执行console.log(b.x); 指针b一直保存的是对象①号的地址。很显然是个对象{n:2},在控制台上打印出的是这个对象②号即:Object {n: 2}。
画个图来说明问题吧:
相关文章推荐
- js正则表达式用法汇总
- 开发JavaScript组件
- JSON-Linking data
- ExtJs之Ext.view.View
- js中使用EL表达式
- (三)JavaScript之[事件]与[字符串]
- JavaScript中多位数相加处理方法
- ExtJS获取父子、兄弟容器元素方法
- Extjs grid 单元格溢出用……代替
- Javascript
- ExtJs TabPanel右键功能插件Ext.ux.TabCloseMenu
- ExtJs之Ext.XTemplate:模板成员函数
- 3月25日 javascript练习
- 20行左右的(HTML和JS)代码实现的贪吃蛇游戏
- JS控制网页文字大小,使其能够自适应屏幕大小
- 【bzoj1029】[JSOI2007]建筑抢修
- ExtJs之Ext.XTemplate:数组填充,访问父对象
- 【bzoj1028】[JSOI2007]麻将
- 【bzoj1015】[JSOI2008]星球大战starwar
- 【bzoj1821】[JSOI2010]Group 部落划分 Group