在学习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,使其在自身作用域内运行,防止污染全局。

js中不容小觑的var声明的更多相关文章

  1. js中局部变量必须用var去声明

    js中的变量与其他的脚本语言都是很不一样的,在function中你如果不用var 声明一个变量,那么这个变量将在全局可见,也就相当于创建了全局变量.所以在function中声明变量尽量都是用var来声 ...

  2. 前端面试题:JS中的let和var的区别

    最近很多前端的朋友去面试被问到let和var的区别,其实阮一峰老师的ES6中已经很详细介绍了let的用法和var的区别.我简单总结一下,以便各位以后面试中使用. ES6 新增了let命令,用来声明局部 ...

  3. js中的let和var

    在ES6中,应该尽量使用const和let来声明变量,而尽量避免使用var. var的缺点是它的作用域比较混乱,使用let能够保证清晰的作用域. 下面看一个小例子. var x = 3; if(x== ...

  4. js中函数提升及var变量提示

    其中,在javascript中,函数声明及var声明的变量会得到提升.但是函数声明会先于var声明的变量被提升.即便function写在后面. 看下面的例子: var aa = 221; functi ...

  5. JS中的let和var的区别

    最近很多前端的朋友去面试被问到let和var的区别,其实阮一峰老师的ES6中已经很详细介绍了let的用法和var的区别.我简单总结一下,以便各位以后面试中使用. ES6 新增了let命令,用来声明局部 ...

  6. 深入探究js中的隐式变量声明

    前两天遇到的问题,经过很多网友的深刻讨论,终于有一个相对可以解释的通的逻辑了,然后我仔细研究了一下相关的点,顺带研究了一下js中的隐式变量. 以下文章中提到的隐式变量都是指没有用var,let,con ...

  7. js中定义变量之②var let const的区别

    var 上一篇文章有讲过,是js定义变量的关键词. 但是在es6中,新添加了两个关键词,用于变量声明的关键词:let 和const 接下来就说一下var let 和const的区别: 首先说var 用 ...

  8. node.js中允许的app对象声明方式

    伪对象形式 app = function () { console.log("我是一个初始化的app对象"); }; app.get=function () { console.l ...

  9. js中定义变量加var与不加var的区别?

    var 不一定是用来定义局部变量的 jscript的全局变量和局部变量的分界是这样的:                  过程体(包括方法function,对象Object o ={})外的所有变量不 ...

随机推荐

  1. hihocoder #1039 : 字符消除 ( 字符串处理类 ) 好久之前做的题目,具体的算法代码中阅读吧

    #1039 : 字符消除 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi最近在玩一个字符消除游戏.给定一个只包含大写字母"ABC"的字符串s,消 ...

  2. Spring Boot2.0之 整合Redis事务

    Redis事物 Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命 ...

  3. chorme dev tools的小技巧

    1 快速文件转换 在DevTools打开的时候,你可以按下Ctrl+P来快速的寻找和打开你工程中的任意文件. 2 在源代码中搜索 Ctrl+Shift+F 即可在所有已加载的文件中查找一个特定的字符串 ...

  4. ML一些零散记录

    朴素贝叶斯的假定条件:变量独立同分布 一般情况下,越复杂的系统,过拟合的可能性就越高,一般模型相对简单的话泛化能力会更好一点,增加隐层数可以降低网络误差(也有文献认为不一定能有效降低),提高精度,但也 ...

  5. 安装JDK+Eclipse+Maven+Git/Gitee(windows系统和linux系统)

    1. 安装JDK 官网下载 下载java SE 下载 Java SE 7 1.1 windows配置jdk windows配置jdk 1.2 Ubuntu配置jdk Ubuntu 安装 JDK 7 / ...

  6. Collection View Programming Guide for iOS---(四)---Using the Flow Layout

      Using the Flow Layout使用流布局 The UICollectionViewFlowLayout class is a concrete layout object that y ...

  7. python学习笔记4-时间函数

    1 time #时间与日期 import time; # This is required to include time module. ticks = time.time() print (&qu ...

  8. js遍历ajax回调函数返回值中的object对象

    function printObject(obj) {      //obj = {"cid":"C0","ctext":"区县& ...

  9. ASP.NET Core 依赖注入(DI)

    ASP.NET Core的底层设计支持和使用依赖注入.ASP.NET Core 应用程序可以利用内置的框架服务将服务注入到启动类的方法中,并且应用程序服务也可以配置注入.由ASP.NET Core 提 ...

  10. 793. Preimage Size of Factorial Zeroes Function

    Let f(x) be the number of zeroes at the end of x!. (Recall that x! = 1 * 2 * 3 * ... * x, and by con ...