一个对于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 相关文章推荐
jQuery1.3.2 升级到jQuery1.4.4需要修改的地方
Jan 06 Javascript
JSON.parse()和JSON.stringify()使用介绍
Jun 20 Javascript
jQuery 中$(this).index与$.each的使用指南
Nov 20 Javascript
基于javascript实现的搜索时自动提示功能
Dec 26 Javascript
JS实现简单路由器功能的方法
May 27 Javascript
JS组件Bootstrap Table表格行拖拽效果实现代码
Aug 27 Javascript
Web程序员必备的7个JavaScript函数
Jun 14 Javascript
微信小程序之ES6与事项助手的功能实现
Nov 30 Javascript
详解angularJs指令的3种绑定策略
Apr 13 Javascript
jQuery实现动态添加、删除按钮及input输入框的方法
Apr 27 jQuery
解决JS内存泄露之js对象和dom对象互相引用问题
Jun 25 Javascript
jQuery中使用validate插件校验表单功能
May 24 jQuery
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处理后端&amp;接口访问超时的解决方法
2016/10/29 PHP
PHP构造二叉树算法示例
2017/06/21 PHP
简单谈谈PHP面向对象之标识对象
2017/06/27 PHP
php 删除一维数组中某一个值元素的操作方法
2018/02/01 PHP
抽出www.templatemonster.com的鼠标悬停加载大图模板的代码
2007/07/11 Javascript
js 模拟实现类似c#下的hashtable的简单功能代码
2010/01/24 Javascript
JavaScript自定义DateDiff函数(兼容所有浏览器)
2012/03/01 Javascript
js确认删除对话框效果的示例代码
2014/02/20 Javascript
JQuery EasyUI 日期控件如何控制日期选择区间
2014/05/05 Javascript
使用jquery解析XML的方法
2014/09/05 Javascript
jQuery使用before()和after()在元素前后添加内容的方法
2015/03/26 Javascript
基于JavaScript 性能优化技巧心得(分享)
2017/12/11 Javascript
js数组常用最重要的方法
2018/02/04 Javascript
Node.js学习之内置模块fs用法示例
2020/01/22 Javascript
vue实现户籍管理系统
2020/05/29 Javascript
vue实现tab栏点击高亮效果
2020/08/19 Javascript
Nuxt.js nuxt-link与router-link的区别说明
2020/11/06 Javascript
[54:08]LGD女子刀塔学院 DOTA2炼金术士教学
2014/01/09 DOTA
[01:17:12]职来职往完美电竞专场
2014/09/18 DOTA
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
使用Python发送各种形式的邮件的方法汇总
2015/11/09 Python
教大家使用Python SqlAlchemy
2016/02/12 Python
浅谈Python2.6和Python3.0中八进制数字表示的区别
2017/04/28 Python
Python subprocess库的使用详解
2018/10/26 Python
python3下载抖音视频的完整代码
2019/06/05 Python
网易有道2017内推编程题 洗牌(python)
2019/06/19 Python
python调用Matplotlib绘制分布点图
2019/10/18 Python
python logging设置level失败的解决方法
2020/02/19 Python
Python 通过正则表达式快速获取电影的下载地址
2020/08/17 Python
python学习之使用Matplotlib画实时的动态折线图的示例代码
2021/02/25 Python
python实现简单文件读写函数
2021/02/25 Python
美国最大的在线水培用品商店:GrowersHouse.com
2018/08/14 全球购物
大众服装店创业计划书范文
2014/01/01 职场文书
中职生自荐信范文
2014/06/15 职场文书
学校开学标语
2014/10/06 职场文书
python3使用diagrams绘制架构图的步骤
2021/04/08 Python