当前位置:首页 > JavaScript

js 实现before

2026-03-14 22:08:40JavaScript

在JavaScript中,可以通过修改原型链或使用高阶函数来实现类似before的功能,即在目标函数执行前插入自定义逻辑。以下是几种实现方法:

通过原型链扩展Function

Function原型添加before方法,允许在调用原函数前执行前置函数:

Function.prototype.before = function(beforeFn) {
    const originalFn = this;
    return function(...args) {
        beforeFn.apply(this, args);
        return originalFn.apply(this, args);
    };
};

// 示例用法
const sayHello = () => console.log("Hello");
const logBefore = () => console.log("About to say hello");

const wrappedFn = sayHello.before(logBefore);
wrappedFn(); // 输出: About to say hello \n Hello

使用高阶函数包装

直接通过函数组合实现前置逻辑,不修改原型:

js 实现before

const before = (beforeFn, originalFn) => (...args) => {
    beforeFn.apply(this, args);
    return originalFn.apply(this, args);
};

// 示例用法
const sayHi = () => console.log("Hi");
const logTime = () => console.log(`Time: ${new Date().toISOString()}`);

const enhancedHi = before(logTime, sayHi);
enhancedHi(); // 输出时间戳后输出 Hi

保留原函数上下文

确保前置函数和原函数共享相同的this上下文:

Function.prototype.before = function(beforeFn) {
    const originalFn = this;
    return function() {
        beforeFn.call(this);
        return originalFn.call(this);
    };
};

// 示例:对象方法调用
const obj = {
    name: "Alice",
    greet: function() { console.log(`My name is ${this.name}`) }
};
obj.logBefore = () => console.log("Starting greeting...");

obj.greet = obj.greet.before(obj.logBefore);
obj.greet(); // 输出前置日志并正确显示name

参数传递处理

显式处理参数传递的场景:

js 实现before

const beforeWithArgs = (beforeFn, mainFn) => (...args) => {
    beforeFn(args);
    return mainFn(args);
};

// 示例
const add = (a, b) => a + b;
const validate = (args) => {
    if (args.some(isNaN)) throw new Error("Invalid numbers");
};

const safeAdd = beforeWithArgs(validate, add);
console.log(safeAdd(2, 3)); // 5

异步场景支持

处理异步前置操作:

Function.prototype.beforeAsync = async function(beforeFn) {
    const originalFn = this;
    return async function(...args) {
        await beforeFn.apply(this, args);
        return originalFn.apply(this, args);
    };
};

// 示例
const fetchData = async () => "Data";
const checkAuth = async () => {
    await new Promise(resolve => setTimeout(resolve, 500));
    console.log("Auth checked");
};

const secureFetch = fetchData.beforeAsync(checkAuth);
secureFetch().then(console.log); // 先检查认证后获取数据

以上方法可根据具体需求选择:

  • 原型链扩展适合需要全局使用的场景
  • 高阶函数适合局部逻辑组合
  • 异步版本适用于Promise链式调用
  • 注意this绑定和参数传递的细节差异

标签: jsbefore
分享给朋友:

相关文章

js实现全选

js实现全选

实现全选功能的方法 在JavaScript中实现全选功能通常涉及监听全选复选框的点击事件,并根据其状态控制其他复选框的选中状态。以下是几种常见的实现方式: 基础DOM操作实现 通过获取所有目标复选框…

js 实现继承

js 实现继承

原型链继承 通过让子类的原型对象指向父类的实例来实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Par…

js 进度条的实现

js 进度条的实现

使用 HTML 和 CSS 创建基础进度条 HTML 结构可以简单使用一个 div 元素作为容器,内部嵌套另一个 div 表示进度: <div class="progress-containe…

js实现选项卡

js实现选项卡

实现选项卡的基本思路 选项卡通常由一组标签和对应的内容面板组成。点击标签时,显示对应的内容面板,隐藏其他面板。实现这一效果需要结合HTML结构、CSS样式和JavaScript交互逻辑。 HTML结…

js实现复制功能

js实现复制功能

使用 document.execCommand 方法 这种方法适用于较旧的浏览器,但在现代浏览器中可能被逐步淘汰。通过创建一个临时的 textarea 元素,将文本内容放入其中,然后执行复制命令。…

js手势实现

js手势实现

手势识别实现方法 在JavaScript中实现手势识别通常涉及监听触摸事件(touchstart、touchmove、touchend)或鼠标事件(mousedown、mousemove、mouseu…