js中不容小觑的var声明
在学习vue相关课程中,有一次跟着老师敲代码,写出了如下代码:
var Child = { template:`<div @click='handleClick'><slot></slot></div>`, methods:{ handleClick(){ this.$bus.$emit( 'change' ); }, }, mounted(){ var self = this; counter = 0; this.$bus.$on( 'change',function(){ counter++; console.log( "you clicked "+counter+" times" ); } ); } };
将组件注册到app实例后,实例化3个子组件,在点击触发'click'的时候,打印效果如下:
点击一次执行3次可以理解,因为每个子组件都给prototype里的$bus总线push了自己的事件处理函数,但理论上来讲,每个组件实例化的过程中,都会调用自己的mounted钩子,在钩子里因为闭包的存在,形成可保存的作用域,所以,每个实例都有自己独立的的context( 如counter ),即:应该执行3次,但counter不应该累加,应该出现3个'you clicked 1 times'。
觉得迷糊,我自己又按照自己的理解写了一遍代码,运行,结果好好的,就是上述期待效果,问题在哪呢?
将两个文件逐行对比后,定位到了问题:
正确的版本
出问题的版本
两个版本之间唯一的差别是,counter变量一个用var声明了,一个没有,于是赶紧搜起...看到这么一篇文章,其中与我的问题相关的核心描述在此:
看到此处,豁然开朗,所以不加var的变量都绑在了全局window对象上,不会再根据mounted钩子函数的执行单独创建作用域了,所有child实例push到$bus里的事件处理函数访问的都是window.counter,所以数值累加就是正常表现了。
看来js代码中var的使用不容小觑,对于声明的任何一个变量都要做到胸有成竹,是不是要绑在window上做全局用?如果不是,一定要加var,使其在自身作用域内运行,防止污染全局。
路漫漫其修远兮,吾将上下而求索。
May stars guide your way⭐⭐⭐