V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mytry
V2EX  ›  程序员

一个 JavaScript 挑战题,检测隐形人是否存在~

  •  
  •   mytry · 2018-11-20 15:01:18 +08:00 · 3657 次点击
    这是一个创建于 2194 天前的主题,其中的信息可能已经有所发展或是发生改变。

    检测 Math 对象是否被 Proxy 拦截。(如果有打印 hooked,期望得到 true ;没有则 false )

    在线代码: https://jsfiddle.net/8sdugz9r/

    答案有多个,当然越简单越好~

    15 条回复    2018-11-21 17:02:36 +08:00
    meepo3927
        1
    meepo3927  
       2018-11-20 16:09:32 +08:00
    if (Math.random() < 0.5)

    是何作用 ?
    mytry
        2
    mytry  
    OP
       2018-11-20 16:25:03 +08:00
    @meepo3927 可以在有没有 Proxy 之间做一个对比
    ljbha007
        3
    ljbha007  
       2018-11-20 16:29:57 +08:00
    试了很多办法 都不行
    gen900
        4
    gen900  
       2018-11-20 16:35:19 +08:00
    @meepo3927 随机替换 Math。
    murmur
        5
    murmur  
       2018-11-20 16:39:06 +08:00
    @meepo3927 以前有在线编程题因为测试用例是给定的被摸出规律 然后返回值 return true 或者 return false 都能过很多例子
    chairuosen
        6
    chairuosen  
       2018-11-20 16:47:43 +08:00
    抖个机灵:
    ```
    else{
    return false
    }
    return true
    ```
    page470075640
        7
    page470075640  
       2018-11-20 17:35:09 +08:00
    ```
    if (Math.random() < 0.5) {
    console.log('hooked')

    self.Math = new Proxy(Math, {
    get(obj, prop) {
    return obj[prop]
    }
    })
    } else {
    return false
    }

    return true


    function self() {}
    ```
    themostlazyman
        8
    themostlazyman  
       2018-11-20 17:52:47 +08:00
    self.Math.random = () => {
    return 1;
    }
    autoxbc
        9
    autoxbc  
       2018-11-20 18:48:53 +08:00   ❤️ 2
    function bomb()
    {
    try {
    return bomb()
    } catch(err) {
    try {
    Math.PI
    return false
    } catch(err) {
    return true
    }
    }
    }

    console.log( bomb() )
    TomatoYuyuko
        10
    TomatoYuyuko  
       2018-11-20 19:03:00 +08:00
    @autoxbc #9 666 这是什么蛇皮操作?为啥爆栈之后 err 打印不出来了,而且为啥有代理π会报错,看不懂 QAQ
    autoxbc
        11
    autoxbc  
       2018-11-20 19:13:27 +08:00   ❤️ 2
    @TomatoYuyuko #10
    Math 真身和代理的区别是代理多一次 getter 函数调用

    所以先填满栈,再去访问 Math.PI ,失败说明被代理,成功说明是静态对象

    思路来自楼主的上一贴
    https://www.v2ex.com/t/509253
    mytry
        12
    mytry  
    OP
       2018-11-20 19:42:37 +08:00
    @autoxbc 回答正确~ 其实最先是在研究这个问题,然后才虚构了上一贴的问题😄 不过这个问题还有更简单更高效更通用的答案。
    eggggger
        13
    eggggger  
       2018-11-20 20:23:49 +08:00   ❤️ 1
    function hasProxy(obj) {
    Object.defineProperty(obj, 'self', {
    get: function() { return this }
    })
    return obj.self !== obj
    }
    mytry
        14
    mytry  
    OP
       2018-11-20 21:02:17 +08:00
    @eggggger 💯
    yuutan
        15
    yuutan  
       2018-11-21 17:02:36 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2274 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:07 · PVG 00:07 · LAX 08:07 · JFK 11:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.