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实现页面定时跳转总结篇
Sep 21 Javascript
JavaScript函数获取事件源的小例子
May 14 Javascript
Grunt入门教程(自动任务运行器)
Aug 06 Javascript
深入理解JavaScript 函数
Jun 06 Javascript
JavaScript获取当前url根目录(路径)
Jun 17 Javascript
浅谈bootstrap使用中的一些问题以及解决过程
Oct 18 Javascript
JQuery Ajax WebService传递参数的简单实例
Nov 02 Javascript
基于jQuery的select下拉框选择触发事件实例分析
Nov 18 Javascript
JavaScript for循环 if判断语句(学习笔记)
Oct 11 Javascript
vuex state中的数组变化监听实例
Nov 06 Javascript
微信小程序开发搜索功能实现(前端+后端+数据库)
Mar 04 Javascript
Vue解决移动端弹窗滚动穿透问题
Dec 15 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文件上传的例子及参数详解
2013/12/12 PHP
php读取csv实现csv文件下载功能
2013/12/18 PHP
PHP中使用匿名函数操作数据库的例子
2014/11/17 PHP
Zend Framework入门知识点小结
2016/03/19 PHP
php 多文件上传的实现实例
2016/10/23 PHP
DHTML 中的绝对定位
2006/11/26 Javascript
jquery select操作的日期联动实现代码
2009/12/06 Javascript
js 实现打印网页中定义的部分内容的代码
2010/04/01 Javascript
xss文件页面内容读取(解决)
2010/11/28 Javascript
uploadify 3.0 详细使用说明
2012/06/18 Javascript
JS中Iframe之间传值的方法
2013/03/11 Javascript
高效率JavaScript编写技巧整理
2013/08/23 Javascript
jQuery 实现侧边浮动导航菜单效果
2014/12/26 Javascript
JS+DIV+CSS实现仿表单下拉列表效果
2015/08/18 Javascript
jQuery实现鼠标悬停背景翻转的黑色导航菜单代码
2015/09/14 Javascript
jQuery实现批量判断表单中文本框非空的方法(2种方法)
2015/12/09 Javascript
JSONP和批量操作功能的实现方法
2016/08/21 Javascript
基于JavaScript实现鼠标向下滑动加载div的代码
2016/08/31 Javascript
前端 Vue.js 和 MVVM 详细介绍
2016/12/29 Javascript
JavaScript之解构赋值的理解
2019/01/30 Javascript
JS利用prototype给类添加方法操作详解
2019/06/21 Javascript
[01:13:51]TNC vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python库urllib与urllib2主要区别分析
2014/07/13 Python
Python使用pyodbc访问数据库操作方法详解
2018/07/05 Python
python散点图实例之随机漫步
2018/08/27 Python
Django 路由系统URLconf的使用
2018/10/11 Python
pycharm执行python时,填写参数的方法
2018/10/29 Python
python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)
2020/12/03 Python
JBL澳大利亚官方商店:扬声器、耳机和音响系统
2018/05/24 全球购物
高中生职业生涯规划书
2014/02/24 职场文书
党风廉设责任书
2014/04/16 职场文书
优质服务活动实施方案
2014/05/02 职场文书
党的群众路线整改落实情况汇报
2014/10/28 职场文书
消防安全培训工作总结
2015/10/23 职场文书
spring cloud 配置中心native配置方式
2021/09/25 Java/Android
JS前端使用Canvas快速实现手势解锁特效
2022/09/23 Javascript