在外部获取闭包内 key 变量的值。(不用考虑所有浏览器,Chrome 支持就可以)
1
suzic 2018-11-19 15:14:29 +08:00 via Android
不会。但感觉用 eval 能解
|
2
jowan 2018-11-19 16:52:41 +08:00
```
recursion = () => { var key = apiX(100) return k = key <= 1 ? key : recursion() } try { recursion() } catch (e) { console.log(k) } |
3
hsfzxjy 2018-11-19 16:53:07 +08:00 3
```
function d () { try { return d() } catch (e) { return apiX() } } console.log(d()); ``` 用爆栈引发异常 |
4
jerrry 2018-11-19 17:07:12 +08:00 1
这是什么字体?怎么感觉比 FiraCode 还顺眼。
|
5
vicvinc 2018-11-19 17:26:45 +08:00
为啥 throw 一个 error 不会触发
|
6
zbinlin 2018-11-19 17:32:51 +08:00
function x(fn) {
const ret = fn(fn); if (ret === fn) { try { return x(fn); } catch (err) { return ret(); } } else { return ret; } } console.log(x(apiX)); |
7
zbinlin 2018-11-19 17:38:56 +08:00 1
精简下:
function x(fn) { try { return x(fn(fn)); } catch (err) { return fn(); } } console.log(x(apiX)); |
8
morethansean 2018-11-19 17:40:00 +08:00
@jerrry #4
祖传 Monaco |
11
seki 2018-11-19 17:49:02 +08:00 1
Math.random = () => 1
|
13
linxiaoziruo 2018-11-19 18:21:14 +08:00
@hsfzxjy 验证了下代码,执行正确。但是我有个不明白的地方,爆栈应该只会出现在 d()这个函数的递归调用上,到了执行 apiX()的时候,栈应该重新记数了,应该不会触发 apix 的 catch。求解!
|
14
FakeLeung 2018-11-19 20:23:59 +08:00 via Android
Emmmmm 作为一个前端,看不懂,跑了。
|
15
Sevenskey 2018-11-19 20:33:01 +08:00
@linxiaoziruo 排队求解。顺便一说我发现只要 catch 中执行的函数的函数体内部有 try catch 且 try 中含有函数调用,就会在函数调用处抛爆栈的错;但如果这个函数体内部存在函数调用却没有 try catch,那么就不会抛错。。猜测也许是引擎的某些策略?
|
16
autoxbc 2018-11-19 23:15:11 +08:00
@linxiaoziruo #13
@Sevenskey #15 猜测是不是这样 执行代码 function bomb() { try { return bomb() } catch(err) { return apiX() } } console.log( bomb() ) 爆栈阶段调用过程 bomb_2 (){ try { bomb_1 (){ try { return bomb_0() ... } catch(err) { return apiX_0() ... } } } catch(err) { apiX_1 (){ try { return internal() ... } catch(err) { return key } } } } 实际流程 => bomb_0(申请资源出错) => apiX_0(申请资源出错) => bomb_1(抛出错误) => apiX_1(正常执行) => internal(申请不到资源) => return key 本题可解的关键是 return key 分支比 return internal() 少一级函数调用,如果两者调用长度相等,那么就失败了 简单添加一句代码给 return key 分支加长调用链,令 apiX 为 apiX = function(x) { try { return internal(x) } catch(err) { (function(){})() // 此句新加 return key } } 此时用上面方法爆栈是无法获取 key 的 |
17
Sparetire 2018-11-20 01:17:11 +08:00 via Android
楼上正解,这里的关键就在于让调用 internal(x)的时候爆栈就行,只要调用栈足够深就爆栈,递归只是达成这一目的的方式
|
19
mytry OP 公布答案~
|
20
linxiaoziruo 2018-11-20 11:16:33 +08:00
@mytry 老哥多来点这种趣味性的东西!
|
21
razor1895 2018-11-20 11:28:09 +08:00
apiX(new Error());
|