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 异步调用框架 (Part 3 - 代码实现)
Aug 04 Javascript
热点新闻滚动特效的js代码
Aug 17 Javascript
jQuery 和 CSS 的文本特效插件集锦
Dec 12 Javascript
javascript强制点击广告的方法
Feb 06 Javascript
JavaScript改变CSS样式的方法汇总
May 07 Javascript
jquery实现的V字形显示效果代码
Oct 27 Javascript
20行JS代码实现网页刮刮乐效果
Jun 23 Javascript
vue-cli2.9.3 详细教程
Apr 23 Javascript
vue router 源码概览案例分析
Oct 09 Javascript
微信小程序点击图片实现长按预览、保存、识别带参数二维码、转发等功能
Jul 20 Javascript
vue 自定义右键样式的实例代码
Nov 06 Javascript
swiper自定义分页器的样式
Sep 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加水印的代码(支持半透明透明打水印,支持png透明背景)
2013/01/17 PHP
CI(CodeIgniter)框架实现图片上传的方法
2017/03/24 PHP
[推荐]javascript 面向对象技术基础教程
2009/03/03 Javascript
Javascript读取cookie函数代码
2010/10/16 Javascript
JavaScript快速检测浏览器对CSS3特性的支持情况
2012/09/26 Javascript
JS添加删除一组文本框并对输入信息加以验证判断其正确性
2013/04/11 Javascript
jquery实现动态画圆
2014/12/04 Javascript
JavaScript运动减速效果实例分析
2015/08/04 Javascript
JS组件Bootstrap Table布局详解
2016/05/27 Javascript
JS实现的找零张数最小问题示例
2017/11/28 Javascript
Angular路由ui-router配置详解
2018/08/01 Javascript
vue2.0父子组件间传递数据的方法
2018/08/16 Javascript
vue3.0 CLI - 3.2 路由的初级使用教程
2018/09/20 Javascript
layui数据表格跨行自动合并的例子
2019/09/02 Javascript
Vue.set 全局操作简单示例
2019/09/19 Javascript
浅谈Vue.use到底是什么鬼
2020/01/21 Javascript
vue中英文切换实例代码
2020/01/21 Javascript
Angular进行简单单元测试的实现方法实例
2020/08/16 Javascript
老生常谈python函数参数的区别(必看篇)
2017/05/29 Python
简单了解OpenCV是个什么东西
2017/11/10 Python
vscode 远程调试python的方法
2017/12/01 Python
python OpenCV学习笔记直方图反向投影的实现
2018/02/07 Python
浅谈pandas用groupby后对层级索引levels的处理方法
2018/11/06 Python
python批量从es取数据的方法(文档数超过10000)
2018/12/27 Python
python小程序之4名牌手洗牌发牌问题解析
2020/05/15 Python
Python3+Django get/post请求实现教程详解
2021/02/16 Python
python 实现网易邮箱邮件阅读和删除的辅助小脚本
2021/03/01 Python
秋季运动会广播稿
2014/02/22 职场文书
实用的简历自我评价
2014/03/06 职场文书
爱国卫生月活动总结范文
2014/04/25 职场文书
社保委托书怎么写
2014/08/02 职场文书
税务干部个人整改措施思想汇报
2014/10/10 职场文书
抗洪救灾感谢信
2015/01/22 职场文书
2015年房地产销售工作总结
2015/04/20 职场文书
Python 如何实现文件自动去重
2021/06/02 Python
MySQL悲观锁与乐观锁的实现方案
2021/11/02 MySQL