JS 对连等赋值的一些探索

本文探讨了JavaScript中的连等赋值现象,通过实验分析了变量声明、赋值顺序和赋值方式。结论表明,连等赋值是从左向右进行,每个变量在赋值过程中指向同一对象,而非右向左赋值。实验结果验证了这些理论,并对初识印象中的错误进行了修正。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在之前做练习时遇到了类似下面这道题的场景,发现输出结果和预期结果略有出入。本文对JS中的连等赋值做个简单讨论。

var a = b = c = 1;

function test(){
	var a = b = c = 2;
	console.log(a, b, c); //  2, 2, 2;
}
test();

console.log(a, b, c); // 1, 2, 2;

结论

var a = b = c = {value : 1};

// 等价于

var tmp = {value : 1};
var a = tmp;
b = tmp;
c = tmp;

两个探索 v1.0

  1. 变量声明命令var是否对连等赋值中的所有变量都有用?

    做个实验

    function test(){
        var a = b = c = 1;
    }
    test();
    
    console.log(a);
    console.log(b);
    console.log(c);
    

    var声明的变量具有函数作用域,在函数test()中声明的变量,在函数外部是访问不到的。

    预期结果一
    如果vara b c都有用,那么变量a b c都是函数test()的内部变量,此时打印变量a b c都会报错未声明。

    预期结果二
    如果var只对a有用,那么变量a是函数test()的内部变量,而变量b c则会隐式地声明为window对象的属性,即全局变量,此时打印变量a 会报错未定义,而打印b c则会正常显示为1

    实验结果

    // console.log(a); // a is not defined
    console.log(b); // 1
    console.log(c); // 1
    

    验证
    我们同时试着打印一下window对象中a b c,发现b c确实被声明成了全局变量。

    function test(){
    	var a = b = c = 1;
    }
    test();
    
    console.log(window.a); // undefined
    console.log(window.b); // 1
    console.log(window.c); // 1
    
  2. 连等赋值的实际赋值过程是什么样的? (内容有误,以改正内容为准)

    从赋值号=它本身的规则来讲,是从右向左运算的,将右边的值赋值给左边的变量。这么来考虑,其过程好像是很清晰的。即

    var a = b = c = 1;
    // 等价于
    c = 1;
    b = c;
    a = b;
    

    但有没有可能是这样下面的

    var a = b = c = 1;
    // 等价于
    c = 1;
    b = 1;
    a = 1;
    

    做个实验
    我们用对象{value : 1}来代替1.

    var a = b = c = { value : 1};
    
    console.log(a === b);
    console.log(b === c);
    console.log(a === c);
    

    我们知道对象之间进行想等比较时,比较的是两个对象的地址是否一致,也就是说只有变量指向同一个对象时,才返回true

    预期结果一
    如果是第一种赋值方式,那么三个变量都会指向同一个对象,结果应该为三个true

    预期结果二
    如果是第二种赋值方式,那么三个变量各自会指向不同的对象,结果应该为三个false

    实验结果

    var a = b = c = { value : 1};
    
    console.log(a === b); // true;
    console.log(b === c); // true;
    console.log(a === c); // true;
    

两个改正 v1.1

  1. 赋值顺序

    起初以为是从右向左依次赋值,但后来实践中推翻了这个猜测。实际上是从左向右。

    做个实验

    var a = { value : 1};
    b = a;
    a.obj= a = { value : 2};
    console.log(b);
    

    预期结果一
    如果是从右向左赋值(即先赋值a再赋值a.obj),此时a指向了一个新的对象,那么对a.obj进行赋值就不会影响b,输出结果应该是{value:1}

    预期结果二
    如果是从左向右赋值(即先赋值a.obj再赋值a),那么在对a.obj进行赋值时,ab指向的是同一个对象,那么输出结果的对象中会包含valueobj两个属性。

    实验结果
    实验结果
    结果中显示有valueobj两个属性,则说明连等赋值的赋值顺序是从左向右

  2. 赋值方式

    同时因为赋值方向的确定,此前猜测的赋值方式也是错误的。在之前的猜测中,为了解释连等语句中a = b = c = {value : 1},a b c三个变量指向同一个对象。认为下一个变量是用上一个变量赋值的。
    但实际上没有那么复杂,就是创建一个对象,然后依次让a b c指向这个对象。
    可以理解为其等价操作是:

    var tmp = {value: 1};
    a = tmp;
    b = tmp;
    c = tmp;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值