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 相关文章推荐
JavaScript 学习笔记(十三)Dom创建表格
Jan 21 Javascript
Asp.net下利用Jquery Ajax实现用户注册检测(验证用户名是否存)
Sep 12 Javascript
通过Jquery遍历Json的两种数据结构的实现代码
Jan 19 Javascript
jQuery实现动画效果的实例代码
May 07 Javascript
纯JS实现动态时间显示代码
Feb 08 Javascript
关于javaScript注册click事件传递参数的不成功问题
Jul 18 Javascript
javascript制作网页图片上实现下雨效果
Feb 26 Javascript
php利用curl获取远程图片实现方法
Oct 26 Javascript
jQuery和JavaScript节点插入元素的方法对比
Nov 18 Javascript
Underscore之Array_动力节点Java学院整理
Jul 10 Javascript
Vue+Element实现表格编辑、删除、以及新增行的最优方法
May 28 Javascript
js实现淘宝浏览商品放大镜功能
Oct 28 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
一个显示天气预报的程序
2006/10/09 PHP
PHP可变函数的使用详解
2013/06/14 PHP
PHP+MySQL统计该库中每个表的记录数并按递减顺序排列的方法
2016/02/15 PHP
PHP5.6读写excel表格文件操作示例
2019/02/26 PHP
Alliance vs Liquid BO3 第一场2.13
2021/03/10 DOTA
javascript 图片裁剪技巧解读
2012/11/15 Javascript
解析prototype,JQuery中跳出each循环的方法
2013/12/12 Javascript
JS脚本defer的作用示例介绍
2014/01/02 Javascript
javascript动态创建表格及添加数据实例详解
2015/05/13 Javascript
如何使用jQuery技术开发ios风格的页面导航菜单
2015/07/29 Javascript
JavaScript中的定时器之Item23的合理使用
2015/10/30 Javascript
js数组去重的5种算法实现
2015/11/04 Javascript
聊一聊JavaScript作用域和作用域链
2016/05/03 Javascript
webuploader模态框ueditor显示问题解决方法
2016/12/27 Javascript
AngulaJS路由 ui-router 传参实例
2017/04/28 Javascript
微信小程序template模板实例详解
2017/10/27 Javascript
CheckBox多选取值及判断CheckBox选中是否为空的实例
2017/10/31 Javascript
JavaScript继承与多继承实例分析
2018/05/26 Javascript
QRCode.js二维码生成并能长按识别
2018/10/16 Javascript
webpack4.x CommonJS模块化浅析
2018/11/09 Javascript
Node.js API详解之 V8模块用法实例分析
2020/06/05 Javascript
js实现3D旋转效果
2020/08/18 Javascript
[41:56]Spirit vs Liquid Supermajor小组赛A组 BO3 第一场 6.2
2018/06/03 DOTA
[01:11:46]DOTA2-DPC中国联赛 正赛 iG vs Magma BO3 第一场 2月23日
2021/03/11 DOTA
python win32 简单操作方法
2017/05/25 Python
[原创]使用豆瓣提供的国内pypi源
2017/07/02 Python
Python cookbook(数据结构与算法)让字典保持有序的方法
2018/02/18 Python
Python爬虫实战:分析《战狼2》豆瓣影评
2018/03/26 Python
pandas DataFrame 根据多列的值做判断,生成新的列值实例
2018/05/18 Python
详解python 模拟豆瓣登录(豆瓣6.0)
2019/04/18 Python
python virtualenv虚拟环境配置与使用教程详解
2020/07/13 Python
迪梵英国官方网站:Darphin英国
2017/12/06 全球购物
小橄榄树:Le Petit Olivier
2018/04/23 全球购物
放假通知范文
2015/04/14 职场文书
工作年限证明范本
2015/06/15 职场文书
vue @ ~ 相对路径 路径别名设置方式
2022/06/05 Vue.js