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

求教一个 js 的问题,入门菜鸡

  •  
  •   zmz980126 · 45 天前 · 2415 次点击
    这是一个创建于 45 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概场景就是有一段源代码,不修改它

    //源代码
    ...
    function a(){
    console.log("111");
    }
    ...
    a();
    console.log("333");
    ...
    //新代码
    function b(){
     console.log("222");
    }
    

    大概就是想在 a 调用完立刻调用 b 输出结果顺序为 111 222 333

    扩展一步,如果是调用前能办到吗,即在执行 a 前先把 b 执行

    (不知道 a 被调用了几次,但想把 b 绑定在 a 上)

    可以在 b 中直接修改 a 的运行时代码吗?

    感谢~

    27 条回复    2021-04-29 16:20:08 +08:00
    yunyuyuan
        1
    yunyuyuan   45 天前
    有点不知所云
    xiaoxinshiwo
        2
    xiaoxinshiwo   45 天前
    回调函数
    kop1989
        3
    kop1989   45 天前
    我揣测一下,看到 lz 说先执行 b,lz 是不是想讨论 b 是异步的问题。

    假设 a 、b 都是同步(同线程)的情况下:
    a();b();输出 333 。

    假设 a 、b 是异步的情况下:
    用 promise 或者 async 、await 语法糖。
    joesonw
        4
    joesonw   45 天前
    var _a = a; a = function() { _a(); b(); }
    kop1989
        5
    kop1989   45 天前
    如果不太懂 promise 或者 async 、await,也可以按照#2 说的,b 的传入参数里加入 callback 函数。
    既把执行完 b 需要做的代码直接当作参数传入 b 。b 最后执行。
    Kasumi20
        6
    Kasumi20   45 天前
    你要是能把 a()改成下面这样的话,我还有点办法
    window.a = function (){
    console.log("111");
    }
    shakukansp
        7
    shakukansp   45 天前
    第一种情况先执行 A 再执行 B 只要改成 promise 或者 async await 就行了
    第二种情况可以用修饰器
    @b
    function a() {}
    让 b 在 a 之前执行
    touchwithe
        8
    touchwithe   45 天前 via iPhone
    这不就是 py 中的装饰器么?参考四楼,把 a 覆盖就行了
    Biwood
        9
    Biwood   45 天前 via iPhone
    函数劫持,见 4 楼
    AsisA
        10
    AsisA   45 天前
    1. 控制执行顺序的话,如果是同步代码,那么直接按照执行顺序排列函数调用顺序就行
    2. 如果是异步代码,可以用 Promise,Async/Await,Rxjs 等方案
    3. 第三个问题用装饰器即可
    yamedie
        11
    yamedie   45 天前
    面向切面编程
    yaphets666
        12
    yaphets666   45 天前
    js 考察代码执行顺序的都是在考察微任务宏任务 event loop 不是用 settimeout 就是用 promise 解决
    DrakeXiang
        13
    DrakeXiang   45 天前
    楼主说的是有一段源代码不能修改,然后加新代码在源代码顺序执行的过程中插入执行,这是不可能的
    ciaoly
        14
    ciaoly   45 天前 via Android
    或许可以通过 window 的某些事件实现吧。。。
    Augi
        15
    Augi   45 天前 via iPhone
    无论怎么样,必须在源代码上做修改。
    hronro
        16
    hronro   45 天前
    想在运行时修改原函数内的代码,这是不可能的。
    如果真的可以做到,那所有的广告 JS SDK 都可以去修改网站本身的函数,给里面注入各种后门,那得多可怕。
    unco020511
        17
    unco020511   45 天前
    如果是 java,可以用切面或者热修复之类的,但是 js,我就不知道有没有这中操作了
    nekochyan
        18
    nekochyan   45 天前
    如果你能在 b 中拿到 a 这个对象 这就好办,就像四楼一样,拿不到那就没办法
    lllllliu
        19
    lllllliu   45 天前
    责任链包装一哈。一路 next,
    使用或者不是使用箭头函数改变上下文。
    gesse
        20
    gesse   45 天前
    @kop1989
    你太高看楼主了。
    zmz980126
        21
    zmz980126   44 天前
    @joesonw 这么写,我有一个问题
    如果 a 的调用在这段代码之前执行,这个覆盖不就执行不到吗
    zmz980126
        22
    zmz980126   44 天前
    @gesse 是的,太高看我了,刚开始学 js
    zmz980126
        23
    zmz980126   44 天前
    @Kasumi20 如果是是 window.a 的话,怎么做呢,拜谢~
    zmz980126
        24
    zmz980126   44 天前
    其实最初的场景是一个课程学习网站,每过一段时间会出现一个确认框确认你是否真的在看,挺烦人,所以我就写了个油猴脚本(因为刚开始学 js 想试试),就遇到了这个问题想在它每次执行 showwarn()后执行一个 onclick 的 unshow() (当然,原来的函数名肯定不叫这个) ,最后没解决,就每隔一段时间 t 检测一下,那个改变的 html 元素,然后改变就 unshow,感觉写的很蠢
    如果 t 太长,那如果出现确认框说不定也要等很长时间,如果 t 太短那就会一直执行这个检测,感觉很影响效率(且蠢)
    然后就有了这个问题
    xingheng
        25
    xingheng   44 天前
    function decorator
    oldshensheep
        26
    oldshensheep   44 天前
    MutationObserver 可以监听 dom 的变化,然后调用你的 unshow()函数就行了
    https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver/MutationObserver
    如果你一开始把你要干什么说出来大家就明白了。

    如果不修改 a 的话应该不能实现你的要求。
    KiZuNaYa
        27
    KiZuNaYa   44 天前
    加个定时器不就好了?
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1579 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 16:40 · PVG 00:40 · LAX 09:40 · JFK 12:40
    ♥ Do have faith in what you're doing.