函数实参为对象时的陷阱
1. 正文
上周在实现某个弹层功能的时候,用到了rc-util
里的 contains
方法函数, 结果 code-review
的时候同事对该代码提出了疑问:
上述代码是 antd
内部抽象的一个工具方法,用来判断某个dom是否为另一个dom的祖先节点。
同事疑问的是 let node = n;
这段代码是不是多余的?
首先一开始的理解是 函数参数 n
是一个对象,一个dom
节点对象。
如果用 node
保存 n
的值,防止 node = node.parentNode
这段代码执行的时候,会改变传入的实参 n
对应的值。
毕竟以下的代码我们都很熟悉:
即当实参为对象时,函数内部是可以改变该对象的值从而影响函数之外的实参。
但是测试另外一段代码,发现和理解的不一样:
即 n.a = 3
和 n = {a:3}
这两段代码是不一样的。
网上也有相关资料,其实可以简单的理解为: 当函数一开始执行时,n
是指向实参 B
的一个引用.
n.a = 3
是在引用上再关联了一个属性,此时和 B
还是同一个引用,因此会改变实参B
的值。
而 n = {a:3}
则使得 n
不再指向实参 B
, 而是指向一个新对象{a:3}
,也就是 n
与 B
彻底断绝了关系,因此不会改变实参 B
的值。
是不是可以给蚂蚁的团队提个issue建议删除该代码,不过有这句代码也不会有什么bug 该行代码可能是为了符合 eslint
规范: 不对函数的参数进行赋值. 链接
2. 相关资料
Last updated