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 相关文章推荐
JQUERY 浏览器判断实现函数
Aug 20 Javascript
基于jQuery的为attr添加id title等效果的实现代码
Apr 20 Javascript
封装了jQuery的Ajax请求全局配置
Feb 05 Javascript
JavaScript数据结构和算法之图和图算法
Feb 11 Javascript
javascript之Boolean类型对象
Jun 07 Javascript
easyui combotree加载静态数据问题(选不上)解决方法
Dec 26 Javascript
axios取消请求的实践记录分享
Sep 26 Javascript
vue-cli项目中使用echarts图表实例
Oct 22 Javascript
js 根据对象数组中的属性进行排序实现代码
Sep 12 Javascript
原生JS实现留言板功能
Feb 08 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
Jun 16 Javascript
基于Vue全局组件与局部组件的区别说明
Aug 11 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页面缓存方法小结
2015/01/10 PHP
php数组键名技巧小结
2015/02/17 PHP
PHP 实现代码复用的一个方法 traits新特性
2015/02/22 PHP
CodeIgniter配置之database.php用法实例分析
2016/01/20 PHP
PHP Mysqli 常用代码集合
2016/11/12 PHP
JS 用6N±1法求素数 实例教程
2009/10/20 Javascript
js函数中onmousedown和onclick的区别和联系探讨
2013/05/19 Javascript
jquery js 重置表单 reset()具体实现代码
2013/08/05 Javascript
JavaScript设计模式之单例模式实例
2014/09/24 Javascript
JavaScript中的无阻塞加载性能优化方案
2014/10/10 Javascript
JavaScript ParseFloat()方法
2015/12/18 Javascript
js实现滚动条滚动到页面底部继续加载
2015/12/19 Javascript
Angularjs 实现分页功能及示例代码
2016/09/14 Javascript
表单input项使用label同时引用Bootstrap库导致input点击效果区增大问题
2016/10/11 Javascript
JS中的回调函数实例浅析
2018/03/21 Javascript
浅谈webpack+react多页面开发终极架构
2018/11/11 Javascript
小程序实现多列选择器
2019/02/15 Javascript
微信小程序+云开发实现欢迎登录注册
2019/05/24 Javascript
webpack DllPlugin xxx is not defined解决办法
2019/12/13 Javascript
浅谈python中的占位符
2017/11/09 Python
详解分布式任务队列Celery使用说明
2018/11/29 Python
python批量修改文件夹及其子文件夹下的文件内容
2019/03/15 Python
Python+pyplot绘制带文本标注的柱状图方法
2019/07/08 Python
numpy创建单位矩阵和对角矩阵的实例
2019/11/29 Python
Python制作一个仿QQ办公版的图形登录界面
2020/09/22 Python
python中封包建立过程实例
2021/02/18 Python
美国猫狗药物和用品网站:PetCareRx
2017/01/05 全球购物
NYX Professional Makeup俄罗斯官网:世界知名的化妆品品牌
2019/12/26 全球购物
如何提高MySql的安全性
2014/06/19 面试题
装修协议书范本
2014/04/21 职场文书
企业诚信承诺书
2014/05/23 职场文书
会计工作态度自我评价
2015/03/06 职场文书
产品调价通知函
2015/04/20 职场文书
英语演讲开场白
2015/05/29 职场文书
Python爬虫框架之Scrapy中Spider的用法
2021/06/28 Python
python blinker 信号库
2022/05/04 Python