模块化JavaScript:如何传递变量与事件?
模块化JavaScript中正确传递变量与事件的方法
我来帮你梳理一下这段代码里的问题,以及模块化JS里正确传递变量、绑定事件的核心要点~
先说说你代码里的核心问题
你在bindEvents里写的this.show.click(this.sendData(this.start_date, this.end_date))有两个关键问题:
- 函数立即执行:这里你直接调用了
sendData,页面加载时就会执行它,而不是点击按钮时才触发。 - 事件对象与this指向混乱:
sendData里的e参数会是undefined,而且点击事件触发时,this会指向按钮元素,不是getData对象本身。
正确的事件绑定与变量传递方案
方案1:用箭头函数保留this指向(推荐)
箭头函数不会改变this的指向,会继承外层上下文的this(也就是getData对象),同时可以灵活传递事件对象和变量:
bindEvents: function() { // 点击时执行箭头函数,再调用sendData this.show.addEventListener('click', (e) => { this.sendData(e); }); }
对应的sendData可以直接访问对象自身的变量,不用额外传递:
sendData: function(e){ e.preventDefault(); // 直接用this访问模块内的变量 console.log(this.start_date); console.log(this.end_date); // this.form.submit(); }
方案2:用bind绑定this与预设参数
如果不想用箭头函数,可以用bind来固定this的指向,还能提前预设参数:
bindEvents: function() { // bind返回新函数,this绑定为getData,同时预设前两个参数 this.show.addEventListener('click', this.sendData.bind(this, this.start_date, this.end_date)); }
注意这时候sendData的参数顺序要调整,bind预设的参数会排在事件对象前面:
sendData: function(sdate, edate, e){ e.preventDefault(); console.log(sdate); // 拿到start_date console.log(edate); // 拿到end_date console.log(this); // 指向getData对象 }
变量传递的优化建议
1. 让模块更独立,避免直接嵌入PHP输出
你现在直接在对象字面量里写<?php echo $start_ts; ?>,虽然能工作,但会让模块和PHP耦合度太高。可以改成初始化时传入参数:
const getData = { start_date: null, end_date: null, // 把变量作为init的参数传入 init: function(startDate, endDate) { this.start_date = startDate; this.end_date = endDate; this.cacheDom(); this.bindEvents(); }, // ... 其他方法 } // 页面里初始化模块时传入PHP生成的变量 getData.init(<?php echo $start_ts; ?>, <?php echo $stop_ts; ?>);
2. 明确获取DOM元素,避免全局依赖
原代码里this.form = form;依赖全局的form变量,很容易出问题,最好在cacheDom里明确获取:
cacheDom: function() { this.form = document.getElementById('your-form-id'); this.show = document.getElementById('your-button-id'); }
修正后的完整代码
const getData = { start_date: null, end_date: null, init: function(startDate, endDate) { this.start_date = startDate; this.end_date = endDate; this.cacheDom(); this.bindEvents(); }, cacheDom: function() { this.form = document.getElementById('data-form'); this.show = document.getElementById('show-data-btn'); }, bindEvents: function() { this.show.addEventListener('click', (e) => { this.sendData(e); }); }, sendData: function(e){ e.preventDefault(); console.log(this.start_date); console.log(this.end_date); // this.form.submit(); }, render: function() {} } // 初始化模块 getData.init(<?php echo $start_ts; ?>, <?php echo $stop_ts; ?>);
内容的提问来源于stack exchange,提问作者Imnotapotato
相关产品推荐
相关产品推荐

