JavaScript函数绑定用法实例分析
本文通过ExtJS面板开发实例,深入解析JavaScript中函数this指针在事件回调中丢失的问题。文章对比了传参、全局变量、闭包及call方法四种解决方案,重点推荐利用call实现函数绑定的最佳实践,帮助开发者正确处理对象上下文。
JavaScript函数绑定概述
本文通过具体实例详细讲解JavaScript中的函数绑定技术,旨在为读者提供实用的参考与借鉴。
前言

假设你需要实现一个包含数字按钮(如1、2、3)的界面,点击这些按钮后在文本输入框中显示对应内容,并具备删除功能。至于拨打功能,此处暂不深入,仅作模拟演示。若由我初始开发,通常会采取以下步骤:
1. 使用CSS和HTML构建界面布局。
2. 利用JavaScript的事件委托机制,监听按钮父节点的点击事件。
然而,若采用面向对象的思想进行开发,情况会有所不同。由于我使用了Ext框架,它封装了许多底层逻辑。对于不熟悉Ext的读者,我将尽量详细解释后续代码的含义。
描述
ContactTelPanel =Ext.extend(Ext.Panel, {
//构造方法
constructor : function(config) {
Ext.apply(this, config);//直接把config对象的属性全复制到this对象中
Parent = this.parent;
var me = this;
ContactTelPanel.superclass.constructor.call(this, {//用ContactTelPanel的父类也就是Ext.Panel的构造函数
autoScroll : true,
title : "拨打电话",//设置title,跟这篇文章的主体没关系,不要管他
id : "contacttelpanel",
bodyStyle : "padding: 30px 300px;",
defaults : {//可以为该对象(ContactTelPanel)包含的组件(也就是在items配置选项)设置一些相同属性
layout : "column",
defaults : {
xtype : "button",
width : 50,
height : 25,
style : "margin:4px 15px",
handler : this.press //为每个按钮都添加一个click的事件
},
bodyBorder : false
},
items : [ {//textfield组件
height : 30,
width : 250,
xtype : "textfield",
id : "tf",
style : "margin-bottom:10px"
}, {// 没有xtype就是默认为panel,下面也是,不然就不要纠结了,直接在这里想象成第一行按钮1、按钮2、按钮3
items : [ {
text : "1"
}, {
text : "2"
}, {
text : "3"
} ]
}, {// 这里是按钮4、按钮5、按钮6
items : [ {
text : "4"
}, {
text : "5"
}, {
text : "6"
} ]
}, {// 这里是按钮7、按钮8、按钮9 下同
items : [ {
text : "7"
}, {
text : "8"
}, {
text : "9"
} ]
}, {
items : [ {
text : "*"
}, {
text : "0"
}, {
text : "#"
} ]
}, {
items : [ {
text : "拨打",
}, {
text : "删除",
} ]
} ]
});
},
press : function() {
var text = this.text, textfield = Ext.getDom("tf");
if (/[0-9*#]/.test(text)) {//在textfield中显示所点击按钮的数字
textfield.value += text;
} else if (this.text == "删除") {//删除功能
textfield.value = textfield.value.slice(0, -1);
} else if (this.text == "拨打") {//这个先不要管他
Tel.telcall(textfield.value);
}
}
});
问题背景与this指针丢失
从上述代码可以看出,ContactTelPanel继承了Ext.Panel,该面板包含多个按键,每个按键都监听了click事件。实际上,这种写法效率较低,更优的做法是使用事件委托,仅监听父节点的click事件,并通过事件流判断目标对象进行操作。本文的核心在于探讨handler : this.press这段代码在事件监听中的应用。我遇到的主要问题是:如果在press函数中需要使用ContactTelPanel类的某些属性,该如何处理?
思路
我的初步想法是,在press函数中直接使用this对象来获取类属性。但实际测试发现,如果在press函数中执行console.dir(this),Chrome控制台显示的对象并非ContactTelPanel,而是Button对象。这是因为this指针在回调执行时发生了改变。针对这一情况,我总结了以下三种解决方法:
函数绑定的四种解决方案
解决方案
方法一:在监听事件的函数中传递参数。
代码示例:handler : this.press(this),随后在press函数体中编写alert(arguments[0])。
现象:页面加载时确实会弹出ContactTelPanel窗口,但点击按钮时并未出现预期效果。
原因分析:this.press(this)这种写法会被JavaScript解析器视为立即调用press函数,导致其在页面加载时即被执行,而非在点击时执行。
方法二:在ContactTelPanel类中定义全局变量。
代码示例:例如在第5行设置me = this,然后在press函数体中编写alert(me)。
现象:点击按钮时能成功弹出窗口,方案可行。
缺点:污染全局变量,容易被别人无意篡改。比如我在引入这个页面的js后面再引用其他js的时候,在后面的js中设置var me = "monkindey",那么你再点击那个页面的按钮的时候它会弹出123,为不是ContactTelPanel对象
方法三:简单运用闭包。
代码示例:handler : function(){me.press(me)}。注:me即为ContactTelPanel对象。由于在内部function中this指针已变为button对象,因此应在function外部使用me(或其他变量名)保存this对象,即var me = this。
现象:此方法运行成功。
方法四:使用call实现函数绑定。
代码示例:handler : function(){ me.press.call(this,me);}。
个人评价:我认为这是最为实用的方法。
补充说明:前文已详解基于纯JavaScript的函数绑定技术,感兴趣的读者可对比阅读,分析两者的异同。
附录:此处附上JavaScript系统自带事件参考表,供读者查询使用:
JavaScript事件与功能说明大全: http://tools.jb51.net/table/javascript_event
如需了解更多JavaScript相关内容,可查看本站专题:《JavaScript常用函数技巧汇总》、《JavaScript事件相关操作与技巧大全》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》。
希望本文所述内容能对大家的JavaScript程序设计有所帮助。
JS处理含Emoji或中文的字符串转数组乱码问题
2026-11-05 16:12:28
JS怎么使用展开运算符合并对象
2026-11-05 14:42:18
ES6+环境下判断JS对象为空的简洁写法
2026-11-05 12:12:23
怎么通过replacer函数自定义JS中JSON的格式化输出
2026-11-05 11:19:44
JS正则表达式基础:字面量与RegExp构造函数的区别及常用元字符
2026-11-05 11:16:58
