JavaScript中兩種類型的全局對象/函數



一、核心JavaScript內置對象,即ECMAScript實現提供的不依賴於宿主環境的對象

這些對象在程序執行之前就已經(實例化)存在了。ECMAScript稱為The Global Object,分為以下幾種

1, 值屬性的全局對象(Value Properties of the Global Object)。有NaN,Infinity,undefined。
2, 函數屬性的全局對象(Function Properties of the Global Object)。有eval,parseInt,parseFloat,isNaN,isFinite,decodeURI,encodedURI,encodeURIComponent
3,構造器(類)屬性的全局對象(Constructor Properties of the Global Object)。有Object,Function,Array,String,Boolean,Number,Date,RegExp,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError。
4,其它屬性的全局對象(Other Properties of the Global Object),可以看出成是Java中的靜態類,可以直接用類名+點號+方法名使用。有Math,JSON。

ECMAScript規范提到這些全局對象(The Global Object)是具有Writable屬性的,即Writable為true,枚舉性(Enumerable)為false,即不能用for in枚舉。ECMAScript有這么一段

Unless otherwise specified, the standard built-in properties of the global object have attributes {[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}.


雖然規范提到The Global Object是可以被重寫的,但不會有誰去重寫它們的。這里僅僅做個測試。

1
2
3
4
5
6
7
8
9
NaN    = 11;
eval   = 22;
Object = 33;
Math   = 44;
 
alert(NaN);
alert(eval);
alert(Object);
alert(Math);<br>

分別取值屬性的全局對象, 函數屬性的全局對象,構造器(類)屬性的全局對象,其它屬性的全局對象NaN,eval,Object,Math。結果如下

結果可以看出除了NaN在IE9(pre3)/Safari不能被重寫外,其它都被重寫了。這里只是列舉了四個,感興趣的可以將以上所有的The Global Object一一測試下。這里想表達的是核心JavaScript內置對象一般是可以被重寫的 ,雖然沒人這么干。

下面測試下其可枚舉性

1
2
3
4
5
6
7
8
9
10
11
12
for ( var  in  NaN){
     alert(a);
}
for ( var  in  eval){
     alert(a);
}
for ( var  in  Object){
     alert(a);
}
for ( var  in  Math){
     alert(a);
}

所有瀏覽器都沒有彈出,即屬性不被枚舉。感興趣的可以將以上所有的The Global Object的枚舉性一一測試下。當然對於有些瀏覽器如Firefox,某些Global Object被重寫后又是可以被枚舉的。


二、宿主環境提供的全局對象/函數 

如window,alert,setTimeout,document,location等,多數瀏覽器都會限制其重寫

1
2
window = 55;
alert(window);

該句在IE下會出錯提示非法復制,后面的彈出框沒有執行。其它瀏覽器則當window=55不存在,仍然彈出了window。

再重寫下alert

1
2
alert = 55;
console.log(alert);

IE下提示報錯,Firefox/Chrome/Safari/Opera竟然被重寫了,從對應的控制台可以看到輸出了55。可以看出對於宿主環境提供的全局對象/函數,有的瀏覽器不支持重寫,有的則可以重寫 。

以下是兩種方式聲明全局變量

1
2
3
4
5
6
7
8
a1 = 11;
var  a2 = 22;
 
for (a  in  window){
     if (a== 'a1' ||a== 'a2' ){
         alert(a)
     }
}

上述代碼在IE中不會彈出信息框,在IE中內部大概如下

1
2
3
4
5
6
7
//IE
with (host_object){ //window
     with (global_object){ //Global
         a1 = 11;
         var  a2 = 22;
     }  
}

即a1,a2是作為上面說的第一種,JS引擎提供的Global對象上的屬性,而非第二種宿主環境提供的window對象上的屬性。因此IE中for in window時a1,a2都不存在。如果IE中提供對象Global對象的引用,沒准下面的代碼可以彈出信息框。

1
2
3
4
5
for (a  in  Global){
     if (a== 'a1' ||a== 'a2' ){
         alert(a)
     }
}

Firefox/Safari/Chrome/Opera中內部大概是下面的樣子

1
2
3
4
5
6
7
//Firefox/Safari/Chrome/Opera
with(host_object){ //window
     a1 = 11;
     var a2 = 22;
     with(global_object){ //Global
     }  
}

即a1,a2是作為上面說的第二種,宿主環境提供的全局對象window上的屬性。因此for in window時a1,a2都存在,彈出了信息框。
再看第三者方式聲明全局變量window.a3 = 33,這樣是顯示的把a3掛在window上作為window的屬性,因此在所有瀏覽器中for in window時都能獲取到a3。

 

全局對象是預定義的對象,作為 JavaScript 的全局函數和全局屬性的占位符。通過使用全局對象,可以訪問所有其他所有預定義的對象、函數和屬性。全局對象不是任何對象的屬性,所以它沒有名稱。

全局對象只是一個對象,而不是類。既沒有構造函數,也無法實例化一個新的全局對象。

頂層函數(全局函數)

FF: Firefox, N: Netscape, IE: Internet Explorer

函數 描述 FF N IE
decodeURI() 解碼某個編碼的 URI。 1 4 5.5
decodeURIComponent() 解碼一個編碼的 URI 組件。 1 4 5.5
encodeURI() 把字符串編碼為 URI。 1 4 5.5
encodeURIComponent() 把字符串編碼為 URI 組件。 1 4 5.5
escape() 對字符串進行編碼。 1 - 3
eval() 計算 JavaScript 字符串,並把它作為腳本代碼來執行。 1 2 3
getClass() 返回一個 JavaObject 的 JavaClass。      
isFinite() 檢查某個值是否為有窮大的數。 1 4 4
isNaN() 檢查某個值是否是數字。 1 2 3
parseFloat() 解析一個字符串並返回一個浮點數。 1 2 3
parseInt() 解析一個字符串並返回一個整數。 1 2 3
unescape() 對由 escape() 編碼的字符串進行解碼。 1 - 3

頂層屬性(全局屬性)

FF: Firefox, N: Netscape, IE: Internet Explorer

屬性 描述 FF N IE
Infinity 代表正的無窮大的數值。 1 4 4
java 代表 java.* 包層級的一個 JavaPackage。      
NaN 指示某個值是不是數字值。 1 4 4
Packages 根 JavaPackage 對象。      
undefined 指示未定義的值。 1 4 5.5
 
 
Note:

encodeURI()和encodeURIComponent()方法用於編碼傳遞給瀏覽器的URI(統一資源標識符)。有效的URI不能包含某些字符,如空格。這兩個方法用於編碼URI,這樣用專門的UTF-8編碼替換所有的非有效字符,就可以使瀏覽器仍能夠接受並理解它們。

encodeURI()方法用於處理完整的URI(例如,http://www.wrox.com/illegal value.htm),而encodeURIComponent()用於處理URI的一個片斷(如前面的URI中的illegal value.htm)。這兩個方法的主要區別是encodeURI()方法不對URI中的特殊字符進行編碼,如冒號、前斜杠、問號和英鎊符號,而encodeURIComponent()則對它發現的所有非標准字符進行編碼。例如:
var sUri = "www.sohu.com/abc def 我.aspx";
alert(encodeURI(sUri));
alert(encodeURIComponet(sUri));

這段代碼輸出兩個值:
www.sohu.com/abc%20def%20%E6%88%91.aspx
www.sohu.com%2Fabc%20def%20%E6%88%91.aspx

可以看到,除空格外,第一個URI無任何改變,空格被替換為%20。第二個URI中的所有非字母數字字符都被替換成它們對應的編碼,基本上使這個URI變得無用。這就是encodeURI()可以處理完整URI,而encodeURIComponent()只能處理附加在已有URI末尾的字符串的原因。

自然,還有兩個方法用於解碼編碼過的URI,即decodeURI()和decodeURIComponent()。如你所料,這兩個方法所做的恰與其對應的方法相反。decodeURI()方法只對用encodeURI()方法替換的字符解碼。例如,%20將被替換為空格,而%23不會被替換,因為它表示的是英鎊符號(#),encodeURI()並不替換這個符號。同樣的,decodeURIComponent()會解碼所有encodeURIComponent()編碼過的字符,意味着它將對所有的特殊值解碼。例如:

這段代碼輸出兩個值:

在這個例子中,變量uri存放的是用encodeURIComponent()編碼的字符串。生成的值說明了應用兩個解碼方法時會發生的事情。第一個值由decodeURI()輸出,把%20替換成空格。第二個值由decodeURIComponent()輸出,替換所有的特殊。

這些URI方法encodeURI()encodeURIComponent()decodeURI()decodeURICom- ponent()代替了BOM的escape()unescape()方法。URI方法更可取,因為它們會對所有Unicode符號編碼,而BOM方法只能對ASCII符號正確編碼。盡量避免使用escape()unescape()方法。

 
sample:
var s="WebForm1.aspx?a=" + encodeURIComponent('abc &=*def 我') + "&b="+ encodeURIComponent('abc def & = *大集合');
alert(s);
window.location.href=s;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM