该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-11-08
学习学习了
|
|
返回顶楼 | |
发表时间:2010-11-08
//感觉这个问题大家说的有点复杂
var a=[1,2,3] alert(a[2]) //3 因为数组有这个值a[2]所以当然要返回了 a[2]=a=[] // ? alert(a[2]) //undefined //常规思维 //如果要给变量赋值哪么首先是确定变量本身的属性,比如要给a[2]赋值 //首先计算a[2]之前是什么,如果没有定义a是一个数组哪么此时脚本就会直接报错 //因为 var a=[1,2,3] //既然此时确定了a[2]的值是3 //a[2]=3 //哪么往下走:从右到左,先执行a=[]此时的a是一个空数组[],也就是改变了 //原始定义的var a=[1,2,3]值的变量定义值a=[] //接着往右赋值a[2]=[],也就是说此时的a[2]不管值是多少,是继承自var a=[1,2,3] //而不是a=[] //因为a=[]没有a[2]这个元素, 此时a[]既然没有a[2]这个元素哪么 //a[2]==undefined相当于: var a=[] a[2]=? //没有值,当然返回的是undefined |
|
返回顶楼 | |
发表时间:2010-11-09
我是一名新手下面是我的理解,先看下面一个例子
int i = 0; i = i++; System.out.println("i = " + i);//i = 0; 这段代码分如下步骤执行 (1)i = 0 ,读取变量i的地址,把0的值赋给i; (2)i = i ++ ,因为=的优先级高于++,所以先执行赋值运算符=,编译器读取右边i的地址 (3)读取左边的i的地址(编译器并不认为右边i的地址等于左边的i的地址) (4)右边i++ (5)打印左边的i值(因为编译器拿到的是左边的i的值) 可以看出编译器按下面处理 int i = 0; int j = 0;// j = i ++ ; System.out.println("j = " + j); 其实,我认为上面的代码也是一样的 var a = {n:1}; a.x = a = {n:2}; alert(a.x); a.x = a = {n:2};左边a.x中的a和右边的a代表两个不同的地址,解释器如下处理; var a = {n:1}; var b = {n:1}; b.x = a = {n :2}; alert(b.n); alert(a.n); alert(a.x); var a = {n:1}; a.x = a = {n:2};//a.x中的a指向的是 {n:1}, alert(a.n);//2 ,证明解释器拿到的是 a = {n:2}; alert(a.x);// |
|
返回顶楼 | |
发表时间:2010-12-29
昨天遇到一位大神告知
var a=b=1; 运行时会报错,怎么都有点想不明白,试着尝试运行了一下,发现并没有出错提示,有点不甘心,看到 var a = {n:1}; a.x = a = {n:2}; alert(a.x); // --> undefined 感觉原理有点类似, 遂改写了一下 var a; a.x = a = {n:2}; alert(a.x); 居然真的报错了!看了上面各位的解释,这里在做一点小小补充,以便新手能够理解: 1.赋值运行算的顺序是从右到左的; 2.JS垃圾回收不会在语句执行时进行. a.x = a = {n:2}; 这条语句执行过程猜得没错的话应该是 1.查找a并得到a的引用 2.查找a.x发现未定义就重新分配内存并得他的引用 3.再次查找a并得到a的引用 4.给{n:2}分配内存并得到他的引用 5.将新a的引用指向{n:2}的引用 //注意:这里本来应该回收旧a及旧a的x,但因为执行完这条语句后才能GC,所以尚未销毁a,即第2步中的旧a.x的引用在内存中仍然存在 6.将旧a的x指向新的a的引用 7.垃圾回收旧a及旧a的x 个人见解,难免有误,欢迎指正. |
|
返回顶楼 | |
发表时间:2011-01-17
a.x = a = {n:2};
1. a={n:2}; 2. a.x={n:2}; //此时的a为{n:1},即{n:1}.x={n:2}; 所以alert(a.x)为undefined, 因为此时的a已经指向{n:2}, 没有为它的x属性赋值。 |
|
返回顶楼 | |
发表时间:2011-02-14
rainsilence 写道 看了两遍才明白。实际上最后alert(a.x);的a是{n:2},a.x=a的左边的a是{n:1}。 也就是说最后赋值的那个a,没有地方引用,所以alert(a.x);才会是未定义 LZ写了这么多也没明白。看这一句就明白了。。 |
|
返回顶楼 | |
发表时间:2011-02-14
对于lz第5点
function fun(){ var a = b = 5; } fun(); alert(typeof a); // --> undefined alert(typeof b); // --> number 其中 var a=b=5; 只是声明了局部变量a,而b并未声明,对于未声明的变量直接在js中赋值就会当做全局变量。 所有b本来就可以在外部读到。 |
|
返回顶楼 | |
发表时间:2011-02-16
最后修改:2011-02-16
看这个代码
var a,b,c,d; a=b=c=d={a:1}; a.x=a=b.y=b=c.z=c={} console.log(a,b,c,d) 和结果: 我觉得是这样的,执行这句话的时候,发现有a.x b.y c.z,虚拟机会先把地址准备好,也就是虚拟机要做这件事: 先分别找a.x、a、b.y、b、c.z、c的地址,这时,a.x,b.y,c.z 分别指向旧对象内部的地址,而a,b,c分别为存放对象指针的地址,当赋值时,会将所有这些地址的值都赋值成赋值语句最右面的值。但是由于a.x,b.y,c.z分别指向旧对象的x、y、z域,故这几个值是赋给了就对象,即d,而a、b、c分别赋予了新值,即空对象,所以可以看到如图的结果 纯属推测,也许不是地址,是一个临时的setter也不一定,总之是虚拟机内部实现的。 这帖子里的问题和这个是一样的问题吧。 |
|
返回顶楼 | |