今天在寫js 全局變量作用域的時候,碰到了一個納悶的問題
首先根據定義:全局變量有兩種方式建立:
1 方法外部聲明的變量,2 方法内部沒有使用var關鍵字聲明的變量
第一次代碼
function Person(str){
this.name=str;
}
var p1=new Person('z3');
console.log(p1.name); //結果 z3
console.log(name); //結果 z3
一開始對于這兩個結果,我認為是理所當然的;
第一個結果 p1.name 傳回z3。首先函數内的this代表着指向目前調用者。通過Person對象建立了一個p1執行個體。再調用p1.name,此時的this指向就是這個對象執行個體。
第二個結果 name 傳回 z3。 當時沒有深究,認為this.name執行完之後建立的是一個全局變量(這裡一下錯了兩個地方,後續說明)。
是以當時得出的總結是 1, this總是指向目前調用者,2,使用this.field可以建立全局變量。
在上面的代碼再添加行代碼
第二次代碼
function Person(str){
this.name=str;
this.age=25;
}
var p1=new Person('z3');
console.log(p1.name); //結果 z3
console.log(name); //結果 z3
console.log(p1.age); //結果25
console.log(age); // age is not defined
對這個結果一開始很不可思議,怎麼name沒問題,age 就變成了沒有定義。
想了一會想不通之後, 打開firebug, 運作之後檢視window這個對象有沒有age這個變量(如果有就是全局變量)。一看果然沒有
隻有一個Person對象及這個對象的執行個體 p1。 那這個name是怎麼回事? 繼續看了下window相關的屬性,居然看到了這麼個東東
居然還有window.name這個屬性,而且值預設是空字元""; 也就是說下面這樣的代碼完全可以執行,沒有undefined, 也沒有 xx is not defined
<script type=text/javascript>
alert(name);
</script>
把上面代碼再做一個修改
第三次代碼
function Person(str){
this.name=str;
age=25;
}
var p1=new Person('z3');
console.log(p1.name); //結果 z3
console.log(name); //結果 z3
console.log(p1.age); //結果 undefined
console.log(age); // 25
這一下就了然了,首先this隻是代表指向目前調用者,this.field 不會建立全局變量。
第二個列印結果是正确的 是因為 name這個全局變量不是通過this.name建立的 而是window自帶了一個name這個屬性,并且預設值為""。通過this.name指派,隻是把window.name的預設值覆寫了。
第三個列印結果為undefined 原因很簡單,age=25 是全局變量要調用隻能是window.age或age。通過p1.age,隻能是聲明了一個變量但是未指派,是以列印出來就是undefined
目前隻是知道window對象中有name這個屬性,而且它的作用很廣,其中有個重要的作用是可以解決js中同源政策的問題。