RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1421282
Accepted
EzioMercer
EzioMercer
Asked:2022-08-17 22:41:26 +0000 UTC2022-08-17 22:41:26 +0000 UTC 2022-08-17 22:41:26 +0000 UTC

为什么 JS 类不使用 private 关键字

  • 772

我一直在想:为什么private在 JS 类中,他们决定使用符号而不是通常的关键字#?

到目前为止我还没有真正寻找它,但是通过简单的搜索,他们基本上说它在 JS 中被使用,以及如何使用它的#更多private示例,但他们没有回答为什么?

今天我决定还是要找到答案,因为。我敢肯定我不是唯一一个问这个问题的人。好吧,在搜索中,我遇到了专门针对该主题的完整常见问题解答(英文)

javascript классы
  • 1 1 个回答
  • 84 Views

1 个回答

  • Voted
  1. Best Answer
    EzioMercer
    2022-08-17T22:41:26Z2022-08-17T22:41:26Z

    问题为什么要标志#?给出以下答案:

    没有人来说,#这是最美丽、最直观的指定私人状态的东西。相反,它更像是一个消除过程:

    • @最初是最喜欢的,但被装饰者拿走了。TC39 考虑替换装饰器和私有状态符号,但委员会决定推迟用户对转译器的现有使用。

    • _会导致与现有 JavaScript 代码的兼容性问题,该代码长期以来一直允许_在开头使用标识符或(公共)属性名称。

    • 其他可以用作中缀运算符但不能用作前缀运算符的字符假设是可能的,例如%, ^, &, ?,因为我们的语法有点独特 - х.%у,当前无效,因此不会有歧义。但是,减少可能会导致ASI出现问题,例如以下看起来像使用中缀运算符:

      class Foo {
        %x;
        method() {
          calculate().my().value()
          %x.print()
        }
      }
      

      在这里,用户可能打算为 调用 print 方法this.%x,但将使用模运算符!

    • 您可以使用 ASCII 或 IDStart 中不可用的其他Unicode代码点,但许多用户可能会发现很难输入它们,因为 它们在传统键盘上找不到。

    最后,唯一的其他选择是更长的标点符号序列,与单个字符相比,这似乎不是最佳选择。

    对问题为什么不使用关键字private?给出以下答案:

    这样的声明在其他语言(尤其是Java)中使用,并暗示访问将是 via this.x。假设不是这种情况(见上文),在 JavaScript 中,这将自动创建或访问公共字段,而不是引发错误。这是 bug 的主要潜在来源,或者应该是私有的公共字段的不可见创建。

    它还允许声明和访问之间的对称性,就像公共字段一样:

    class A {
     pub = 0;
     #priv = 1;
     m() {
       return this.pub + this.#priv;
     }
    }
    

    因此,如果第一个问题一切都清楚,那么对于第二个问题,我有一堆问题。参考(见上文),如果我理解正确,指的是这两个(嗯,或两者)点之一。首先,我将给出他们的翻译:

    1. 为什么没有访问权限this.x?(原创)

    拥有私有命名字段x不应该阻止存在公共命名字段x,因此访问私有字段不能是简单的查找。

    由于缺少静态类型,这只是 JavaScript 中的一个问题。静态类型语言使用类型声明来区分外部公共/内部私有情况,而不需要符号。但是动态类型语言没有足够的静态信息来区分这些情况。

    1. 为什么不对接收器进行运行时类型检查以确定是否应该访问名为的私有或公共字段x?(原创)

    属性访问语义已经很复杂,我们不想仅仅为了添加这个特性而减慢每个属性访问。

    它还允许类方法被欺骗来处理非实例公共字段,就好像它们是私有实例字段一样。例如,请参阅此评论

    仔细研究了指定的注释,我终于明白为什么他们没有private按照其他语言的习惯输入它。以下是评论的第一部分:

    考虑这种情况:

    class X {
        private a;
    
        constructor(a) { this.a = a }
    
        swap(otherX) {
            let otherA = otherX.a;
    
            otherX.a = this.a;
            this.a = otherA;
    
            return otherA;
        }
    }
    

    让我们swap用一个实例X作为参数调用:

    let x1 = new X(1);
    let x2 = new X(2);
    x1.swap(x2); // --> 2
    

    在这种情况下,对的引用otherX.a应该引用名为的私有字段a,对吗?

    如果我们调用swap的对象不是 的实例X怎么办?

    let x1 = new X(1);
    let x2 = {a: 3};
    x1.swap(x2); // --> TypeError или 3?
    

    如果不为参数指定类型otherX,我们就无法告诉编译器是否otherX.a:

    • 查找名为ay的字段otherX或
    • 查找名称为ay的私有字段otherX

    如果你想问为什么不只是 obj.x 总是引用声明私有字段 x 的类中的私有字段?,则给出以下答案:

    类方法经常操作不是类实例的对象。如果代码obj.x突然停止引用不应该是类的实例的x对象obj的公共字段,那将是令人惊讶的,仅仅是因为该代码意外出现在声明名为私有字段的类中的某个地方,也许内心深处说班级。objx

    如果您有时间和愿望,可以阅读有关此问题的整个讨论。

    简而言之,人们对这个决定非常不满,并提供了多种方式和方法来按照通常的方式来做。从我对几乎所有评论的快速浏览中,我可以区分出 3 种类型的句子:

    1. @改为使用#
    2. 使用不同的语法,但带有#或全新的东西。例如像this#x(没有点)。或this->x。或者,例如,声明 c using private,但通过访问this.#x
    3. 在运行时进行任何检查,以便您准确确定此私有或公共字段

    这些建议的几乎所有答案都是:

    1. 装饰者使用此标志
    2. 当建议的语法中断或导致对程序员在一种情况下使用这种语法的原因产生误解时,给出了示例,而在这种情况下使用另一种语法。
    3. 访问字段的算法目前已经得到很好的优化,没有人会在每次访问类字段时插入任何条件检查

    我以及许多其他评论员唯一不清楚的是,将为什么protected或其他关键字发明什么?我们每次都必须在名字前写一堆字符吗?

    就个人而言,这一切让我对作者的立场和选择有了清晰的认识,希望对提出这个问题的人也有帮助:)

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5