一个对于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实现禁止后退的方法
Dec 27 Javascript
JavaScript XML操作 封装类
Jul 01 Javascript
jQuery 美元符冲突的解决方法
Mar 28 Javascript
Jquery ThickBox插件使用心得(不建议使用)
Sep 08 Javascript
编写Js代码要注意的几条规则
Sep 10 Javascript
javascript操作table(insertRow,deleteRow,insertCell,deleteCell方法详解)
Dec 16 Javascript
js实现固定显示区域内自动缩放图片的方法
Jul 18 Javascript
vue货币过滤器的实现方法
Apr 01 Javascript
利用Dectorator分模块存储Vuex状态的实现
Feb 05 Javascript
一些你可能不熟悉的JS知识点总结
Mar 15 Javascript
浅探express路由和中间件的实现
Sep 30 Javascript
vue 返回上一页,页面样式错乱的解决
Nov 14 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 utf-8编码问题,utf8编码,数据库乱码,页面显示输出乱码
2013/04/08 PHP
深入理解php printf() 输出格式化的字符串
2016/05/23 PHP
PHP 实现字符串翻转(包含中文汉字)的实现代码
2017/04/01 PHP
Jquery 获取表单text,areatext,radio,checkbox,select值的代码
2009/11/12 Javascript
js 程序执行与顺序实现详解
2013/05/13 Javascript
浅谈EasyUI中Treegrid节点的删除
2015/03/01 Javascript
jQuery给多个不同元素添加class样式的方法
2015/03/26 Javascript
基于jquery实现图片相关操作(重绘、获取尺寸、调整大小、缩放)
2015/12/25 Javascript
详解JavaScript的AngularJS框架中的表达式与指令
2016/03/05 Javascript
Vue.js基础知识汇总
2016/04/27 Javascript
Bootstrap选项卡与Masonry插件的完美结合
2016/07/06 Javascript
jquery 追加元素append、prepend、before、after用法与区别分析
2016/12/02 Javascript
详解Node.js 命令行程序开发教程
2017/06/07 Javascript
vue.js评论发布信息可插入QQ表情功能
2017/08/08 Javascript
史上最全JavaScript数组去重的十种方法(推荐)
2017/08/17 Javascript
vue组件jsx语法的具体使用
2018/05/21 Javascript
JavaScript实现的文本框placeholder提示文字功能示例
2018/07/25 Javascript
从源码里了解vue中的nextTick的使用
2018/11/22 Javascript
Vue框架下引入ActiveX控件的问题解决
2019/03/25 Javascript
微信小程序如何利用getCurrentPages进行页面传值
2019/07/01 Javascript
详解vue 组件注册
2020/11/20 Vue.js
手把手教你用python抢票回家过年(代码简单)
2018/01/21 Python
python实现websocket的客户端压力测试
2019/06/25 Python
python实现大文本文件分割
2019/07/22 Python
python-web根据元素属性进行定位的方法
2019/12/13 Python
python实现对变位词的判断方法
2020/04/05 Python
PyTorch实现重写/改写Dataset并载入Dataloader
2020/07/14 Python
python 对象真假值的实例(哪些视为False)
2020/12/11 Python
利用HTML5中Geolocation获取地理位置调用Google Map API在Google Map上定位
2013/01/23 HTML / CSS
欧洲著名的珠宝和手表网上商城:uhrcenter
2017/04/10 全球购物
澳大利亚最好的电动自行车:Leon Cycle
2020/12/19 全球购物
设计师大码女装:11 Honoré
2020/05/03 全球购物
酒店员工职业生涯规划
2014/02/25 职场文书
活动总结书
2014/05/08 职场文书
应届毕业生求职信
2014/05/26 职场文书
清明节主题班会
2015/08/14 职场文书