document.getElementById介绍


Posted in Javascript onSeptember 13, 2011

把你的大脑当做浏览器执行下面的代码两次,分别是IE6和IE9:

function testFunc(){ 
alert('test') 
} 
$(function(){ 
var g = document.getElementById , 
w = window.testFunc ; 
//g 
alert(typeof(g)); 
alert(String(g)); 
alert(g instanceof Object); 
alert(g instanceof Function); 
//w 
alert(typeof(w)); 
alert(String(w)); 
alert(w instanceof Object); 
alert(w instanceof Function); 
//执行 
alert(g('t')); 
w(); 
});

在标准浏览器中(IE9、FF、chrome等)上述代码执行得非常一致,返回结果如下:
typeof => "function"
String => "function #funcName#{[native code]}" 
instanceof Object => true 
instanceof Function => true

很奇怪,虽然类型是函数,但是我们却不能直接使用括号来执行函数g,而需要使用call

g.call(document,elementId);
但是如果运行环境是IE6,一切看起来非常诡异,下面是运行结果(注意粗体部分):

//g 
typeof => "object" 
String => "function getElementById{[native code]}" 
instanceof Object => false 
instanceof Function => false 
//w 
typeof => "function" 
String => "function testFunc{alert('test')}" 
instanceof Object => true 
instanceof Function => true

在IE 6下,对于g和w都只能使用括号直接执行函数,而不需要使用call。对于函数g使用下面的方式调用会导致一个“对象没有该属性”的错误:
g.call(document,eleId)
在IE6下,对于自定义的函数testFunc测试结果没有任何问题,但是对于g却十分地诡异!

既然g是object那么为何可以像函数一样用()直接调用执行?
而在标准浏览器中,g既然是函数为什么却不能直接使用()来执行呢?
事实上对于document.getElementById,它到底是function还是object就连jQuery 1.6.2也没有解决这个问题。
在IE6中$.isFunction(g)仍然返回的是false!下面是jQuery 1.6.2的jQuery.isFunction的相关源代码:

class2type={}; 
... 
// Populate the class2type map 
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { 
class2type[ "[object " + name + "]" ] = name.toLowerCase(); 
}); 
... 
type: function( obj ) { 
return obj == null ? 
String( obj ) : 
class2type[ Object.prototype.toString.call(obj) ] || "object"; 
}, 
... 
isFunction: function( obj ) { 
return jQuery.type(obj) === "function"; 
}

于是在StackOverflow上提了这个问题,好在牛人确实多,很快就有了回复。最后我简单的总结一下给大家参考:
document.getElementById 最初被定义为 HTMLDocument (HTML DOM)接口的一个成员,但是在后来的 2 级 DOM 中移入到 Document (XML DOM)接口中。
document.getElementById属于host object,它是一个function,但是它并没有被定义在ECMAScript中而是DOM接口的一部分。
支持[[Call]](内部属性?)host object的typeof返回值就是function。请记住Host Objects并不总是遵循Native Objects的相关规则,比如typeof。
而对于testFunc它是native object, 更具体地说是native function。
下面是EcmaScript 5对于typeof操作符的返回结果的归类:

Type of val Result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Object (native and does not implement [[Call]]) "object"
Object (native or host and does implement [[Call]]) "function"
Object (host and does not implement [[Call]]) Implementation-defined except may not be "undefined", "boolean", "number", or "string".
所以如果要实现用$代替document.getElementById需要这么做:
var $ = function(id) { return document.getElementById(g) };

但是即使有了上面的解释之后,我对Host Object和Native Object又有了新的疑惑。
Javascript 相关文章推荐
JS getMonth()日期函数的值域是0-11
Feb 15 Javascript
jquery实现的超出屏幕时把固定层变为定位层的代码
Feb 23 Javascript
禁止iframe页面的所有js脚本如alert及弹出窗口等
Sep 03 Javascript
用js读、写、删除Cookie代码续篇
Dec 03 Javascript
深入分析Javascript事件代理
Jan 30 Javascript
js图片切换具体实现代码
Oct 13 Javascript
基于JQuery的购物车添加删除以及结算功能示例
Mar 08 Javascript
原生JS实现导航下拉菜单效果
Nov 25 Javascript
JS实现数组按升序及降序排列的方法
Apr 26 Javascript
jQuery替换节点元素的操作方法
Mar 18 jQuery
react 生命周期实例分析
May 18 Javascript
通过vue.extend实现消息提示弹框的方法记录
Jan 07 Vue.js
动态创建样式表在各浏览器中的差异测试代码
Sep 13 #Javascript
contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
Sep 13 #Javascript
jQuery中使用了document和window哪些属性和方法小结
Sep 13 #Javascript
从jQuery.camelCase()学习string.replace() 函数学习
Sep 13 #Javascript
各情景下元素宽高的获取实现代码
Sep 13 #Javascript
JS字符串函数扩展代码
Sep 13 #Javascript
Javascript学习笔记 delete运算符
Sep 13 #Javascript
You might like
用php和MySql来与ODBC数据连接
2006/10/09 PHP
鸡肋的PHP单例模式应用详解
2013/06/03 PHP
19个Android常用工具类汇总
2014/12/30 PHP
PHP中数据类型转换的三种方式
2015/04/02 PHP
详解PHP的Yii框架中日志的相关配置及使用
2015/12/08 PHP
PHP使用socket发送HTTP请求的方法
2016/02/14 PHP
深入解析PHP的Yii框架中的缓存功能
2016/03/29 PHP
PHP简单实现图片格式转换(jpg转png,gif转png等)
2019/10/30 PHP
Javascript-Mozilla和IE中的一个函数直接量的问题
2007/01/09 Javascript
JS处理VBArray的函数使用说明
2008/05/11 Javascript
js的压缩及jquery压缩探讨(提高页面加载性能/保护劳动成果)
2013/01/29 Javascript
JavaScript使用focus()设置焦点失败的解决方法
2014/09/03 Javascript
基于JavaScript实现div层跟随滚动条滑动
2016/01/12 Javascript
jQuery遍历DOM节点操作之filter()方法详解
2016/04/14 Javascript
js Canvas绘制圆形时钟效果
2017/02/17 Javascript
关于js中的鼠标事件总结
2017/07/11 Javascript
详解在vue-test-utils中mock全局对象
2018/11/07 Javascript
layUI实现前端分页和后端分页
2019/07/27 Javascript
vue简单练习 桌面时钟的实现代码实例
2019/09/19 Javascript
vue通过接口直接下载java生成好的Excel表格案例
2020/10/26 Javascript
[02:27]2014DOTA2国际邀请赛 VG赛后采访:更大的挑战在等着我们
2014/07/13 DOTA
[04:01]2014DOTA2国际邀请赛 TITAN告别Ohaiyo期望明年再战
2014/07/15 DOTA
在Python中关于中文编码问题的处理建议
2015/04/08 Python
Python实现返回数组中第i小元素的方法示例
2017/12/04 Python
利用python实现对web服务器的目录探测的方法
2019/02/26 Python
python3.6中@property装饰器的使用方法示例
2019/08/17 Python
python 的numpy库中的mean()函数用法介绍
2020/03/03 Python
中国医药集团国药在线:国药网
2017/02/06 全球购物
专门经营化妆刷的美国彩妆品牌:Sigma Beauty
2017/09/11 全球购物
Rentalcars.com中国:世界上最大的在线汽车租赁服务
2019/08/22 全球购物
设计师个人求职信范文
2014/02/02 职场文书
初三学生评语大全
2014/04/24 职场文书
争先创优个人总结
2015/03/04 职场文书
实习护士自荐信
2015/03/25 职场文书
幼儿园园务工作总结2015
2015/05/18 职场文书
使用Oracle命令进行数据库备份与还原
2021/12/06 Oracle