一个对于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 相关文章推荐
JavaScript中switch判断容易犯错的一个细节
Aug 27 Javascript
javascript的BOM
May 03 Javascript
javascript Promise简单学习使用方法小结
May 17 Javascript
Vue.js学习之过滤器详解
Jan 22 Javascript
ionic2打包android时gradle无法下载的解决方法
Apr 05 Javascript
使用vue2实现购物车和地址选配功能
Mar 29 Javascript
微信小程序修改swiper默认指示器样式的实例代码
Jul 18 Javascript
JavaScript常用工具方法封装
Feb 12 Javascript
vue路由--网站导航功能详解
Mar 29 Javascript
基于vue框架手写一个notify插件实现通知功能的方法
Mar 31 Javascript
layui对工具条进行选择性的显示方法
Sep 19 Javascript
html+vue.js 实现漂亮分页功能可兼容IE
Nov 07 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
桌面中心(三)修改数据库
2006/10/09 PHP
PHP中运用jQuery的Ajax跨域调用实现代码
2012/02/21 PHP
PHP中浮点数计算比较及取整不准确的解决方法
2015/01/09 PHP
PHP获取昨天、今天及明天日期的方法
2016/02/03 PHP
php中如何执行linux命令详解
2018/11/06 PHP
Laravel 队列使用的实现
2019/01/08 PHP
利用js获取服务器时间的两个简单方法
2010/01/08 Javascript
JS对外部文件的加载及对IFRMAME的加载的实现,当加载完成后,指定指向方法(方法回调)
2011/07/04 Javascript
AJAX跨域请求json数据的实现方法
2013/11/11 Javascript
JQuery each打印JS对象的方法
2013/11/13 Javascript
jQuery实现table隔行换色和鼠标经过变色的两种方法
2014/06/15 Javascript
Jquery ajax加载等待执行结束再继续执行下面代码操作
2015/11/24 Javascript
jQuery中实现prop()函数控制多选框(全选,反选)
2016/08/19 Javascript
JavaScript的new date等日期函数在safari中遇到的坑
2016/10/24 Javascript
Nodejs进阶:如何将图片转成datauri嵌入到网页中去实例
2016/11/21 NodeJs
easyui-datagrid特殊字符不能显示的处理方法
2017/04/12 Javascript
vue与django集成打包的实现方法
2019/11/11 Javascript
理解Python中的With语句
2016/03/18 Python
Django重装mysql后启动报错:No module named ‘MySQLdb’的解决方法
2018/04/22 Python
对python 匹配字符串开头和结尾的方法详解
2018/10/27 Python
Python通过cv2读取多个USB摄像头
2019/08/28 Python
python脚本之一键移动自定格式文件方法实例
2019/09/02 Python
Python模块汇总(常用第三方库)
2019/10/07 Python
Python实例教程之检索输出月份日历表
2020/12/16 Python
利用css3制作3D样式按钮实现代码
2013/03/18 HTML / CSS
英国办公用品商店:Office Outlet
2018/04/04 全球购物
Java方面的关于数组和继承的笔面试题
2015/09/18 面试题
路政管理专业个人自荐信范文
2013/11/30 职场文书
大学生写自荐信的技巧
2014/01/08 职场文书
家长通知书家长评语
2014/04/17 职场文书
应届大学生自荐书
2014/06/17 职场文书
慈善捐赠倡议书
2014/08/30 职场文书
党员对照检查剖析材料
2014/10/13 职场文书
2014年稽查工作总结
2014/12/20 职场文书
实习生个人总结范文
2015/02/28 职场文书
Python 语言实现六大查找算法
2021/06/30 Python