函数实参为对象时的陷阱

发布于 2023-05-20 15:22:16 字数 1708 浏览 42 评论 0

上周在实现某个弹层功能的时候,用到了rc-util里的 contains 方法函数, 结果 code-review 的时候同事对该代码提出了疑问:

export default function contains(root, n) {
  let node = n;
  while (node) {
    if (node === root) {
      return true;
    }
    node = node.parentNode;
  }
  return false;
}

上述代码是 antd 内部抽象的一个工具方法,用来判断某个dom是否为另一个dom的祖先节点。

同事疑问的是 let node = n; 这段代码是不是多余的?

首先一开始的理解是 函数参数 n 是一个对象,一个dom节点对象。
如果用 node 保存 n 的值,防止 node = node.parentNode 这段代码执行的时候,会改变传入的实参 n 对应的值。

毕竟以下的代码我们都很熟悉:

function contains(root, n) {
  if(n) {
    n.a = 3
  }
}

const A = {a:1};
const B = {a:2};
contains(A,B)
console.log(B)    // {a:3}

即当实参为对象时,函数内部是可以改变该对象的值从而影响函数之外的实参。

但是测试另外一段代码,发现和理解的不一样:

function contains(root, n) {
  if(n) {
    n = {a:3}
  }
}

const A = {a:1};
const B = {a:2}
contains(A,B)
console.log(B) // {a:2}

n.a = 3n = {a:3} 这两段代码是不一样的。

网上也有相关资料,其实可以简单的理解为: 当函数一开始执行时,n 是指向实参 B 的一个引用。

n.a = 3 是在引用上关联了一个属性,此时和 B 还是同一个引用,因此会改变实参B的值。

n = {a:3} 则使得 n 不再指向实参 B, 而是指向一个新对象{a:3},也就是 nB 彻底断绝了关系,因此不会改变实参 B 的值。

是不是可以给蚂蚁的团队提个issue建议删除该代码,不过有这句代码也不会有什么bug 该行代码可能是为了符合 eslint 规范: 不对函数的参数进行赋值。链接

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

舟遥客

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

金兰素衣

文章 0 评论 0

ゃ人海孤独症

文章 0 评论 0

一枫情书

文章 0 评论 0

清晰传感

文章 0 评论 0

mb_XvqQsWhl

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文