在JavaScript中不论什么时候执行程式码,他都是在执行环境里面执行,而他的基础执行环境就是「全域执行环境」,当JavaScript在建立这个「全域执行环境」时会创造两个东西,第一个是全域物件Global Object
,另一个就是此篇文章要讲的主题,一个特殊的变数:this
。
一开始说JavaScript不论何时执行都一定会创造这两个东西,因为程式码已经在建立出来的「执行环境」中执行了,也就是说,就算我们在没有任何程式码的情况下去呼叫this
他也不会是undefined或是出错,如下:
在执行环境被建立的状况下,他可以决定this
里面是什么,而在「全域执行环境」中的this
就代表这个「浏览器的视窗」,因为我在浏览器中执行JavaScript,所以这时候的this
也就是window
物件,如下:
所以说当在「全域执行环境」中宣告一个全域变数,就可以把this
当物件一样去调用他,例如:
//宣告全域变数Astrvar Astr = 'A';//宣告一个印出this中Astr的funcitonvar func = function(){ console.log(this.Astr);};func(); //会输出A
在「全域执行环境」中宣告一个变数,那这个变数就会像特性一样,建立在window
物件中,所以当我们在全域环境执行func()
的时候,就等于是印出window.Astr
的值,而我们也能够在console中看到他,如下:
但是this
也不会永远是window
物件,当他出现在物件内的时候this
则会代表this
所在的该物件,例如:
//建立一个物件Avar objA = { name:'A', writeName:function(){ console.log(this.name); }};objA.writeName(); //会输出A
因为writeName()
这个function是透过objA执行的,所以这时候的this
就会变成objA,不是window
,接下来继续举个例子:
//建立一个物件Avar objA = { name:'A', writeName:function(){ console.log(this.name); }, objB:{ name:'B', writeName:function(){ console.log(this.name); }, }};objA.objB.writeName(); //会输出B
虽然writeName()
这个function还是在objA内,但他其实是在objA中的特性objB内被呼叫,所以这时候的this
会是objB,而不是objA也不是window
。
最后我们看个比较容易混淆的:
//宣告全域变数namevar name = '_this';//建立一个物件Avar objA = { name:'A', writeName:function(){ //在writeName特性里面宣告一个印出this.name的function并执行他 var writeNameB = function(){ console.log(this.name) }; writeNameB(); },};objA.writeName(); //会输出_this
这个答案是不是很令人惊讶!我们把程式码拆开来看,一般来说在调用writeName()
这个function的时候是以objA去调用的,所以他的this.name
应该会是'A',但是!那是在writeName()
里面的情况下,在上面的例子中真正印出this.name
的function是writeNameB()
,而我们在writeName()
里面执行writeNameB()
的时候并没有在任何物件下调用他,这时候的this
就不会指向该物件,而会是「全域执行环境」中的window
,所以他会印出的this.name
就会等于window.name
,也就是印出全域变数的name也就是_this。
当然还有很多可以应用到this的地方,例如onclick事件中的参数this可以回传触发的Element之类的,不过因为这篇主要在讲JavaScript中的this,如果有机会下次再打一篇文章说明。
如果我有观念错误或解释不清楚的地方,还麻烦各位大大指点了,谢谢大家!