允许其他JavaScript函数(包括其他文件中的函数)“挂接到”我的函数中

时间:2019-06-21 01:50:21

标签: javascript hook

我觉得我想得太过分了,但是我坚持了下来。 JavaScript是否有能力允许其他功能(来自相同或不同的JS文件)与功能挂钩?

澄清一下,如果我在编写的函数中创建一个数组,是否可以在解析之前允许其他JS文件挂接该数组以修改该数组?还是我需要构建某种系统来管理所有“挂钩”?如果可能的话,我想避免使用全局窗口变量,但是起作用。

这是一个例子

为了争辩,我们假设它们按照我列出的顺序运行(忽略我在此处创建的竞争条件)。

main.js

var animals = ['cat', 'dog'];
animals = hookIntoThis(animals); //Allow other functions or files to add/modify animals to the array here
console.log(animals); //--> "cat", "dog", "elephant"

hookIntoThis()实际上并不是对任何东西的引用,而这正是我要让其他函数/文件(如果存在)修改数组的地方。

other.js

function addMoreAnimals(animals){ //This would somehow listen for that hook from main.js
    animals.push('elephant');
    animals.push('lion');

    return animals;
}

whatever.js

function noLions(animals){ //This would also hook into that function from main.js to modify the array
    if ( animals.indexOf('lion') >= 0 ){
        animals.splice(animals.indexOf('lion'), 1); //Just for the sake of example
    }

    return animals;
}

起初,我以为自定义DOM事件/侦听器会起作用,但是(据我所知)这是单向的。我可以触发甚至将动物数组传递给DOM事件,但是除非使用全局窗口变量,否则我将无法获取任何数据 back

如果这是一个过于简单的概念和/或重复的问题,我深表歉意。在发布之前,我做了很多搜索。

1 个答案:

答案 0 :(得分:0)

我认为,如果main不知道哪些其他模块将要修改animals,自定义事件侦听器就是正确的选择。

如果您知道所有钩子将同步执行,则可以在主线程完成后让main在微任务中完成其主要工作(修改后),例如:

// main.js
let modifiableAnimals = ['cat', 'dog'];
window.addEventListener('customHook', ({ detail: modifyFn }) => {
  modifiableAnimals = modifyFn(modifiableAnimals);
});
Promise.resolve()
  .then(() => {
    console.log(modifiableAnimals);
  });

// other.js
window.dispatchEvent(
  new CustomEvent(
    'customHook',
    {
      detail: (animals) => {
        animals.push('elephant');
        animals.push('lion');
        return animals;
      }
    }
  )
);

// whatever.js
window.dispatchEvent(
  new CustomEvent(
    'customHook',
    {
      detail: (animals) => {
        if ( animals.indexOf('lion') >= 0 ){
          animals.splice(animals.indexOf('lion'), 1); //Just for the sake of example
        }
        return animals;
      }
    }
  )
);

如果您知道现有数组仅将被变异(并且不必重新分配),则可以对其进行简化:

// main.js
const modifiableAnimals = ['cat', 'dog'];
window.addEventListener('customHook', ({ detail: modifyFn }) => {
  modifyFn(modifiableAnimals);
});
Promise.resolve()
  .then(() => {
    console.log(modifiableAnimals);
  });

// other.js
window.dispatchEvent(
  new CustomEvent(
    'customHook',
    {
      detail: (animals) => {
        animals.push('elephant');
        animals.push('lion');
      }
    }
  )
);

// whatever.js
window.dispatchEvent(
  new CustomEvent(
    'customHook',
    {
      detail: (animals) => {
        if ( animals.indexOf('lion') >= 0 ){
          animals.splice(animals.indexOf('lion'), 1); //Just for the sake of example
        }
      }
    }
  )
);

这仍然很奇怪,IMO。如果可能的话,我考虑与main.js和其他文件建立一个 else 接口,并使用处理程序调用{​​{1}}函数:

main.js