一个对于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 相关文章推荐
手机平板等移动端适配跳转URL的js代码
Jan 25 Javascript
JS实现的竖向折叠菜单代码
Oct 21 Javascript
自定义vue全局组件use使用、vuex的使用详解
Jun 14 Javascript
JS实现匀加速与匀减速运动的方法示例
Sep 04 Javascript
javaScript字符串工具类StringUtils详解
Dec 08 Javascript
js判断输入框不能为空格或null值的实现方法
Mar 02 Javascript
Node.js爬取豆瓣数据实例分析
Mar 05 Javascript
vue如何解决循环引用组件报错的问题
Sep 22 Javascript
VUE解决微信签名及SPA微信invalid signature问题(完美处理)
Mar 29 Javascript
微信小程序实现手势滑动效果
Aug 26 Javascript
vue 子组件watch监听不到prop的解决
Aug 09 Javascript
vue3使用vuedraggable实现拖拽功能
Apr 06 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
PHP 设计模式之观察者模式介绍
2012/02/22 PHP
PHP简洁函数(PHP简单明了函数语法)
2012/06/10 PHP
Laravel框架创建路由的方法详解
2019/09/04 PHP
laravel解决迁移文件一次删除创建字段报错的问题
2019/10/24 PHP
picChange 图片切换特效的函数代码
2010/05/06 Javascript
关于可运行代码无法正常执行的使用说明
2010/05/13 Javascript
对xmlHttp对象的理解
2011/01/17 Javascript
jQuery编辑器KindEditor4.1.4代码高亮显示设置教程
2013/03/01 Javascript
appendChild() 或 insertBefore()使用与区别介绍
2013/10/11 Javascript
基于jQuery实现的图片切换焦点图整理
2014/12/07 Javascript
Javascript无参数和有参数类继承问题解决方法
2015/03/02 Javascript
JavaScript声明变量名的语法规则
2015/07/10 Javascript
js实现的黑背景灰色二级导航菜单效果代码
2015/08/24 Javascript
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
2016/06/12 Javascript
seajs学习教程之基础篇
2016/10/20 Javascript
easyui导出excel无法弹出下载框的快速解决方法
2016/11/10 Javascript
微信小程序 Tab页切换更新数据
2017/01/05 Javascript
详解vue前后台数据交互vue-resource文档
2017/07/19 Javascript
Vue数据监听方法watch的使用
2018/03/28 Javascript
解决微信小程序scroll-view组件无横向滚动的问题
2020/02/04 Javascript
vue项目实现多语言切换的思路
2020/09/17 Javascript
Python单体模式的几种常见实现方法详解
2017/07/28 Python
Python3实战之爬虫抓取网易云音乐的热门评论
2017/10/09 Python
python opencv实现运动检测
2018/07/10 Python
Face++ API实现手势识别系统设计
2018/11/21 Python
python在OpenCV里实现投影变换效果
2019/08/30 Python
手把手教你用纯css3实现轮播图效果实例
2017/05/04 HTML / CSS
HTML5中input[type='date']自定义样式与日历校验功能的实现代码
2017/07/11 HTML / CSS
介绍一下JMS编程步骤
2015/09/22 面试题
幼儿园法制宣传日活动总结
2014/11/01 职场文书
教师先进事迹材料
2014/12/16 职场文书
乡镇司法所2015年度工作总结
2015/10/14 职场文书
HAM-2000摩机图
2021/04/22 无线电
JavaWeb 入门篇:创建Web项目,Idea配置tomcat
2021/07/16 Java/Android
Redis实现主从复制方式(Master&Slave)
2022/06/21 Redis
windows系统搭建WEB服务器详细教程
2022/08/05 Servers