JavaScript 自定义事件机制实现:从基础到多绑定与移除

作者:木棉

时间:2026-10-23

浏览:486

本文深入探讨 JavaScript 中自定义事件的实现机制。通过类设计模式,利用事件对外通信以提高开发效率。重点解析如何通过 createFunction 封装带参函数以解决参数传递问题,并实现事件的多绑定与动态移除功能,展示完整的代码逻辑与执行流程。

文章目录

JavaScript 自定义事件机制实现:从基础到多绑定与移除

此外,借助事件机制可将类设计为独立模块,通过事件进行外部通信,从而提升程序的开发效率。相信熟悉 C# 的程序员对事件的优势并不陌生。接下来,让我们直接通过代码来理解:


function class1() { // 最简单的事件设计模式


}

class1.prototype = {


show: function () {


this .onShow();


},

onShow: function () { }


}

function test() {


var obj = new class1();


obj.onShow = function () {


alert( " test " );


}

obj.show();


}

事件处理程序参数传递

接下来探讨如何向事件处理程序传递参数:


// 将有参数的函数封装为无参数的函数


function createFunction(obj, strFunc) {


var args = []; // 定义args 用于存储传递给事件处理程序的参数


if ( ! obj) obj = window; // 如果是全局函数则obj=window;


// 得到传递给事件处理程序的参数


for ( var i = 2 ; i < arguments.length; i ++ ) args.push(arguments[i]);


// 用无参数函数封装事件处理程序的调用


return function () {


obj[strFunc].apply(obj, args); // 将参数传递给指定的事件处理程序


}
}

function class1() {


}

class1.prototype = {


show: function () {


this .onShow();


},

onShow: function () { }


}

function objOnShow(userName) {


alert( " hello, " + userName);


}

function test() {


var obj = new class1();


var userName = " test " ;


obj.onShow = createFunction( null , " objOnShow " , userName);


obj.show();


}

自定义事件的多绑定实现

由于事件机制仅传递函数名称而不包含参数信息,直接传递参数不可行。为此,我们可以转换思路:不思考如何传入参数,而是思考如何构建一个无需参数的处理程序,该程序由原有的带参处理程序创建而成,即外层封装。这里的封装函数即为 createFunction,它巧妙地利用 apply 方法将带参函数转换为无参函数。最后,我们来看看如何实现自定义事件的多绑定:


// 使自定义事件支持多绑定


// 将有参数的函数封装为无参数的函数


function createFunction(obj, strFunc) {


var args = []; // 定义args 用于存储传递给事件处理程序的参数


if ( ! obj) obj = window; // 如果是全局函数则obj=window;


// 得到传递给事件处理程序的参数


for ( var i = 2 ; i < arguments.length; i ++ ) args.push(arguments[i]);


// 用无参数函数封装事件处理程序的调用


return function () {


obj[strFunc].apply(obj, args); // 将参数传递给指定的事件处理程序


}
}

function class1() {


}

class1.prototype = {


show: function () {


if ( this .onShow) {


for ( var i = 0 ; i < this .onShow.length; i ++ ) {


this .onShow[i]();


}
}
},

attachOnShow: function (_eHandler) {


if ( ! this .onShow) { this .onShow = []; }


this .onShow.push(_eHandler);


}
}

function objOnShow(userName) {


alert( " hello, " + userName);


}

function objOnShow2(testName) {


alert( " show: " + testName);


}

function test() {


var obj = new class1();


var userName = " your name " ;


obj.attachOnShow(createFunction( null , " objOnShow " , userName));


obj.attachOnShow(createFunction( null , " objOnShow2 " , " test message " ));


obj.show();


}

事件处理函数的动态移除

可以看出,attachOnShow 方法的基本思想是对数组执行 push 操作。实际上,我们也可以在事件执行完毕后移除处理函数,下面单独实现这一功能:


// 将有参数的函数封装为无参数的函数


function createFunction(obj, strFunc) {


var args = []; // 定义args 用于存储传递给事件处理程序的参数


if ( ! obj) obj = window; // 如果是全局函数则obj=window;


// 得到传递给事件处理程序的参数


for ( var i = 2 ; i < arguments.length; i ++ ) args.push(arguments[i]);


// 用无参数函数封装事件处理程序的调用


return function () {


obj[strFunc].apply(obj, args); // 将参数传递给指定的事件处理程序


}
}

function class1() {


}

class1.prototype = {


show: function () {


if ( this .onShow) {


for ( var i = 0 ; i < this .onShow.length; i ++ ) {


this .onShow[i]();


}
}
},

attachOnShow: function (_eHandler) { // 附加事件


if ( ! this .onShow) { this .onShow = []; }


this .onShow.push(_eHandler);


},

detachOnShow: function (_eHandler) { // 移除事件


if ( ! this .onShow) { this .onShow = []; }


this .onShow.pop(_eHandler);


}
}

function objOnShow(userName) {


alert( " hello, " + userName);


}

function objOnShow2(testName) {


alert( " show: " + testName);


}

function test() {


var obj = new class1();


var userName = " your name " ;


obj.attachOnShow(createFunction( null , " objOnShow " , userName));


obj.attachOnShow(createFunction( null , " objOnShow2 " , " test message " ));


obj.show();


obj.detachOnShow(createFunction( null , " objOnShow " , userName));


obj.show(); // 移除一个,显示剩余的一个


obj.detachOnShow(createFunction( null , " objOnShow2 " , " test message " ));


obj.show(); // 两个都移除,一个也不显示


}

关于自定义事件的学习暂告一段落。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章