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_01_isPlainObject分析与重构
Oct 20 Javascript
js调用iframe实现打印页面内容的方法
Mar 04 Javascript
JavaScript原生对象之Number对象的属性和方法详解
Mar 13 Javascript
jQuery中toggle()函数的使用实例
Apr 17 Javascript
不依赖Flash和任何JS库实现文本复制与剪切附源码下载
Oct 09 Javascript
JS 调用微信扫一扫功能
Dec 22 Javascript
H5手机端多文件上传预览插件
Apr 21 Javascript
vue 自定义 select内置组件
Apr 10 Javascript
JavaScript反射与依赖注入实例详解
May 29 Javascript
React+Webpack快速上手指南(小结)
Aug 15 Javascript
Vue 实时监听窗口变化 windowresize的两种方法
Nov 06 Javascript
详解Vue中的MVVM原理和实现方法
Jul 15 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/04/09 PHP
PHP的Json中文处理解决方案
2016/09/29 PHP
php中bind_param()函数用法分析
2017/03/28 PHP
Thinkphp5结合layer弹窗定制操作结果页面
2017/07/07 PHP
PHP实现提高SESSION响应速度的几种方法详解
2019/08/09 PHP
PHP并发场景的三种解决方案代码实例
2021/02/27 PHP
一个对于js this关键字的问题
2007/01/09 Javascript
50款非常棒的 jQuery 插件分享
2012/03/29 Javascript
js获取事件源及触发该事件的对象
2013/10/24 Javascript
javascript与jquery中跳出循环的区别总结
2013/11/04 Javascript
基于NodeJS的前后端分离的思考与实践(一)全栈式开发
2014/09/26 NodeJs
js带前后翻页的图片切换效果代码分享
2015/09/08 Javascript
微信公众号 客服接口的开发实例详解
2016/09/28 Javascript
微信小程序实现动态设置页面标题的方法【附源码下载】
2017/11/29 Javascript
swiper自定义分页器使用方法详解
2020/09/14 Javascript
Vue实现购物车详情页面的方法
2019/08/20 Javascript
Vue3.0数据响应式原理详解
2019/10/09 Javascript
详解微信小程序之提高应用速度小技巧
2020/01/07 Javascript
Python translator使用实例
2008/09/06 Python
python连接MySQL数据库实例分析
2015/05/12 Python
详解Python中expandtabs()方法的使用
2015/05/18 Python
python虚拟环境virtualenv的使用教程
2017/10/20 Python
Python后台开发Django的教程详解(启动)
2019/04/08 Python
python禁用键鼠与提权代码实例
2019/08/16 Python
详解修改Anaconda中的Jupyter Notebook默认工作路径的三种方式
2021/01/24 Python
Bailey帽子官方商店:Bailey Hats
2018/09/25 全球购物
The North Face北面德国官网:美国著名户外品牌
2018/12/12 全球购物
TripAdvisor日本:全球领先的旅游网站
2019/02/14 全球购物
科室工作的个人自我评价
2013/10/30 职场文书
买房子个人收入证明
2014/01/16 职场文书
学校元旦晚会方案
2014/02/19 职场文书
社会治安综合治理管理责任书
2014/04/16 职场文书
入党积极分子个人总结
2015/03/02 职场文书
关于感恩的作文
2019/08/26 职场文书
nginx从安装到配置详细说明(安装,安全配置,防盗链,动静分离,配置 HTTPS,性能优化)
2022/02/12 Servers
正则表达式基础与常用验证表达式
2022/06/16 Javascript