视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
浅析JavaScript中两种类型的全局对象/函数_javascript技巧
2020-11-27 21:16:44 责编:小采
文档

这里所说的JavaScript指浏览器环境中的包括宿主环境在内的。第一种是ECMAScript Global Object,第二种是宿主环境(Host)下的全局对象/函数。

一、核心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是可以被重写的,但不会有谁去重写它们的。这里仅仅做个测试。
代码如下:
NaN = 11;
eval = 22;
Object = 33;
Math = 44;

alert(NaN);
alert(eval);
alert(Object);
alert(Math);


分别取值属性的全局对象, 函数属性的全局对象,构造器(类)属性的全局对象,其它属性的全局对象NaN,eval,Object,Math。结果如下

结果可以看出除了NaN在IE9(pre3)/Safari不能被重写外,其它都被重写了。这里只是列举了四个,感兴趣的可以将以上所有的The Global Object一一测试下。这里想表达的是核心JavaScript内置对象一般是可以被重写的 ,虽然没人这么干。

下面测试下其可枚举性
代码如下:
for(var a in NaN){
alert(a);
}
for(var a in eval){
alert(a);
}
for(var a in Object){
alert(a);
}
for(var a in Math){
alert(a);
}

所有浏览器都没有弹出,即属性不被枚举。感兴趣的可以将以上所有的The Global Object的枚举性一一测试下。当然对于有些浏览器如Firefox,某些Global Object被重写后又是可以被枚举的。

二、宿主环境提供的全局对象/函数

如window,alert,setTimeout,document,location等,多数浏览器都会其重写
代码如下:
window = 55;
alert(window);

该句在IE下会出错提示非法复制,后面的弹出框没有执行。其它浏览器则当window=55不存在,仍然弹出了window。

再重写下alert
代码如下:
alert = 55;
console.log(alert);

IE下提示报错,Firefox/Chrome/Safari/Opera竟然被重写了,从对应的控制台可以看到输出了55。可以看出对于宿主环境提供的全局对象/函数,有的浏览器不支持重写,有的则可以重写 。

以下是两种方式声明全局变量
代码如下:
a1 = 11;
var a2 = 22;

for(a in window){
if(a=='a1'||a=='a2'){
alert(a)
}
}

上述代码在IE中不会弹出信息框,在IE中内部大概如下
代码如下:
//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对象的引用,没准下面的代码可以弹出信息框。
代码如下:
for(a in Global){
if(a=='a1'||a=='a2'){
alert(a)
}
}

Firefox/Safari/Chrome/Opera中内部大概是下面的样子
代码如下:
//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。

下载本文
显示全文
专题