zoukankan      html  css  js  c++  java
  • 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

    函数描述FFNIE
    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

    属性描述FFNIE
    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;
  • 相关阅读:
    Hdu 1257 最少拦截系统
    Hdu 1404 Digital Deletions
    Hdu 1079 Calendar Game
    Hdu 1158 Employment Planning(DP)
    Hdu 1116 Play on Words
    Hdu 1258 Sum It Up
    Hdu 1175 连连看(DFS)
    Hdu 3635 Dragon Balls (并查集)
    Hdu 1829 A Bug's Life
    Hdu 1181 变形课
  • 原文地址:https://www.cnblogs.com/shirly77/p/6250631.html
Copyright © 2011-2022 走看看