zoukankan      html  css  js  c++  java
  • 理解javascript中的连续赋值

    之前在扒源码时经常看到类似的连续赋值操作:

     var a = b = 1; 

    在某度搜了众多前辈的博客,总算对这骚操作有点眉目。

    Case analysis

    首先,javascript中连续赋值最典型案例是:

    var a = {n: 1}; 
    var b = a;
    a.x = a = {n: 2}; 
    console.log(a.x); //undefined 
    console.log(b.x); //{n: 2} 

     

    Analysis in short

    var a = {n: 1}; //创建对象{n: 1},a指向对象{n: 1}
    var b = a; //将 a中的地址传给b,即 b也指向对象{n: 1}
    a.x = a = {n: 2}; 
    /*
    1)创建对象{n: 1}中的"x"属性
    2)将a指向新对象{n: 2}
    3) 将对象{n: 1}中的"x"指向新对象{n: 2}
    */
    console.log(a.x); //undefined 
    console.log(b.x); //{n: 2} 

     如果看懂了,下面可以直接忽略2333

     Analysis in long

    我归纳了一下,要看懂这个问题要理解三个点:

    • 此处的a,b是引用类型

    • 在javascript中字段访问操作符"."的优先级高于赋值操作符"="

    • 出现多个赋值操作符"="时,运算顺序为从右向左

    1. 此处的a,b是引用类型

    引用类型是区别于基本类型的。javasript中的基本类型总共有5种,Undefined、Null、String、Number、Boolean。引用类型有Object,Array,Function,,,blabla~,简单说就是除了5种基本类型,可以说其它都为引用类型。

    案例中的{n: 1}和{n: 2}都为Object类,即为引用类型。在javascript中当复制保存某个对象时,操作的是对象的引用,但在为对象添加属性时,操作的是实际的对象。即在第一行和第二行命令中a,b其实存储的是对象{n: 1}的引用(地址)。

    这有点像C中的指针。如下图,案例第一行命令可以解析为,在堆(heap)中创建了一个对象{n: 1},另外在栈(stack)中创建了变量a,变量a的值为对象{n: 1}的地址,即图中的h[0]。第二行命令意思是再在栈中创建另一个变量b,变量b的值与变量a的值相等,即为对象{n: 1}的地址。

    打个比方,你有一张去餐馆的地图,你把地图复制一份给你的基友,地图是多了一张,但餐馆的实际位置是没有改变的。

    2. 运算顺序问题

    这一节对应的是第二和第三个点。根据javascript中的运算符优先级 Operator precedence,可知:

    • 在javascript中字段访问操作符"."的优先级高于赋值操作符"="
    • 出现多个赋值操作符"="时,运算顺序为从右向左

    因此在运行第三行命令时,分3步执行:

    (1)先执行"a.x",此时a储存的仍然是h[0]地址,即指向对象{n: 1}。"a.x"相当于"h[0].x",即在对象{n: 1}中添加了属性"x",变为{n: 1; x: undefined},但是"x"还没赋值;注意,此时对象{n: 1; x: undefined}中的"x"属性是等待赋值的,操作挂起

     (2)再执行"a = {n: 2}",由于{n: 2}是个新对象,则程序在堆中再创建一个对象{n: 2},并且将变量a指向该对象,如图,此时a储存的即为h[1]的地址

    (3)最后一步"a.x = a",(1)中被挂起的操作继续执行,对象{n: 1; x: undefined}中的"x"指向对象{n: 2}。运算完成。

    3. 结果解释

    在运行完上述命令后,变量a指向了新对象{n : 2};变量b 的地址没有发生改变,因而仍指向修改后的对象{n: 1;x: {n : 2}}。

    var a = {n: 1}; 
    var b = a; 
    a.x = a = {n: 2}; 
    console.log(a.x); //undefined 
    console.log(b.x); //{n: 2} 
  • 相关阅读:
    sqlserver添加表、字段注释
    SQL语句增加字段、修改字段、修改类型、修改默认值
    端口概念
    删除数据库数据
    转移数据库表数据
    优化网站
    提高SQL查询效率
    相关方法扩展
    SQL空和NULL的区别
    C#分布式缓存Couchbase使用
  • 原文地址:https://www.cnblogs.com/Gavin257/p/9562214.html
Copyright © 2011-2022 走看看