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 学习笔记(十四) 正则表达式
Jan 22 Javascript
Jquery 点击按钮显示和隐藏层的代码
Jul 25 Javascript
jQuery.clean使用方法及思路分析
Jan 07 Javascript
解析javascript 浏览器关闭事件
Jul 08 Javascript
jQuery函数的第二个参数获取指定上下文中的DOM元素
May 19 Javascript
jQuery实现表格行上下移动和置顶效果
Jun 05 Javascript
jQuery鼠标悬浮链接弹出跟随图片实例代码
Jan 08 Javascript
详解Vue2+Echarts实现多种图表数据可视化Dashboard(附源码)
Mar 21 Javascript
vue.js如何更改默认端口号8080为指定端口的方法
Jul 14 Javascript
js案例之鼠标跟随jquery版(实例讲解)
Jul 21 jQuery
原生JS写Ajax的请求函数功能
Dec 22 Javascript
webpack自动打包和热更新的实现方法
Jun 24 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防注
2007/01/15 PHP
php图片处理:加水印、缩略图的实现(自定义函数:watermark、thumbnail)
2010/12/02 PHP
在PHP上显示JFreechart画的统计图方法
2013/11/03 PHP
使用pthreads实现真正的PHP多线程(需PHP5.3以上版本)
2014/05/05 PHP
php实现批量压缩图片文件大小的脚本
2014/07/04 PHP
PHP文件及文件夹操作之创建、删除、移动、复制
2016/07/13 PHP
escape、encodeURI、encodeURIComponent等方法的区别比较
2006/12/27 Javascript
关于在IE下的一个安全BUG --可用于跟踪用户的系统鼠标位置
2013/04/17 Javascript
jquery拖动插件(jquery.drag)使用介绍
2013/06/18 Javascript
jQuery 借助插件Lavalamp实现导航条动态美化效果
2013/09/27 Javascript
JavaScript实现窗口抖动效果
2016/10/19 Javascript
JavaScript中如何使用cookie实现记住密码功能及cookie相关函数介绍
2016/11/10 Javascript
easyui关于validatebox实现多重规则验证的方法(必看)
2017/04/12 Javascript
Vue组件开发技巧总结
2018/03/04 Javascript
vue+Element-ui实现分页效果
2020/11/15 Javascript
[01:16:12]完美世界DOTA2联赛PWL S2 FTD vs Inki 第一场 11.21
2020/11/23 DOTA
在Python的Django框架中包装视图函数
2015/07/20 Python
python字典多键值及重复键值的使用方法(详解)
2016/10/31 Python
python利用拉链法实现字典方法示例
2017/03/25 Python
浅谈flask源码之请求过程
2018/07/26 Python
python+opencv 读取文件夹下的所有图像并批量保存ROI的方法
2019/01/10 Python
python3将变量写入SQL语句的实现方式
2020/03/02 Python
浅谈python量化 双均线策略(金叉死叉)
2020/06/03 Python
pycharm 关掉syntax检查操作
2020/06/09 Python
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2012/04/17 面试题
应届生程序员求职信
2013/11/05 职场文书
继电保护工岗位职责
2014/01/05 职场文书
老师给学生的表扬信
2014/01/17 职场文书
《一个中国孩子的呼声》教学反思
2014/02/12 职场文书
小区消防演习方案
2014/02/21 职场文书
导师推荐信范文
2014/05/09 职场文书
民主生活会整改措施(党员)
2014/09/18 职场文书
毕业生代领毕业材料的授权委托书
2014/09/29 职场文书
python-for x in range的用法(注意要点、细节)
2021/05/10 Python
redis实现的四种常见限流策略
2021/06/18 Redis
Java使用httpRequest+Jsoup爬取红蓝球号码
2021/07/02 Java/Android