一个对于js this关键字的问题


Posted in Javascript onJanuary 09, 2007

所以拿出来与大家共勉:
先运行以下的js代码
<script>
foo = {
 'bar': function () {
 alert(this);
 },
 'toString': function () {
 return 'foo';
 }
};
foo.bar();//返回的是"foo"
(foo.bar)();//返回的是"[object Window]"
(foo.bar || null)();//返回的是"[object Window]"
bar = foo.bar; bar();//返回的是"[object Window]"
</script>

我对这里的代码的解释:

foo.bar(); //打印foo
//1. alert隐式调用toString方法,转型成字符串,在foo里重写了toString方法,因此为foo

(foo.bar)();//打印foo
//2. 这里的执行同上

(foo.bar || null)();
/*
3. 这里在IE6.0,Mozilla Firefox1.5.0.7和Opera9.0里有不同的效果,IE和Opera都是object,Mozilla的为foo
暂且不谈这几个的JS对||的解释方法,这与bar方法中的this还有和||运算符是有关的。经过||之后
这里的this已经不再为window了,this关键字的作用,如果按照C++的理解,应该为动态联编,而非静态联编,我们平常的例子中
<script>
(function (){
this.div = document.createElement("div");div.innerHTML="never-online";
document.body.appendChild(div);
 this.div.onclick = function(){
 alert(this.tagName);//这里的this就是div而非匿名函数中的this
 }
})()
</script>
也就是说,这里this的作用域不再是foo对象,而是一个全局的作用域。因此alert(this)相当于alert(window);
所以为object

BTW:有可能是||运算符是要把两个表达式的执行转换为全局范围的比较,所以在IE和Opera中,这里(foo.bar || null)返回的是一个全局引用,即:
 'bar': function () {
 alert(this);//这里的this已经为全局this,全局的this,即为window
 },
详细的,我将在篇末加入一段代码,以示说明
*/

bar = foo.bar; bar();//返回的是"[object Window]"
/*4. 
这里在IE6.0,Mozilla Firefox1.5.0.7和Opera9.0里都为相同的object,如果理解上面的执行,理解这句显然会比较简单
理由同上,这里把foo.bar的引用给到一个全局变量bar,而全局变量都隶属于window的引用,看下面代码:
var a = 'never-online';
alert(this.a); //never-online
alert(window.a); //never-online
如果你尝试着把bar = foo.bar; bar();改成以下代码,或许就可以明白了
foo.alert = foo.bar; foo.alert ();
这里的foo.alert依然为foo对象的引用,因此foo对象里的this,在这里依然有效,并没有成为window object
因为很明显的bar属性window,因此引用foo.bar里虽然有this,但是this引用为window
*/

再看看我们把这个例子改成这样:
<script>
foo = {
 'bar': function () {
 var oSelf = this;
 alert(this.toString);
 if (oSelf==window) {
 oSelf = foo;
 }
 alert(oSelf);
 },
 'toString': function () {
 return 'foo';
 }
};

window.toString = function () {
 alert("引用全局this --- window");
}

foo.bar();
(foo.bar)();
(foo.bar || null)();
bar = foo.bar; bar();
</script>

这样应该明白原因了。

从这个例中(foo.bar || null)(); 可以看出Mozilla的解释器会更“标准”一些,而Opera和IE的解释方法则与Mozilla的不一样。||运算符的作用,出现了不同的效果。同我上面所说的, 有可能是||运算符是要把两个表达式的执行转换为全局范围的比较,所以在IE和Opera中,这里(foo.bar || null)返回的是一个全局引用 

Javascript 相关文章推荐
prototype Element学习笔记(篇二)
Oct 26 Javascript
JavaScript 无符号右移赋值操作
Apr 17 Javascript
40个有创意的jQuery图片和内容滑动及弹出插件收藏集之三
Jan 03 Javascript
捕获浏览器关闭、刷新事件不同情况下的处理方法
Jun 02 Javascript
通过js简单实现将一个文本内容转译成加密文本
Oct 22 Javascript
select多选 multiple的使用示例
Jun 16 Javascript
javascript设置和获取cookie的方法实例详解
Jan 05 Javascript
jQuery实现图片局部放大镜效果
Mar 17 Javascript
JavaScript 数组some()和filter()的用法及区别
May 20 Javascript
AngularJS 入门教程之HTML DOM实例详解
Jul 28 Javascript
jQuery-ui插件sortable实现自由拖动排序
Dec 01 jQuery
es6函数之箭头函数用法实例详解
Apr 25 Javascript
JS控件autocomplete 0.11演示及下载 1月5日已更新
Jan 09 #Javascript
根据分辩率调用不同的CSS.
Jan 08 #Javascript
如何用javascript判断录入的日期是否合法
Jan 08 #Javascript
[IE&amp;FireFox兼容]JS对select操作
Jan 07 #Javascript
javascript中的对象和数组的应用技巧
Jan 07 #Javascript
JavaScript For Beginners(转载)
Jan 05 #Javascript
JavaScript的目的分析
Jan 05 #Javascript
You might like
PHP Squid中可缓存的动态网页设计
2008/09/17 PHP
安装apache2.2.22配置php5.4(具体操作步骤)
2013/06/26 PHP
一个js写的日历(代码部分网摘)
2009/09/20 Javascript
JavaScript 变量作用域分析
2011/07/04 Javascript
JavaScript中的变量声明早于赋值分析
2012/03/01 Javascript
FireBug 调试JS入门教程 如何调试JS
2013/12/23 Javascript
setInterval与clearInterval的使用示例代码
2014/01/28 Javascript
JS实现仿百度输入框自动匹配功能的示例代码
2014/02/19 Javascript
jquery中each方法示例和常用选择器
2014/07/08 Javascript
js判断当页面无法回退时关闭网页否则就history.go(-1)
2014/08/07 Javascript
JavaScript中的比较操作符&gt;、=、
2014/12/31 Javascript
浅谈时钟的生成(js手写简洁代码)
2016/08/20 Javascript
AngularJS 单元测试(二)详解
2016/09/21 Javascript
JavaScript 数组的进化与性能分析
2017/09/18 Javascript
JS实现十字坐标跟随鼠标效果
2017/12/25 Javascript
js前端面试之同步与异步问题详解
2019/04/03 Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
2019/05/08 Javascript
使用Python判断IP地址合法性的方法实例
2014/03/13 Python
python生成随机mac地址的方法
2015/03/16 Python
Python实现在线程里运行scrapy的方法
2015/04/07 Python
Python复制文件操作实例详解
2015/11/10 Python
python3使用requests模块爬取页面内容的实战演练
2017/09/25 Python
python 并发编程 多路复用IO模型详解
2019/08/20 Python
Python reversed反转序列并生成可迭代对象
2020/10/22 Python
使用Html5 Stream开发实时监控系统
2020/06/02 HTML / CSS
英国可持续奢侈品包包品牌:Elvis & Kresse
2018/08/05 全球购物
机电一体化大学生求职信
2013/11/08 职场文书
医学专业毕业生个人求职信
2013/12/25 职场文书
教师个人教学总结
2015/02/11 职场文书
市级三好生竞选稿
2015/11/21 职场文书
幼儿园教师教学反思
2016/03/02 职场文书
关于党风廉政建设宣传教育月的活动总结!
2019/08/08 职场文书
SQLServer2008提示评估期已过解决方案
2021/04/12 SQL Server
python必学知识之文件操作(建议收藏)
2021/05/30 Python
Java基础之详解HashSet的使用方法
2021/06/30 Java/Android
Python实现仓库管理系统
2022/05/30 Python