推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
evilStart

有人用 JavaScript 的# 来创建私有变量么?

  •  
  •   evilStart · Jul 16, 2020 via Android · 4899 views
    This topic created in 2151 days ago, the information mentioned may be changed or developed.
    #这个语法出来也有一段时间了,但我几乎没有见过有项目里用过?有商业或者大的开源项目用这个方法么?
    32 replies    2020-07-19 20:23:24 +08:00
    jiangzhuo
        1
    jiangzhuo  
       Jul 16, 2020
    这个你大概得往前穿越个十几年大概有人这么用。
    zhuangzhuang1988
        2
    zhuangzhuang1988  
       Jul 16, 2020
    不想私有,有时候实在没办法想 hack 一下 js 库,都是私有 咋玩

    ps: 以前用过 tinymce, 初始化 3 次必死, 每次都死在 extends 函数上面,
    直接用, 幸好这个函数公开出来了, 用 lodash 的 动态替换了下, 就没问题了,
    如果真私有了 只能修改代码了
    lxk11153
        3
    lxk11153  
       Jul 16, 2020
    什么语法?来个教程,感谢姐妹
    ChanKc
        5
    ChanKc  
       Jul 16, 2020
    https://github.com/tc39/proposal-class-fields
    是个好东西,因为没有私有变量就没有真正意义上的封装。过去要有私有变量只能利用闭包。
    不过目前还没正式进入标准,所以没有大项目敢用吧
    ChanKc
        6
    ChanKc  
       Jul 17, 2020
    另一个原因,我说得可能比较得罪人
    就是很多前端工程师根本不懂什么叫封装,不懂什么叫 information hiding
    no1xsyzy
        7
    no1xsyzy  
       Jul 17, 2020
    @ChanKc #5 俺寻思就是没闭包没对象的时候也有真正意义上的封装啊
    @zhuangzhuang1988 #2 跑个题,这个特定情况应该提 bug 给上游吧……
    zhuangzhuang1988
        8
    zhuangzhuang1988  
       Jul 17, 2020
    @no1xsyzy 不知道何年马月
    hronro
        9
    hronro  
       Jul 17, 2020 via iPhone
    @ChanKc stage 3 了,基本上等于进了标准。大项目的话,我知道 deno 在用。
    mxT52CRuqR6o5
        10
    mxT52CRuqR6o5  
       Jul 17, 2020 via Android
    deno 里有用到
    而且这个 feature 有些见仁见智的问题(可以上知乎上查查)
    seki
        11
    seki  
       Jul 17, 2020 via iPhone
    可以问一下自己是不是真的有私有变量的需求,为什么会想要设置私有变量,用了之后会不会有哪些不便之处

    这些都思考了之后还是觉得有必要的话那就用吧
    seki
        12
    seki  
       Jul 17, 2020 via iPhone   ❤️ 2
    个人的看法,给没有静态类型检查的语言引入私有变量,就是给运行时埋雷,以前要好多行代码埋的雷,现在只需一个 #
    ChanKc
        13
    ChanKc  
       Jul 17, 2020 via Android
    @no1xsyzy 还真有人出来挑战
    来说说什么是封装
    love
        14
    love  
       Jul 17, 2020
    @seki 什么叫是不是真的有私有变量的需求,难道你写的类全是公开成员? 总是要区别一下私有变量的,以前用下划线,现在换成#不是一样?还自动多了强制不可外部访问功能不好吗。 另外这个和静态类型检查有冲突吗?
    no1xsyzy
        15
    no1xsyzy  
       Jul 17, 2020   ❤️ 1
    @ChanKc #13 将加工完成的半导体元件加上导线及外壳以利使用及保护
    或者整个分子被包裹进另一个更大的分子
    引申到软件工程是指使得一段代码仅仅暴露少量接口,以减少耦合性;或者说用某种方式把代码的边界给隔离开来。
    所以所有程序内存隔离,仅以 stdin stdout stderr 进行交互是一种封装。
    ChanKc
        16
    ChanKc  
       Jul 17, 2020
    @no1xsyzy 有趣的解释
    阅读 https://github.com/tc39/proposal-class-fields/blob/master/PRIVATE_SYNTAX_FAQ.md#why-is-encapsulation-a-goal-of-this-proposal
    “While it's already possible to model true encapsulation using either per-instance closures or WeakMaps”
    这里的 true encapsulation 是指什么?
    seki
        17
    seki  
       Jul 17, 2020
    @love
    如果用下划线这种,那是开发者之间的约定,用 # 就是强制性的。包括 typescript 的 private 也是用于检查,不是 # 这样的强制

    如果你在代码里面引用了其它对象的私有变量,静态类型检查可以提醒你不要这么做。但是没有这种检查的话,那就直接等运行时爆炸了

    真的有不少语言没有私有变量的需求,基本依靠开发者的自觉,比如 ruby 和 python
    no1xsyzy
        18
    no1xsyzy  
       Jul 17, 2020
    @ChanKc #16 我也不知道指的什么,information hiding 又不是 encapsulation 的目标,而是手段。
    强行说 true 不 true 有点 cult 意思在。
    ChanKc
        19
    ChanKc  
       Jul 17, 2020 via Android
    @seki 我想写的时候你就知道哪些是私有的啊,不是都有#开头?不去拿#开头的变量不就没问题了?
    Austaras
        20
    Austaras  
       Jul 17, 2020   ❤️ 1
    我直说吧,要 hard private 都是弱智,你像隔壁 python 一样搞搞 name convention 差不多了
    rioshikelong121
        21
    rioshikelong121  
       Jul 17, 2020
    没有 直接 ts private 。
    gaoryrt
        22
    gaoryrt  
       Jul 17, 2020
    根本不懂什么叫封装也可以写好前端。
    浏览器环境的话,可以,但没有必要。
    libook
        23
    libook  
       Jul 17, 2020
    我们在用,不过确实用得不多,主要是因为将成员私有化这个需求本身就比较少出现,而且利用局部变量往往也可以达到私有化的效果(比如闭包)。

    这个就是个特性而已,没有需求就不用,有需求能想起来用就行。
    optional
        24
    optional  
       Jul 17, 2020
    @ChanKc 封装这大概率是 oo 的说法,js 根本不是纯粹的 oo 语言。 作为一门业务型语音,比较认同上面 Austaras 说的,hard private 是个弱智,依赖这玩意的说明你根本不相信你的队友。
    yaphets666
        25
    yaphets666  
       Jul 17, 2020
    js 现在需要的是语法糖 不需要任何新的概念性的东西了
    MrTreasure
        26
    MrTreasure  
       Jul 17, 2020
    没有使用的场景。

    前端无非就是 Vue React NG,NG 就不说了,没有几个人用 NG 不用 TS 吧。用 Vue 和 React 的大概率也用不到封装。

    那么用到的封装的,大部分是需要写库,写 SDK 的。这些场景大概率会选择 TS 。
    ChanKc
        27
    ChanKc  
       Jul 17, 2020
    @optional 不是不相信我的队友,就如#26 所说,一般都是写库和写 SDK 的需要。还有一种情况可能是跨团队。
    封装就是暴露接口,隐藏实现。暴露和隐藏都是关键。暴露的接口可以认为是有保证的,一定会出现预期的(和文档描述一致的)结果。在这个基础上,所有隐藏的部分,无论是方法还是域都可以随便改随便重构。
    hard private 的好处是可以保证你的 API 的使用者的程序一定不会因为你的重构,升级和优化等等而受到破坏。当然如果所有 API 的使用者都遵循 naming convention,这些 API 的使用者也可以受到封装带来的好处。
    封装的主要受益人是 API 使用者,但是却是 API 的开发者来写的。如果库,SDK 的开发者根本不在乎他的用户的长期的使用体验,可以不用封装。
    #22 说的情况是,过去很长时间里,前端的库不多,在浏览器运行的代码也不多,很多时候用户都是自己调自己的方法,这时候可能就是“跑起来就行”
    还有一种情况是,很多程序在开始建项目的时候确定了一个版本,后来就没再升级过,这个时候就可以像#2 那样随便 hack
    wobuhuicode
        28
    wobuhuicode  
       Jul 17, 2020
    约定命名作为私有也就够了。比如说下划线命名的就是私有之类的。
    放在其它语言你搞个 SDK 出来,人家照样能在 runtime 读取你的私有变量。不也是一个打破约定的事情嘛。
    所以私有公有无非就是大家都要去遵守的约定才有效。
    Yuiham
        29
    Yuiham  
       Jul 17, 2020
    这个 proposal 一堆问题,最好不要进入 ES 标准了。大部分时候 Symbol 足够用了。
    optional
        30
    optional  
       Jul 17, 2020
    @ChanKc 这一套道理谁都明白。,但是业务型语言就是业务型语言,你看新出的语言,限制都在弱化,或者说都在践行『约定大于配置』,用大小写控制可见性,ducktype 替代 interface 。
    hard private 真的是你需要的吗?
    ChanKc
        31
    ChanKc  
       Jul 17, 2020
    @optional 我需不需要看场景啊,我觉得会有场景需要
    chnwillliu
        32
    chnwillliu  
       Jul 19, 2020 via Android
    搭配 ES6 的 Proxy 一起食用那叫一个酸爽,保准泪流满面哭着喊苍天啊这都什么鬼 feature 啊 https://github.com/tc39/proposal-class-fields/issues/106 有兴趣可以看看这个 issue
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2874 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 202ms · UTC 06:05 · PVG 14:05 · LAX 23:05 · JFK 02:05
    ♥ Do have faith in what you're doing.