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实现自定义标签
May 08 Javascript
Jquery 基础学习笔记
May 29 Javascript
为jQuery.Treeview添加右键菜单的实现代码
Oct 22 Javascript
js TextArea的选中区域处理
Dec 28 Javascript
关于onchange事件在IE和FF下的表现及解决方法
Mar 08 Javascript
一个简单的Node.js异步操作管理器分享
Apr 29 Javascript
angularJS 中$scope方法使用指南
Feb 09 Javascript
AngularJS动态生成div的ID源码解析
Aug 29 Javascript
Angularjs 动态改变title标题(兼容ios)
Dec 29 Javascript
用户管理的设计_jquery的ajax实现二级联动效果
Jul 13 jQuery
vue中实现移动端的scroll滚动方法
Mar 03 Javascript
Vue使用Canvas绘制图片、矩形、线条、文字,下载图片
Apr 26 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
PHPWind 发帖回帖Api PHP版打包下载
2010/02/08 PHP
PHP对接微信公众平台消息接口开发流程教程
2014/03/25 PHP
PHP实现文件下载【实例分享】
2017/04/28 PHP
PHP多线程模拟实现秒杀抢单
2018/02/07 PHP
php使用filter_var函数判断邮箱,url,ip格式示例
2019/07/06 PHP
js 操作css实现代码
2009/06/11 Javascript
javascript针对DOM的应用实例(一)
2012/04/15 Javascript
基于JQuery实现滚动到页面底端时自动加载更多信息
2014/01/31 Javascript
display和visibility的区别示例介绍
2014/02/26 Javascript
javascript结合CSS实现苹果开关按钮特效
2015/04/07 Javascript
js实现漂浮回顶部按钮实例
2015/05/06 Javascript
JavaScript统计字符串中每个字符出现次数完整实例
2016/01/28 Javascript
react.js 翻页插件实例代码
2017/01/19 Javascript
Bootstrap常用组件学习(整理)
2017/03/24 Javascript
Vue原理剖析 实现双向绑定MVVM
2017/05/03 Javascript
jQuery Form插件使用详解_动力节点Java学院整理
2017/07/17 jQuery
JavaScript EventEmitter 背后的秘密 完整版
2018/03/29 Javascript
详解Angular路由之路由守卫
2018/05/10 Javascript
微信小程序实现tab页面切换功能
2018/07/13 Javascript
ES6如何用一句代码实现函数的柯里化
2020/01/18 Javascript
js+html+css实现手动轮播和自动轮播
2020/12/30 Javascript
vue.js实现点击图标放大离开时缩小的代码
2021/01/27 Vue.js
python中wx将图标显示在右下角的脚本代码
2013/03/08 Python
python获取局域网占带宽最大3个ip的方法
2015/07/09 Python
python 文件操作删除某行的实例
2017/09/04 Python
Python实现的十进制小数与二进制小数相互转换功能
2017/10/12 Python
解决python大批量读写.doc文件的问题
2018/05/08 Python
Python之批量创建文件的实例讲解
2018/05/10 Python
Python if语句知识点用法总结
2018/06/10 Python
pygame游戏之旅 添加碰撞效果的方法
2018/11/20 Python
美国知名的网上鞋类及相关服装零售商:Shoes.com
2017/05/06 全球购物
销售代理协议书
2014/09/30 职场文书
2014年医院后勤工作总结
2014/12/06 职场文书
2015元旦主持词开场白和结束语
2014/12/14 职场文书
MongoDB数据库部署环境准备及使用介绍
2022/03/21 MongoDB
MySQL实现用逗号进行拼接、以逗号进行分割
2022/12/24 MySQL