JavaScript this 深入理解


Posted in Javascript onJuly 30, 2009

最近一段时间看了很多JavaScript 的库源码, 如 prototype, Ext core 等。这些库中大量应用到了这一概念。直到昨天翻了一下《JavaScript王者归来》这本书才算对this有一个深刻的理解。
大至归结一下:
1. 函数调用者与所有者
JavaScript 中函数(function) 存在调用者 与 所有者这两个概念,调用者是指调用函数的对象,通常是一个指向调用了当前函数的函数的引用,如果是顶层调用,那么caller=null, 大部分浏览器的JavaScript实现 可以用 caller 这个属性获得(这不是 ECMAScript 规范的一部分,所有还是慎用)。 从以下的代码能够很好的理解这点:

function a(){ 
alert('fun a caller=' + a.caller); 
} 
function b(){ 
a(); 
} 
a(); 
b();

-----------
运行结果可以看到两个对话框:
1.
fun a caller=null;
2.
fun a caller=function b(){
a();
}
--------------------------
而对于所有者,则是指调用函数的对象(一个动态的概念), 在函数体中的this就是指向了函数的所有者。在这里的this 与 Java 以及 C++ 中的 this指针是完全不同的两个概念,很多人忽略了这一点,这也是导致 JavaScript中的this无法很好理解的原因之一。看看以下的例子:
var oa = { 
x:1, 
y:2 
} 
var ob = { 
x:11, 
y:12 
} 
function a(w){ 
alert(w + "=" + this.x + "," + this.y) 
} 
a("?"); 
oa.fun = a; 
oa.fun("a"); 
ob.fun = a; 
ob.fun("b");

---------
一开始的调用 a() 这时未指定所有者,一般这种情况 this 是指向浏览器的顶层元素 window 的, 而window中未定义x 与 y 属性。
所以结果显示为: ?=undefined,undefined
oa.fun = a; oa.fun("a"); 将函数引用赋值给对像a的属性fun, 这时再调用函数的所有者变成了a, 则结果显示为:a=1,2
同理 ob.fun("b")则显示:b=11,12。
在JavaScript中要改变一个函数的所有者(this)的方法就是将函数引用赋值给一个对象的属性。
同是在Function对象中也提供了两个原型函数可以实现这一功能: apply, call, 这两个函数的第一个参数就是要指定的所有者对象,它们间的唯一区别就是apply将其后的要传递给函数的形参封装到数组中,或者直接用 arguments对象。而call则直接将形参跟在其后。
因此上面的 oa.fun=a; oa.fun("a") 可以改写成 a.apply(oa, ["a"]) 或 a.call(oa, "a");
ob.fun=b; ob.fun("b") 可以改写成 a.apply(ob, ["b"]) 或 b.call(ob, "b");
知道了以上这此,对于 this 的作用域及其使用就很好理解了。

下面是一些参考文档
javascript this用法小结
https://3water.com/article/16863.htm

JavaScript this 深入理解
https://3water.com/article/19425.htm

JAVASCRIPT THIS详解 面向对象
https://3water.com/article/17584.htm

Javascript this指针
https://3water.com/article/19434.htm

JavaScript中this关键字使用方法详解
https://3water.com/article/7954.htm

Javascript this关键字使用分析
https://3water.com/article/16235.htm

Javascript 相关文章推荐
javascript 获取表单file全路径
Dec 31 Javascript
详解JavaScript语法对{}处理的坑爹之处
Jun 05 Javascript
jQuery .tmpl() 用法示例介绍
Aug 21 Javascript
JavaScript实现显示函数调用堆栈的方法
Apr 21 Javascript
AngularJS使用ng-options指令实现下拉框
Aug 23 Javascript
js中常用的Tab切换效果(推荐)
Aug 30 Javascript
AngularJS 实现JavaScript 动画效果详解
Sep 08 Javascript
canvas 绘制圆形时钟
Feb 22 Javascript
详解vue跨组件通信的几种方法
Jun 15 Javascript
详解用async/await来处理异步
Aug 28 Javascript
JS中的模糊查询功能
Dec 08 Javascript
使用JS实现简易计算器
Jun 14 Javascript
Google Map API更新实现用户自定义标注坐标
Jul 29 #Javascript
JavaScript Konami Code 实现代码
Jul 29 #Javascript
JavaScript 获取事件对象的注意点
Jul 29 #Javascript
javascript CSS画图之基础篇
Jul 29 #Javascript
JQuery 表格操作(交替显示、拖动表格行、选择行等)
Jul 29 #Javascript
JavaScript 设计模式学习 Factory
Jul 29 #Javascript
JQuery UI皮肤定制
Jul 27 #Javascript
You might like
PHP利用COM对象访问SQLServer、Access
2006/10/09 PHP
PHP中通过ADO调用Access数据库的方法测试不通过
2006/12/31 PHP
php+javascript的日历控件
2009/11/19 PHP
PHP5.5和之前的版本empty函数的不同之处
2014/06/13 PHP
php查找指定目录下指定大小文件的方法
2014/11/28 PHP
详解PHP的Yii框架中的Controller控制器
2016/03/29 PHP
ExtJS GTGrid 简单用户管理
2009/07/01 Javascript
jquery easyui combobox模糊过滤(示例代码)
2013/11/30 Javascript
Angular2表单自定义验证器的实现
2016/10/19 Javascript
使用contextMenu插件实现Bootstrap table弹出右键菜单
2017/02/20 Javascript
JS中IP地址与整数相互转换的实现代码
2017/04/10 Javascript
js每隔两秒输出数组中的一项(实例)
2017/05/28 Javascript
JavaScript编程设计模式之观察者模式(Observer Pattern)实例详解
2017/10/25 Javascript
详解React中合并单元格的正确写法
2019/01/08 Javascript
vue相同路由跳转强制刷新该路由组件操作
2020/08/05 Javascript
利用numpy+matplotlib绘图的基本操作教程
2017/05/03 Python
Python中scatter函数参数及用法详解
2017/11/08 Python
python消费kafka数据批量插入到es的方法
2018/12/27 Python
Python+OpenCV感兴趣区域ROI提取方法
2019/01/10 Python
python实现微信自动回复及批量添加好友功能
2019/07/03 Python
python爬虫selenium和phantomJs使用方法解析
2019/08/08 Python
Python读取实时数据流示例
2019/12/02 Python
浅谈keras的深度模型训练过程及结果记录方式
2020/01/24 Python
python实现简单坦克大战
2020/03/27 Python
8种常用的Python工具
2020/08/05 Python
Python之qq自动发消息的示例代码
2021/02/18 Python
美国基督教约会网站:ChristianCafe.com
2020/02/04 全球购物
工程部主管岗位职责
2013/11/17 职场文书
教师自我反思材料
2014/02/14 职场文书
质监局领导班子践行群众路线整改方案
2014/10/26 职场文书
2014教师专业技术工作总结
2014/12/03 职场文书
2015年小学数学教师工作总结
2015/05/20 职场文书
电力安全学习心得体会
2016/01/18 职场文书
《比的意义》教学反思
2016/02/18 职场文书
小学语文的各类谚语(70首)
2019/08/15 职场文书
Lakehouse数据湖并发控制陷阱分析
2022/03/31 Oracle