我查到的原因就两:一个是性能问题,另一个是严格模式报错。
但并不能解释我心中的疑问,要是不让用,造出来干嘛?而且简化代码不挺好的吗
1
netabare 2023-01-10 05:38:35 +08:00 1
因为 JavaScript 一开始就不是一个正经的语言。传说中的 10 天造出来的语言,能期待有多好的设计。
关于性能问题,我的猜测是,因为 JavaScript 是没有类型的,基于原型链的语言,这就意味着属性访问的实现方法和静态强类型 OOP 语言里面的 devirtualization 有很大的差别了。OOP 语言可以通过各种编译期的优化来消除 devirtualization 里面的性能开销,但是 JavaScript 的语言基准太灵活了,所以无法优化。(只是个人不负责任的猜想) 另外一个问题是`with`本身把变量直接引入到上下文里,也就是说,不需要写变量名就可以直接把关联在这个变量上的无论什么垃圾都调用出来。 Kotlin 里面的`with`并不会把变量关联的属性都暴露在上下文里,因为看函数签名就可以知道了: ```kotlin inline fun <T, R> with(receiver: T, block: T.() -> R): R ``` receiver 是被捕获的变量,类型为 T ,block 是一个 receiver 函数,在这个函数里面,`this`的类型是 T ,也就是说必须显式指明`this`再访问这个变量所有可能的方法和属性。这种 aliasing 的写法,显然比把不管什么垃圾都倒进作用域安全多了。 话说过来在有 extension 的语言里,本身 scope 函数就可以自己随手造出来,当然了,scope 函数本身也涉及到了虚函数 devirtualization 的问题,如果语言运行时没有专门优化的话,是会造成性能问题的。 所以,并不是说「简化代码」就很好了。 至于「造出来的原因」,大概就跟语言设计历史上的各种其他的离谱的设计一样吧,因为当时的人们还没意识到哪些设计是好的,哪些是坏的。现在回过头看,也只是在马后炮了。 |
2
Mutoo 2023-01-10 05:58:30 +08:00
js 的 this 关键词已经够复杂了,with 可以把这个复杂性更进一层楼。猜一下输出:
```js a = {this: 'this', that: 'that'}; with(a) { console.log(this, that); } ``` |
4
musi 2023-01-10 08:38:52 +08:00
首先你能查到的都是不推荐用,js 里面的糟粕又不止这一个,为啥非要揪着糟粕点
|
5
1t1y1ILnW0x5nt47 2023-01-10 08:53:17 +08:00
一不小心还容易污染全局
|
6
visper 2023-01-10 09:02:32 +08:00
vue 不是有用 with 吗?
|
7
TWorldIsNButThis 2023-01-10 09:04:13 +08:00 via iPhone
kotlin 的 with 只会拿到 public 的属性
js 呢? |
8
MEIerer 2023-01-10 09:30:30 +08:00
设计简陋,导致不好用,所以 over
|
9
ToyotaLee 2023-01-10 09:36:06 +08:00
现在微前端框架不是用的很火,看使用场景
|
10
makelove 2023-01-10 09:43:03 +08:00
这个不推荐没有任何意义,正常人不会随便用 with ,毕竟没人会为了少打几个字而极大伤害可读性(毕竟看到每一个变量都得想具体会落到哪个对象上)。
要用到的地方不用都不行。 |
11
PTLin 2023-01-10 09:44:22 +08:00
我感觉 with 就是个顺势搞出来的东西。
本身 js 的作用域链进入一个新的作用域就推进去一个新的变量对象,那我估计设计 with 的是不是人是不是一拍脑子,想反正模型都是这样了,那直接出一个让用户把自己的对象推进作用域链头的东西不就好了。 |
12
NerbraskaGuy 2023-01-10 10:12:32 +08:00
JS 搞出来的操作符但是又不推荐用的多了去了,常见的比如 delete 的性能极差
|
13
cyrbuzz 2023-01-10 10:13:45 +08:00
只要可以了解副作用和承担副作用所带来的风险就可以用。
不推荐就是打了个标记,告诉开发者,你可以不用了解这个语法有啥卵用,我也不推荐让其他开发者学习这个语法,但你可以学习了解,并且在你觉得你完全了解它了,需要用它的时候用它。 比如 Vue 里有用`with`去实现模板的编译,`v-if="xxx === 2"`编译为`with(this) { if (xxx === 2) {...} }`,https://github.com/vuejs/petite-vue/blob/main/src/eval.ts#L20 petite-vue 里关于`with`的应用,这行代码很易读也并不会造成混乱(了解并承担了 with 会带来混乱作用域的副作用),实现了一个原本不用 with 会很复杂的功能。 |
14
cweijan 2023-01-10 10:31:25 +08:00
@NerbraskaGuy 这是取决于 V8 的实现吧, 而且前端也不缺这一点性能
|
15
thinkershare 2023-01-10 10:38:00 +08:00
|
16
SoloCompany 2023-01-10 13:30:02 +08:00 via iPhone
因为用了就只能依赖解释执行,无法 hotspot 优化
|
17
sundev 2023-01-10 13:57:28 +08:00 via iPhone
超级不喜欢 with 语法,看起来太费劲了
|