V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
xieqiqiang00
V2EX  ›  JavaScript

JS,在脚本的开头将 fetch 之类的引用给 delete,后面还有办法能获取到吗?

  •  
  •   xieqiqiang00 · 2021-06-05 17:52:24 +08:00 · 2584 次点击
    这是一个创建于 1258 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如
    delete globalThis.fetch
    ....

    还有可能再次获取到 fetch 吗?


    或者
    delete ArrayBuffer
    ...

    还有可能再创建 ArrayBuffer(new ArrayBuffer(8))吗?
    22 条回复    2021-06-07 22:14:34 +08:00
    WizardMeow
        1
    WizardMeow  
       2021-06-05 18:09:49 +08:00 via Android
    iframe
    xieqiqiang00
        2
    xieqiqiang00  
    OP
       2021-06-05 18:11:05 +08:00
    @WizardMeow 的确有可能,那就加个限定吧,nodejs 环境下
    love
        3
    love  
       2021-06-05 20:04:55 +08:00
    我觉得 ArrayBuffer 这类内置对象有可能可以从别的库引用中得到,比如某个 api 返回一个 ArrayBuffer 对象,那就可以通过 .constructor 得到 ArrayBuffer 引用了
    hxsf
        4
    hxsf  
       2021-06-05 22:13:54 +08:00
    node 内置的 vm 模块不够用?
    Rocketer
        5
    Rocketer  
       2021-06-06 00:38:21 +08:00 via iPhone
    真能删除吗? JS 里可是一切皆对象,你以为它是某个类下面的函数,其实函数本身是独立对象,那个类只是引用了一下。

    所以你删掉的也只是一个引用,只有所有引用全部没了,这个对象才可能被回收。
    oott123
        6
    oott123  
       2021-06-06 09:32:44 +08:00
    简单试了试,似乎不太容易
    不过你问有没有可能我觉得还是有可能的……
    xieqiqiang00
        7
    xieqiqiang00  
    OP
       2021-06-07 00:25:41 +08:00
    @hxsf vm 限制不了内存,退一步,nodojs 也根本没法限制 Buffer 之类的内存,分配多少拦不住
    xieqiqiang00
        8
    xieqiqiang00  
    OP
       2021-06-07 00:26:10 +08:00
    @love 的确,那要达到目的还得把相关的功能也删了
    hxsf
        9
    hxsf  
       2021-06-07 08:47:06 +08:00
    @xieqiqiang00 #7 你不说原始需求,大家也没法一次性帮你解决你没说的问题啊?
    vm 完美解决你正文提到的上下文控制的问题。内存问题你正文也没说啊?
    《提问的智慧》了解下?
    xieqiqiang00
        10
    xieqiqiang00  
    OP
       2021-06-07 09:02:53 +08:00 via Android
    @hxsf 我现在用的 vm2,vm2 也没法限制这些内置接口吧,原始问题就是内存限制问题,但我确认 nodejs 是不可能能限制内存的,只能把这些耗内存较大的东西在代码开头移除
    hxsf
        11
    hxsf  
       2021-06-07 10:08:56 +08:00
    @xieqiqiang00 #10 开子进程啊,然后外部控制内存占用,使用 v8-options 或者 cgroups
    xingguang
        12
    xingguang  
       2021-06-07 10:11:15 +08:00
    不行,我记得内置的模块都是不可操作的
    xieqiqiang00
        13
    xieqiqiang00  
    OP
       2021-06-07 11:05:51 +08:00
    @hxsf 不可以的,我现在就是开的子进程,不能限制 buffer 一类的内存,这种内存不属于 V8 的管理部分。
    cgroups 不考虑,我想在 Windows 上也能运行
    xieqiqiang00
        14
    xieqiqiang00  
    OP
       2021-06-07 11:06:21 +08:00
    @xingguang 如果能把所有的引用都干掉的话,就能达到“删掉”的效果了
    xieqiqiang00
        15
    xieqiqiang00  
    OP
       2021-06-07 11:09:29 +08:00
    @hxsf 而且 VM 也没法删除这些内置对象
    muzuiget
        16
    muzuiget  
       2021-06-07 17:19:16 +08:00
    有些是只读属性删除或者修改不了的。
    muzuiget
        17
    muzuiget  
       2021-06-07 17:21:14 +08:00
    感觉就是 X/Y 问题,我猜楼主其实需要一个 JS 的沙盒环境。
    xieqiqiang00
        18
    xieqiqiang00  
    OP
       2021-06-07 17:37:30 +08:00
    @muzuiget 原始的确是 JS 沙箱,常见的几个都试了,现在这个是最终妥协出来的方案,用 vm2+禁止 buffer 类的功能
    kfll
        19
    kfll  
       2021-06-07 19:39:10 +08:00
    xieqiqiang00
        20
    xieqiqiang00  
    OP
       2021-06-07 20:55:20 +08:00
    @kfll 这个我之前试过了太麻烦了,不考虑这个,啥都不支持,fetch 都要自己去通信
    xieqiqiang00
        21
    xieqiqiang00  
    OP
       2021-06-07 22:05:44 +08:00
    @love 我尝试了一下,delete 之后即使是 XHR 返回的 arraybuffer 也是指向的全局里的 arraybuffer,如果我删了全局的 arraybuffer,虽然 XHR 可以返回 arraybuffer 对象但没法再构造新的 arraybuffer 了

    代码如下
    {
    delete ArrayBuffer//不 delete 这个,后面的 new arraybuffer(8)是可以执行成功的
    //ArrayBuffer 的引用已被清除
    const xhr = new XMLHttpRequest();
    xhr.open("GET", "https://cdn.jsdelivr.net/gh/WildXBird/r6sground.cn/cache.txt", true)
    xhr.responseType = "arraybuffer"
    xhr.send()
    xhr.onreadystatechange = () => {
    if (xhr.readyState == XMLHttpRequest.DONE) {
    if (xhr.status >= 200 && xhr.status <= 300) {
    let res = xhr.response
    console.log(typeof (res))
    console.log(res)
    let arraybuffer = res["__proto__"].constructor
    const buffer = new arraybuffer(8);
    console.log(buffer.byteLength);
    }
    }
    }
    }
    xieqiqiang00
        22
    xieqiqiang00  
    OP
       2021-06-07 22:14:34 +08:00
    @love 上面的代码有问题,这个才对
    {
    let tab = new ArrayBuffer(8)
    tab["__proto__"].constructor = {}//不重写这个,后面的 new arraybuffer(8)是可以执行成功的
    delete tab
    //ArrayBuffer 的引用已被清除
    const xhr = new XMLHttpRequest();
    xhr.open("GET", "https://cdn 点 jsdelivr 点 net/gh/WildXBird/r6sground.cn/cache.txt", true)
    xhr.responseType = "arraybuffer"
    xhr.send()
    xhr.onreadystatechange = () => {
    if (xhr.readyState == XMLHttpRequest.DONE) {
    if (xhr.status >= 200 && xhr.status <= 300) {
    let res = xhr.response
    console.log(typeof (res))
    console.log(res)
    let arraybuffer = res["__proto__"].constructor
    const buffer = new arraybuffer(8);
    console.log(buffer.byteLength);
    }
    }
    }
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5307 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 07:51 · PVG 15:51 · LAX 23:51 · JFK 02:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.