1. 程式人生 > >js中不容小覷的var宣告

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,使其在自身作用域內執行,防止汙染全域性。