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 相关文章推荐
ASP.NET中使用后端代码注册脚本 生成JQUERY-EASYUI的界面错位的解决方法
Jun 12 Javascript
chrome原生方法之数组
Nov 30 Javascript
javascript学习笔记(一) 在html中使用javascript
Jun 18 Javascript
Extjs中的GridPanel隐藏列会显示在menuDisabled中解决方法
Jan 27 Javascript
js实现正方形颜色从下往上升的效果
Aug 04 Javascript
JS实现图片产生波纹一样flash效果的方法
Feb 27 Javascript
JavaScript代码因逗号不规范导致IE不兼容的问题
Feb 25 Javascript
Node.js 应用跑得更快 10 个技巧
Apr 03 Javascript
jQuery中animate的几种用法与注意事项
Dec 12 Javascript
用node-webkit把web应用打包成桌面应用(windows环境)
Feb 01 Javascript
axios发送post请求springMVC接收不到参数的解决方法
Mar 05 Javascript
Postman动态获取返回值过程详解
Jun 30 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
2020年4月放送决定!第2期TV动画《邪神酱飞踢》视觉图&主题曲情报公开!
2020/03/06 日漫
PHP自动生成月历代码
2006/10/09 PHP
PHP fopen 读取带中文URL地址的一点见解
2012/09/25 PHP
PHP资源管理框架Assetic简介
2014/06/12 PHP
PHP判断一个gif图片是否为动态图片的方法
2014/11/19 PHP
php基于Snoopy解析网页html的方法
2015/07/09 PHP
php基于闭包实现函数的自调用(递归)实例分析
2016/11/11 PHP
利用Laravel事件系统如何实现登录日志的记录详解
2017/05/20 PHP
PHP判断密码强度的方法详解
2017/05/26 PHP
Laravel中如何轻松容易的输出完整的SQL语句
2020/07/26 PHP
jquery简单体验
2007/01/10 Javascript
javascript 常用代码技巧大收集
2009/02/25 Javascript
javascript中的undefined和not defined区别示例介绍
2014/02/26 Javascript
jQuery之ajax删除详解
2014/02/27 Javascript
深入理解Javascript里的依赖注入
2014/03/19 Javascript
用jquery仿做发微博功能示例
2014/04/18 Javascript
jQuery通过Ajax返回JSON数据
2015/04/28 Javascript
javascript实现类似百度分享功能的方法
2015/07/27 Javascript
基于jquery实现弹幕效果
2016/09/29 Javascript
AngularJS验证信息框架的封装插件用法【w5cValidator扩展插件】
2016/11/03 Javascript
js实现导航栏中英文切换效果
2017/01/16 Javascript
jQuery内容筛选选择器实例代码
2017/02/06 Javascript
JavaScript如何对图片进行黑白化
2018/04/10 Javascript
vue better scroll 无法滚动的解决方法
2018/06/07 Javascript
JavaScript中变量、指针和引用功能与操作示例
2018/08/04 Javascript
Vue多选列表组件深入详解
2021/03/02 Vue.js
Python基于动态规划算法解决01背包问题实例
2017/12/06 Python
Python+request+unittest实现接口测试框架集成实例
2018/03/16 Python
PyQt5每天必学之QSplitter实现窗口分隔
2018/04/19 Python
浅谈Pandas 排序之后索引的问题
2018/06/07 Python
python selenium 弹出框处理的实现
2019/02/26 Python
python 绘制拟合曲线并加指定点标识的实现
2019/07/10 Python
python实现将json多行数据传入到mysql中使用
2019/12/31 Python
日本最大的彩色隐形眼镜销售网站:CharmColor
2020/09/09 全球购物
2014年反腐倡廉工作总结
2014/12/05 职场文书
小学三年级数学教学反思
2016/02/16 职场文书