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中交替点击事件的实现代码
Feb 14 Javascript
BAT及各大互联网公司2014前端笔试面试题--JavaScript篇
Oct 29 Javascript
jQuery实现在下拉列表选择时获取json数据的方法
Apr 16 Javascript
跟我学习javascript的隐式强制转换
Nov 16 Javascript
Angularjs 滚动加载更多数据
Mar 17 Javascript
jquery按回车键实现表单提交的简单实例
May 25 Javascript
浅谈Sublime Text 3运行JavaScript控制台
Jun 06 Javascript
基于Swiper实现移动端页面图片轮播效果
Dec 28 Javascript
React 使用recharts实现散点地图的示例代码
Dec 07 Javascript
Vue+Express实现登录注销功能的实例代码
May 05 Javascript
微信小程序如何使用globalData的方法
Jun 06 Javascript
node.js +mongdb实现登录功能
Jun 18 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中json_encode()和json_decode()
2014/05/25 PHP
php连接oracle数据库的核心步骤
2016/05/26 PHP
在 Laravel 6 中缓存数据库查询结果的方法
2019/12/11 PHP
HR vs ForZe BO3 第一场 2.13
2021/03/10 DOTA
延时重复执行函数 lLoopRun.js
2007/05/08 Javascript
JavaScript replace(rgExp,fn)正则替换的用法
2010/03/04 Javascript
jQuery学习笔记之jQuery的DOM操作
2010/12/22 Javascript
javascript检测页面是否缩放的小例子
2013/05/16 Javascript
javascript中return,return true,return false三者的用法及区别
2015/11/17 Javascript
js从外部获取图片的实现方法
2016/08/05 Javascript
详解Angular中的自定义服务Service、Provider以及Factory
2017/04/22 Javascript
vue2导航根据路由传值,而改变导航内容的实例
2017/11/10 Javascript
Angularjs之ngModel中的值验证绑定方法
2018/09/13 Javascript
JS实现轮播图效果
2020/01/11 Javascript
Vue快速实现通用表单验证的方法
2020/02/24 Javascript
vue 插槽简介及使用示例
2020/11/19 Vue.js
Python中的迭代器与生成器高级用法解析
2016/06/28 Python
详细介绍Python的鸭子类型
2016/09/12 Python
Python操作MySQL模拟银行转账
2018/03/12 Python
使用pytorch进行图像的顺序读取方法
2018/07/27 Python
python将txt等文件中的数据读为numpy数组的方法
2018/12/22 Python
python3获取当前目录的实现方法
2019/07/29 Python
python实现复制大量文件功能
2019/08/31 Python
python3 assert 断言的使用详解 (区别于python2)
2019/11/27 Python
Python操作多维数组输出和矩阵运算示例
2019/11/28 Python
windows10环境下用anaconda和VScode配置的图文教程
2020/03/30 Python
Python selenium爬取微博数据代码实例
2020/05/22 Python
css3的图形3d翻转效果应用示例
2014/04/08 HTML / CSS
药学专业个人的自我评价
2013/12/31 职场文书
大学生自我鉴定评语
2014/01/27 职场文书
建房协议书
2014/04/11 职场文书
放飞理想演讲稿
2014/09/09 职场文书
水利专业大学生职业生涯规划书范文
2014/09/17 职场文书
县委班子四风对照检查材料思想汇报
2014/09/29 职场文书
2014幼儿园保育员工作总结
2014/11/10 职场文书
公司慰问信范文
2015/03/23 职场文书