如何获取函数表达式的返回值?以动态select的onchange事件问题为例
问题根因
你代码运行后拿到undefined是两个独立的JS机制特性叠加导致的:
- 具名函数表达式的作用域限制:写在
select.onchange = function changeMonth() {}中的changeMonth是具名函数表达式,这个函数名仅在函数自身的闭包内部可访问,外部代码无法直接引用。你后续写的changeMonth()调用时,全局作用域下根本不存在名为changeMonth的变量,自然取不到正确返回值。 - 直接调用时的this指向丢失:就算你能正常引用到这个函数,脱离事件触发场景裸调用时,函数内部的
this不会自动指向select元素——浏览器非严格模式下会指向全局window,严格模式下直接为undefined,就算能执行,this.value也拿不到select的选中值。
正确实现方案
- 方案1:独立声明取值函数,手动绑定this指向
把取值逻辑抽成独立可访问的函数,绑定事件和手动调用时都通过call/apply/bind固定this为select元素本身:// 独立声明的取值函数 function getSelectedMonth() { return this.value; } // 创建select元素 const select = document.createElement('select'); select.setAttribute('id', 'select_month'); // 绑定onchange,固定this指向当前select实例 select.onchange = getSelectedMonth.bind(select); // 手动调用取值时,同样把this指向select实例 const selectedMonth = getSelectedMonth.call(select); - 方案2:直接通过DOM API取选中值,无需绕函数调用
你已经给select设置了固定id,不管事件是否触发、不管绑定的函数是什么,直接读取DOM实例的value即可拿到选中值:// 任意位置都可以直接取当前选中值 const currentValue = document.getElementById('select_month').value; - 方案3:将函数表达式赋值给外部可访问的变量
不依赖具名函数表达式的内部名称,把函数表达式赋值给外部作用域可访问的变量,解决作用域访问问题:// 函数表达式赋值给外部变量 let changeMonth = function() { return this.value; } const select = document.createElement('select'); select.setAttribute('id', 'select_month'); // 绑定onchange事件,事件触发时this会自动指向select select.onchange = changeMonth; // 手动调用时手动绑定this到select实例 const selectedMonth = changeMonth.call(select);
注意:事件绑定场景下,onchange触发时浏览器会自动把事件绑定的DOM元素作为函数的this传入,所以事件触发时
this.value能正常拿到值;但手动调用事件处理函数时,不存在这个自动传this的机制,必须手动指定指向,否则会拿到非预期的结果。
内容的提问来源于stack exchange,提问作者Grogu
相关产品推荐
相关产品推荐

