JS中if语句条件如果是赋值语句,那么结果会是什么?

比方说下面这段代码:

var arr = [0,1,2,3,4,5]
for (var i = 0; i < arr.length; i++) {
    if(arr[i] = 0){
        arr.splice(i , 1)
    } 
}
console.log(arr);    //结果是[ 0, 0, 0, 0, 0, 0 ]

而如果把条件的右边换成其他数,比方说5或者8,只要不是0就可以,结果如下:

var arr = [0,1,2,3,4,5]
for (var i = 0; i < arr.length; i++) {
    if(arr[i] = 5){
        arr.splice(i , 1)
    } 
}
console.log(arr);    //结果是[ 1, 3, 5 ]

我想知道if语句的括号里面发生了什么,我试着用一个小demo去理解,发现只要是等式成立,那么返回的结果都可以被转换成true,我的demo如下,在控制台的显示是:

var a = 1    //undefined
Boolean(a = 3)    //true

请问怎么理解上面的代码呢,为什么if语句赋值恒为true不是删完所有的数组项呢?输出结果有些让人匪夷所思。

阅读 8.3k
5 个回答
  • 第一个: arr[i] = 0执行的是先赋值,得到结果0,再执行if(0),0是false啊,所以不进if语句,所以循环一遍其实就是挨个赋值了,得到6个0不难理解吧
    if(arr[i] = 0){

        arr.splice(i , 1)
    } 
  • 第二个:其实看起来结果很诧异,运行一下就知道了

当i=0时,进入if,数组变为[5,1,2,3,4,5],执行删除——>[1,2,3,4,5]
当i=1时,进入if,数组变为[1,5,3,4,5],执行删除——>[1,3,4,5]
当i=2时,进入if,数组变为[1,3,5,5],执行删除——>[1,3,5]
当i=3时,此时数组长度仅为3,跳出循环,得到最终结果

赋值语句的返回值是被赋的值本身。

也就是说你第一段代码的 if 进不去是因为都是 if(0),第二次都是 if(5) 所以就进去了

我们经常会这样利用这个特性:

var a5 = a[5] || (a[5] = 100)
// 取 a 的 5 号位,如果没有值(或者 falsey),为它赋值并取它的值

聪明如你应该一下就能看懂

注意一个区别,变量声明语句没有返回值,这解释你最后一段的倒数第二行代码
简单的验证:

var a = 1 // undefined
a = 2 // 2

希望对你有帮助

我找到答案了!
一、首先说if(arr[i] = 0)的情况,这里也用上面类似的小demo演示:

var a = 1    //undefined
Boolean(a = 0)    //false

看到了吗,此时if语句的条件最终的结果是false,也就是说每次循环都执行了if语句里面的赋值,但是条件不符合,所以if语句里面的代码块没有执行,结果就是6个0。

二、再说说if(arr[i] = 8)的情况:

  1. 第一次循环,i=0,if语句括号里面赋值后结果是true,所以执行条件体,删除数组第0项,

此时的数组是[1,2,3,4,5]

  1. 第二次循环,i=1,if语句括号里面赋值后结果是true,所以执行条件体,删除数组第1项,

此时的数组是[1,3,4,5]

  1. 第三次循环,i=2,if语句括号里面赋值后结果是true,所以执行条件体,删除数组第2项,

此时的数组是[1,3,5]

  1. 第四次循环的时候,i=4,而此时数组长度为3,条件不符合,循环结束。

这样就缕清楚了!

第一段代码对数组进行了赋值操作
第二段代码对数组进行删除元素操作,结果:[ 1, 3, 5 ] 是删除后剩下的元素
希望能帮到你

其实这个都是因为赋值表达式的值是赋值表达式右值。
所以你第一段代码中的

if(arr[i] = 0){ // 这里因为赋值值为0,永远为假,下面的语句不会执行
        arr.splice(i , 1)
    } 

后面

Boolean(a = 3) //这里如果赋值为a=3 !=0 所以返回真,如果是a=0,则返回假。 
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题