一个对于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 相关文章推荐
JQuery获取或设置ckeditor的数据(示例代码)
Nov 15 Javascript
js中的onchange和onpropertychange (onchange无效的解决方法)
Mar 08 Javascript
JavaScript控制各种浏览器全屏模式的方法、属性和事件介绍
Apr 03 Javascript
js实现完全自定义可带多级目录的网页鼠标右键菜单方法
Feb 28 Javascript
jQuery中$.extend()用法实例
Jun 24 Javascript
第一章之初识Bootstrap
Apr 25 Javascript
jquery 判断selection range 是否在容器中的简单实例
Aug 02 Javascript
获取url中用&amp;隔开的参数实例(分享)
May 28 Javascript
vue.js实现插入数值与表达式的方法分析
Jul 06 Javascript
js实现简单的贪吃蛇游戏
Apr 23 Javascript
解决vue项目打包上服务器显示404错误,本地没出错的问题
Nov 03 Javascript
Vuex实现简单购物车
Jan 10 Vue.js
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
如何删除多级目录
2006/10/09 PHP
php生成扇形比例图实例
2013/11/06 PHP
PHP中$_FILES的使用方法及注意事项说明
2014/02/14 PHP
php统计文章排行示例
2014/03/04 PHP
PHP中使用TCPDF生成PDF文档实例
2014/07/01 PHP
PHP使用socket发送HTTP请求的方法
2016/02/14 PHP
java模拟PHP的pack和unpack类
2016/04/13 PHP
Yii2.0 Basic代码中路由链接被转义的处理方法
2016/09/21 PHP
Laravel 微信小程序后端搭建步骤详解
2019/11/26 PHP
Javascript 面向对象 重载
2010/05/13 Javascript
关于COOKIE个数与大小的问题
2011/01/17 Javascript
jquery 查找iframe父级页面元素的实现代码
2011/08/28 Javascript
JavaScript字符串String和Array操作的有趣方法
2012/12/18 Javascript
Javascript中的五种数据类型详解
2014/12/26 Javascript
jQuery ajaxSubmit 实现ajax提交表单局部刷新
2016/07/04 Javascript
基于pako.js实现gzip的压缩和解压功能示例
2017/06/13 Javascript
详解node-ccap模块生成captcha验证码
2017/07/01 Javascript
vue实现文字加密功能
2019/09/27 Javascript
基于JavaScript实现轮播图效果
2021/01/02 Javascript
[01:12]DOTA2 2015年秋季互动指南
2015/11/10 DOTA
python实现颜色空间转换程序(Tkinter)
2015/12/31 Python
使用Nginx+uWsgi实现Python的Django框架站点动静分离
2016/03/21 Python
对python中raw_input()和input()的用法详解
2018/04/22 Python
Python类装饰器实现方法详解
2018/12/21 Python
django如何实现视图重定向
2019/07/24 Python
Python如何通过百度翻译API实现翻译功能
2020/04/02 Python
Pycharm常用快捷键总结及配置方法
2020/11/14 Python
prAna官网:瑜伽、旅行和冒险服装
2019/03/10 全球购物
办护照工作证明范本
2014/01/14 职场文书
工作过失检讨书
2014/02/23 职场文书
2014年党建工作总结
2014/11/11 职场文书
廉洁自律个人总结
2015/02/14 职场文书
个人总结与自我评价2015
2015/03/11 职场文书
mysql知识点整理
2021/04/05 MySQL
Python使用psutil库对系统数据进行采集监控的方法
2021/08/23 Python
Java中try catch处理异常示例
2021/12/06 Java/Android