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 相关文章推荐
jquery validation插件表单验证的一个例子
Mar 03 Javascript
js获取元素在浏览器中的绝对位置
Jul 24 Javascript
Jquery UI震动效果实现原理及步骤
Feb 04 Javascript
深入解析contentWindow, contentDocument
Jul 04 Javascript
js中parseInt函数浅谈
Jul 31 Javascript
浅析tr的隐藏和显示问题
Mar 05 Javascript
JavaScript中String.match()方法的使用详解
Jun 06 Javascript
JQuery用户名校验的具体实现
Mar 18 Javascript
jQuery3.0中的buildFragment私有函数详解
Aug 16 Javascript
详解如何让Express支持async/await
Oct 09 Javascript
JS使用贪心算法解决找零问题示例
Nov 27 Javascript
js核心基础之闭包的应用实例分析
May 11 Javascript
动态创建样式表在各浏览器中的差异测试代码
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读取30天之内的根据算法排序的代码
2008/04/06 PHP
php设计模式 Decorator(装饰模式)
2011/06/26 PHP
php实现webservice实例
2014/11/06 PHP
PHP遍历数组的方法汇总
2015/04/30 PHP
基于PHP+mysql实现新闻发布系统的开发
2020/08/06 PHP
JS类库Bindows1.3中的内存释放方式分析
2007/03/08 Javascript
javascript 函数调用的对象和方法
2010/07/01 Javascript
电子商务网站上的常用的js放大镜效果
2011/12/08 Javascript
HTML复选框和单选框 checkbox和radio事件介绍
2012/12/12 Javascript
jQuery回车实现登录简单实现
2013/08/20 Javascript
javascript陷阱 一不小心你就中招了(字符运算)
2013/11/10 Javascript
JavaScript基础语法、dom操作树及document对象
2014/12/02 Javascript
require.js的用法详解
2015/10/20 Javascript
javascript 中iframe高度自适应(同域)实例详解
2017/05/16 Javascript
AngularJS ng-repeat指令及Ajax的应用实例分析
2017/07/06 Javascript
vue实现移动端图片裁剪上传功能
2020/08/18 Javascript
JavaScript 保护变量不被随意修改的实现代码
2017/09/27 Javascript
基于JavaScript表单脚本(详解)
2017/10/18 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
2018/07/20 Javascript
5个你不知道的JavaScript字符串处理库(小结)
2020/06/01 Javascript
[03:07]【DOTA2亚洲邀请赛】我们,梦开始的地方
2017/03/07 DOTA
Python抓取Discuz!用户名脚本代码
2013/12/30 Python
Django Admin实现上传图片校验功能
2016/03/06 Python
Python通过RabbitMQ服务器实现交换机功能的实例教程
2016/06/29 Python
Python 登录网站详解及实例
2017/04/11 Python
深入理解Python爬虫代理池服务
2018/02/28 Python
Python实现获取系统临时目录及临时文件的方法示例
2019/06/26 Python
深入浅析Python 中的sklearn模型选择
2019/10/12 Python
Python字符串、列表、元组、字典、集合的补充实例详解
2019/12/20 Python
python如何判断IP地址合法性
2020/04/05 Python
BISSELL官网:北美吸尘器第一品牌
2019/03/14 全球购物
VC++笔试题
2014/10/13 面试题
一套比较完整的软件测试人员面试题
2012/05/13 面试题
食品安全处置方案
2014/06/14 职场文书
2015羊年春节慰问信
2015/02/14 职场文书
2015年小学语文教学工作总结
2015/05/25 职场文书