【分享】IE 中一个对象的 native 方法是跟该对象绑定的

WebAdvocate 2010-09-14 05:06:53
加精
函数引用
对于获取一个元素的方式,最为常用的方式是 document 的方法 document.getElementById()。而 document.getElementById() 算是 document 的 native 方法。
获取元素的方法确实比较长,有两种方式可以缩短我们的调用代码:
//方式1
var $1 = function(id){
return document.getElementById(id);
};
//方式2var
$2 = document.getElementById;

定义以上变量后,可以简单的采用
$1(id);
$2(id)
;现在的问题是,$2 可用吗?为什么?

一个例子
<script type="text/javascript">
var pen={
color : "red",
getColor : function(){
return this.color;
}
}
var $ = pen.getColor;
alert(pen.getColor());
alert($());
</script>
这段例子中,采用了 $ 来代替函数 pen.getColor(),但通过测试我们可以知道,直接使用函数 $()无法正确的获得其颜色,为什么?
仔细观察后发现,原来 getColor() 函数其中使用 了 this 关键字,它指向当前调用对象。
所以,var $ = pen.getColor; 只是指向函数体,而没能复制它的上下文。$() 在执行的时候,this 相当于 window 对象。因为没有定义 window 的color 属性,也没有直接定义 color 变量,所以,$() 取出的是 undefined。
<script type="text/javascript">
var color="merge";
var pen={
color : "red",
getColor : function(){
return this.color;
}
}
var $ = pen.getColor;
alert(pen.getColor());
alert($());
</script>
加一个 color 变量,这时候,$() 会取出 “merge”。

联系
上面的例子和我们的问题有关系吗?
有。按道理讲,document.getElementById() 在执行的时候,上下文是 document,而 $2 在执行的时候,上下文是 window。
测试一下:
<!DOCTYPE html>
<div id="d1">Div Element</div>
<script type="text/javascript">
var $1 = function(id) {
return document.getElementById(id);
};
var $2 = document.getElementById;

alert($1('d1'));
alert($2('d1'));
</script>
其中的 $1 和 $2 是我们一开始定义的那两个变量。
IE 里的执行结果,又一次出乎了我们的意料。竟然成功的获取了元素。而其他浏览器中 $2(‘d1’) 是不能获取元素的。
看来,IE 中对元素的 native 方法做了某种绑定。

来自 W3Help 的在线实例:http://www.w3help.org/zh-cn/causes/S/D/9/005/dom_bom_native_method_bind.html

解决方法
使用方式1,即 $1 来保证方法在正确的上下文中执行。

原文
http://www.w3help.org/zh-cn/causes/SD9005

更多兼容性问题:
【分享】浏览器兼容性问题目录
...全文
8454 85 打赏 收藏 转发到动态 举报
写回复
用AI写文章
85 条回复
切换为时间正序
请发表友善的回复…
发表回复
yabo_ 2011-10-10
  • 打赏
  • 举报
回复
这个问题与IE无关, 单纯的javascript中this本身定义的问题.
因为javascript中function是一等公民, 不需要依赖其它对象存在(本身也是对象), 于是this便不再指向一个固定的对象了. this, 更准备的说法应该是执行上下文. 在经过.运算符调用时就是.前的对象, 不经过.调用, 就是全局对象window. 临时改变this, 使用call或者apply, 绑定this, 可以使用闭包保存固定对象,然后call或者apply.
zs0017 2010-11-01
  • 打赏
  • 举报
回复
ligendeai 2010-10-20
  • 打赏
  • 举报
回复
又学到了
WebAdvocate 2010-10-20
  • 打赏
  • 举报
回复
其实最近发现,这个还可以有更深层次的思考。

IE9 以前,IE的DOM实现是出于浏览器内核中的,而JScript出于浏览器之外,他们之间的通信是有windows系统的Com机制实现的。

这里,DOM方法存在于内核DOM内,this关键字则属于外部的 JScript 实现内,他们之间间隔着COM。
因此可以推测出,DOM方法内必然不能使用外部 JScript 实现内的 this 关键字,否则他们无法跨越COM。
这是IE9之前的浏览器设计模式决定的。

当IE9将 JScript 放入浏览器内核中后,这个问题就不存在了。具体表现应该与其他浏览器一致了。
etherdream 2010-09-26
  • 打赏
  • 举报
回复
哈哈。这个问题我以前研究过。只有ie才可以的。

所以最后还是老老实实的用return形式的。


随便说下,如果你的js支持gzip压缩传输的话,用最原始的方法无论是效率还是体积都是最好的,就是看着有点长。
flyhero82 2010-09-26
  • 打赏
  • 举报
回复
受教了~~~很好的教材~~
hjx_gb2000 2010-09-25
  • 打赏
  • 举报
回复
继续学习!
axiu336 2010-09-24
  • 打赏
  • 举报
回复
前面啰嗦了一点,但是平时真的没有注意,学了
munchie 2010-09-24
  • 打赏
  • 举报
回复
顶了不错不错还是不错
netehoney 2010-09-24
  • 打赏
  • 举报
回复
mark
tublit 2010-09-23
  • 打赏
  • 举报
回复
太好了 十分感谢!
学一点 2010-09-23
  • 打赏
  • 举报
回复
讲的不错,值得学习。
学一点 2010-09-23
  • 打赏
  • 举报
回复
值得学习
江南_CAO 2010-09-23
  • 打赏
  • 举报
回复
高手多多 谢谢分享
手机写程序 2010-09-23
  • 打赏
  • 举报
回复
学习下!
程序园苑 2010-09-23
  • 打赏
  • 举报
回复
路过,长见识
wzx303791528 2010-09-22
  • 打赏
  • 举报
回复
哈哈哈哈
van0215 2010-09-21
  • 打赏
  • 举报
回复
一直很好用自带的
dupengyan502490659 2010-09-21
  • 打赏
  • 举报
回复
有时间在好好琢磨
liju123456 2010-09-20
  • 打赏
  • 举报
回复
学习了aa
加载更多回复(57)

5,007

社区成员

发帖
与我相关
我的任务
社区描述
解读Web 标准、分析和讨论实际问题、推动网络标准化发展和跨浏览器开发进程,解决各种兼容性问题。
社区管理员
  • 跨浏览器开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧