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 相关文章推荐
用showModalDialog弹出页面后,提交表单总是弹出一个新窗口
Jul 18 Javascript
Javascript继承(上)——对象构建介绍
Nov 08 Javascript
JavaScript的strict模式与with关键字介绍
Feb 08 Javascript
jquery复选框checkbox实现删除前判断
Apr 20 Javascript
js实现每日自动换一张图片的方法
May 04 Javascript
Node调用Java的示例代码
Sep 20 Javascript
JS使用贪心算法解决找零问题示例
Nov 27 Javascript
vue+iview+less+echarts实战项目总结
Feb 22 Javascript
微信小程序 select 下拉框组件功能
Sep 09 Javascript
Vue中Table组件行内右键菜单实现方法(基于 vue + AntDesign)
Nov 21 Javascript
解决vue+ element ui 表单验证有值但验证失败问题
Jan 16 Javascript
Vue-Ant Design Vue-普通及自定义校验实例
Oct 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关联链接常用代码
2012/11/05 PHP
php获得用户ip地址的比较不错的方法
2014/02/08 PHP
PHP使用FFmpeg获取视频播放总时长与码率等信息
2016/09/13 PHP
PHPMailer ThinkPHP实现自动发送邮件功能
2018/06/10 PHP
tp5(thinkPHP5)框架数据库Db增删改查常见操作总结
2019/01/10 PHP
Laravel框架下载,安装及路由操作图文详解
2019/12/04 PHP
js设置组合快捷键/tabindex功能的方法
2013/11/21 Javascript
开源的javascript项目Kissy介绍
2014/11/28 Javascript
javascript实现日期按月份加减
2015/05/15 Javascript
jQuery实现HTML表格单元格的合并功能
2016/04/06 Javascript
JavaScript String 对象常用方法详解
2016/05/13 Javascript
JS实现延迟隐藏功能的方法(类似QQ头像鼠标放上展示信息)
2017/12/28 Javascript
javascript用rem来做响应式开发
2018/01/13 Javascript
JavaScript模板引擎应用场景及实现原理详解
2018/12/14 Javascript
vue使用prop可以渲染但是打印台报错的解决方式
2019/11/13 Javascript
详解webpack的clean-webpack-plugin插件报错
2020/10/16 Javascript
[47:55]Ti4第二日主赛事败者组 NaVi vs EG 1
2014/07/20 DOTA
Python中的对象,方法,类,实例,函数用法分析
2015/01/15 Python
浅谈django中的认证与登录
2016/10/31 Python
python 系统调用的实例详解
2017/07/11 Python
使用python对文件中的单词进行提取的方法示例
2018/12/21 Python
python3实现逐字输出的方法
2019/01/23 Python
Python中使用遍历在列表中添加字典遇到的坑
2019/02/27 Python
python3对拉勾数据进行可视化分析的方法详解
2019/04/03 Python
Python读写文件模式和文件对象方法实例详解
2019/09/17 Python
python之yield和Generator深入解析
2019/09/18 Python
opencv中图像叠加/图像融合/按位操作的实现
2020/04/01 Python
python zip,lambda,map函数代码实例
2020/04/04 Python
Django QuerySet查询集原理及代码实例
2020/06/13 Python
python利用os模块编写文件复制功能——copy()函数用法
2020/07/13 Python
Python利用imshow制作自定义渐变填充柱状图(colorbar)
2020/12/10 Python
python 实现Harris角点检测算法
2020/12/11 Python
四年级学生期末评语
2014/12/26 职场文书
2015年煤矿安全工作总结
2015/05/23 职场文书
技术入股合作协议书
2016/03/21 职场文书
nginx前后端同域名配置的方法实现
2021/03/31 Servers