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高级程序设计阅读笔记(六) ECMAScript中的运算符(二)
Feb 27 Javascript
javascript动态向网页中添加表格实现代码
Feb 19 Javascript
移除AngularJS下URL中的#字符的方法
Jun 19 Javascript
js图片轮播手动切换效果
Nov 10 Javascript
uploadify多文件上传参数设置技巧
Nov 16 Javascript
js+flash实现的5图变换效果广告代码(附演示与demo源码下载)
Apr 01 Javascript
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
Dec 15 Javascript
JavaScript生成简单等差数列
Nov 28 Javascript
vue-cli 使用vue-bus来全局控制的实例讲解
Sep 15 Javascript
javascript面向对象创建对象的方式小结
Jul 29 Javascript
layui prompt 设置允许空白提交的方法
Sep 24 Javascript
Vue.extend 登录注册模态框的实现
Dec 29 Vue.js
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
一个ftp类(ini.php)
2006/10/09 PHP
PHP的异常处理类Exception的使用及说明
2012/06/13 PHP
PHP中HTML标签过滤技巧
2014/01/07 PHP
学习php设计模式 php实现备忘录模式(Memento)
2015/12/09 PHP
actionscript与javascript的区别
2011/05/25 Javascript
js 动态为textbox添加下拉框数据源的方法
2014/04/24 Javascript
js生成的验证码的实现与技术分析
2014/09/17 Javascript
JavaScript字符串对象charAt方法入门实例(用于取得指定位置的字符)
2014/10/17 Javascript
jQuery基于ajax实现星星评论代码
2015/08/07 Javascript
基于javascript制作微信聊天面板
2020/08/09 Javascript
详解Angular 4.x NgIf 的用法
2017/05/22 Javascript
Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解
2017/08/01 jQuery
php 解压zip压缩包内容到指定目录的实例
2018/01/23 Javascript
微信小程序Getuserinfo解决方案图解
2018/08/24 Javascript
vue项目中运用webpack动态配置打包多种环境域名的方法
2019/06/24 Javascript
Vuex模块化应用实践示例
2020/02/03 Javascript
python基础教程之常用运算符
2014/08/29 Python
PyQt5根据控件Id获取控件对象的方法
2019/06/25 Python
使用TensorFlow直接获取处理MNIST数据方式
2020/02/10 Python
Python终端输出彩色字符方法详解
2020/02/11 Python
python如何操作mysql
2020/08/17 Python
Python logging日志库空间不足问题解决
2020/09/14 Python
python 判断一组数据是否符合正态分布
2020/09/23 Python
Python ConfigParser模块的使用示例
2020/10/12 Python
Python Pandas list列表数据列拆分成多行的方法实现
2020/12/14 Python
python 制作网站筛选工具(附源码)
2021/01/21 Python
如何用Python和JS实现的Web SSH工具
2021/02/23 Python
Under Armour美国官网:美国知名高端功能性运动品牌
2016/09/05 全球购物
党校自我鉴定范文
2013/10/02 职场文书
爱情保证书范文
2014/02/01 职场文书
文员岗位职责范本
2014/03/08 职场文书
美容院店长岗位职责
2014/04/08 职场文书
大学生赌博检讨书
2014/09/22 职场文书
2014普法依法治理工作总结
2014/12/18 职场文书
刑事案件上诉状
2015/05/23 职场文书
解决Go gorm踩过的坑
2021/04/30 Golang